ActivityManagerService.java revision 8920e1cabb56be6c46df40f5329aadbce3132fde
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.ITaskStackListener; 41import android.app.ProfilerInfo; 42import android.app.admin.DevicePolicyManager; 43import android.app.usage.UsageEvents; 44import android.app.usage.UsageStatsManagerInternal; 45import android.appwidget.AppWidgetManager; 46import android.content.res.Resources; 47import android.graphics.Bitmap; 48import android.graphics.Point; 49import android.graphics.Rect; 50import android.os.BatteryStats; 51import android.os.PersistableBundle; 52import android.os.storage.IMountService; 53import android.os.storage.StorageManager; 54import android.service.voice.IVoiceInteractionSession; 55import android.util.ArrayMap; 56import android.util.ArraySet; 57import android.util.SparseIntArray; 58 59import com.android.internal.R; 60import com.android.internal.annotations.GuardedBy; 61import com.android.internal.app.IAppOpsService; 62import com.android.internal.app.IVoiceInteractor; 63import com.android.internal.app.ProcessMap; 64import com.android.internal.app.ProcessStats; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.Installer; 85import com.android.server.pm.UserManagerService; 86import com.android.server.statusbar.StatusBarManagerInternal; 87import com.android.server.wm.AppTransition; 88import com.android.server.wm.WindowManagerService; 89import com.google.android.collect.Lists; 90import com.google.android.collect.Maps; 91 92import libcore.io.IoUtils; 93 94import org.xmlpull.v1.XmlPullParser; 95import org.xmlpull.v1.XmlPullParserException; 96import org.xmlpull.v1.XmlSerializer; 97 98import android.app.Activity; 99import android.app.ActivityManager; 100import android.app.ActivityManager.RunningTaskInfo; 101import android.app.ActivityManager.StackInfo; 102import android.app.ActivityManagerInternal; 103import android.app.ActivityManagerNative; 104import android.app.ActivityOptions; 105import android.app.ActivityThread; 106import android.app.AlertDialog; 107import android.app.AppGlobals; 108import android.app.ApplicationErrorReport; 109import android.app.Dialog; 110import android.app.IActivityController; 111import android.app.IApplicationThread; 112import android.app.IInstrumentationWatcher; 113import android.app.INotificationManager; 114import android.app.IProcessObserver; 115import android.app.IServiceConnection; 116import android.app.IStopUserCallback; 117import android.app.IUiAutomationConnection; 118import android.app.IUserSwitchObserver; 119import android.app.Instrumentation; 120import android.app.Notification; 121import android.app.NotificationManager; 122import android.app.PendingIntent; 123import android.app.backup.IBackupManager; 124import android.content.ActivityNotFoundException; 125import android.content.BroadcastReceiver; 126import android.content.ClipData; 127import android.content.ComponentCallbacks2; 128import android.content.ComponentName; 129import android.content.ContentProvider; 130import android.content.ContentResolver; 131import android.content.Context; 132import android.content.DialogInterface; 133import android.content.IContentProvider; 134import android.content.IIntentReceiver; 135import android.content.IIntentSender; 136import android.content.Intent; 137import android.content.IntentFilter; 138import android.content.IntentSender; 139import android.content.pm.ActivityInfo; 140import android.content.pm.ApplicationInfo; 141import android.content.pm.ConfigurationInfo; 142import android.content.pm.IPackageDataObserver; 143import android.content.pm.IPackageManager; 144import android.content.pm.InstrumentationInfo; 145import android.content.pm.PackageInfo; 146import android.content.pm.PackageManager; 147import android.content.pm.ParceledListSlice; 148import android.content.pm.UserInfo; 149import android.content.pm.PackageManager.NameNotFoundException; 150import android.content.pm.PathPermission; 151import android.content.pm.ProviderInfo; 152import android.content.pm.ResolveInfo; 153import android.content.pm.ServiceInfo; 154import android.content.res.CompatibilityInfo; 155import android.content.res.Configuration; 156import android.net.Proxy; 157import android.net.ProxyInfo; 158import android.net.Uri; 159import android.os.Binder; 160import android.os.Build; 161import android.os.Bundle; 162import android.os.Debug; 163import android.os.DropBoxManager; 164import android.os.Environment; 165import android.os.FactoryTest; 166import android.os.FileObserver; 167import android.os.FileUtils; 168import android.os.Handler; 169import android.os.IBinder; 170import android.os.IPermissionController; 171import android.os.IRemoteCallback; 172import android.os.IUserManager; 173import android.os.Looper; 174import android.os.Message; 175import android.os.Parcel; 176import android.os.ParcelFileDescriptor; 177import android.os.PowerManagerInternal; 178import android.os.Process; 179import android.os.RemoteCallbackList; 180import android.os.RemoteException; 181import android.os.SELinux; 182import android.os.ServiceManager; 183import android.os.StrictMode; 184import android.os.SystemClock; 185import android.os.SystemProperties; 186import android.os.UpdateLock; 187import android.os.UserHandle; 188import android.os.UserManager; 189import android.provider.Settings; 190import android.text.format.DateUtils; 191import android.text.format.Time; 192import android.util.AtomicFile; 193import android.util.EventLog; 194import android.util.Log; 195import android.util.Pair; 196import android.util.PrintWriterPrinter; 197import android.util.Slog; 198import android.util.SparseArray; 199import android.util.TimeUtils; 200import android.util.Xml; 201import android.view.Gravity; 202import android.view.LayoutInflater; 203import android.view.View; 204import android.view.WindowManager; 205 206import dalvik.system.VMRuntime; 207 208import java.io.BufferedInputStream; 209import java.io.BufferedOutputStream; 210import java.io.DataInputStream; 211import java.io.DataOutputStream; 212import java.io.File; 213import java.io.FileDescriptor; 214import java.io.FileInputStream; 215import java.io.FileNotFoundException; 216import java.io.FileOutputStream; 217import java.io.IOException; 218import java.io.InputStreamReader; 219import java.io.PrintWriter; 220import java.io.StringWriter; 221import java.lang.ref.WeakReference; 222import java.util.ArrayList; 223import java.util.Arrays; 224import java.util.Collections; 225import java.util.Comparator; 226import java.util.HashMap; 227import java.util.HashSet; 228import java.util.Iterator; 229import java.util.List; 230import java.util.Locale; 231import java.util.Map; 232import java.util.Set; 233import java.util.concurrent.atomic.AtomicBoolean; 234import java.util.concurrent.atomic.AtomicLong; 235 236public final class ActivityManagerService extends ActivityManagerNative 237 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 238 239 private static final String USER_DATA_DIR = "/data/user/"; 240 // File that stores last updated system version and called preboot receivers 241 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 242 243 static final String TAG = "ActivityManager"; 244 static final String TAG_MU = "ActivityManagerServiceMU"; 245 static final boolean DEBUG = false; 246 static final boolean localLOGV = DEBUG; 247 static final boolean DEBUG_BACKUP = localLOGV || false; 248 static final boolean DEBUG_BROADCAST = localLOGV || false; 249 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 250 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_CLEANUP = localLOGV || false; 252 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 253 static final boolean DEBUG_FOCUS = false; 254 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 255 static final boolean DEBUG_MU = localLOGV || false; 256 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 257 static final boolean DEBUG_LRU = localLOGV || false; 258 static final boolean DEBUG_PAUSE = localLOGV || false; 259 static final boolean DEBUG_POWER = localLOGV || false; 260 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 261 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 262 static final boolean DEBUG_PROCESSES = localLOGV || false; 263 static final boolean DEBUG_PROVIDER = localLOGV || false; 264 static final boolean DEBUG_RESULTS = localLOGV || false; 265 static final boolean DEBUG_SERVICE = localLOGV || false; 266 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 267 static final boolean DEBUG_STACK = localLOGV || false; 268 static final boolean DEBUG_SWITCH = localLOGV || false; 269 static final boolean DEBUG_TASKS = localLOGV || false; 270 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 271 static final boolean DEBUG_TRANSITION = localLOGV || false; 272 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 273 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 274 static final boolean DEBUG_VISBILITY = localLOGV || false; 275 static final boolean DEBUG_PSS = localLOGV || false; 276 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 277 static final boolean DEBUG_RECENTS = localLOGV || false; 278 static final boolean VALIDATE_TOKENS = false; 279 static final boolean SHOW_ACTIVITY_START_TIME = true; 280 281 // Control over CPU and battery monitoring. 282 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 283 static final boolean MONITOR_CPU_USAGE = true; 284 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 285 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 286 static final boolean MONITOR_THREAD_CPU_USAGE = false; 287 288 // The flags that are set for all calls we make to the package manager. 289 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 290 291 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 292 293 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 294 295 // Maximum number recent bitmaps to keep in memory. 296 static final int MAX_RECENT_BITMAPS = 3; 297 298 // Amount of time after a call to stopAppSwitches() during which we will 299 // prevent further untrusted switches from happening. 300 static final long APP_SWITCH_DELAY_TIME = 5*1000; 301 302 // How long we wait for a launched process to attach to the activity manager 303 // before we decide it's never going to come up for real. 304 static final int PROC_START_TIMEOUT = 10*1000; 305 306 // How long we wait for a launched process to attach to the activity manager 307 // before we decide it's never going to come up for real, when the process was 308 // started with a wrapper for instrumentation (such as Valgrind) because it 309 // could take much longer than usual. 310 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 311 312 // How long to wait after going idle before forcing apps to GC. 313 static final int GC_TIMEOUT = 5*1000; 314 315 // The minimum amount of time between successive GC requests for a process. 316 static final int GC_MIN_INTERVAL = 60*1000; 317 318 // The minimum amount of time between successive PSS requests for a process. 319 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 320 321 // The minimum amount of time between successive PSS requests for a process 322 // when the request is due to the memory state being lowered. 323 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 324 325 // The rate at which we check for apps using excessive power -- 15 mins. 326 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on wake locks to start killing things. 330 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // The minimum sample duration we will allow before deciding we have 333 // enough data on CPU usage to start killing things. 334 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 335 336 // How long we allow a receiver to run before giving up on it. 337 static final int BROADCAST_FG_TIMEOUT = 10*1000; 338 static final int BROADCAST_BG_TIMEOUT = 60*1000; 339 340 // How long we wait until we timeout on key dispatching. 341 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 342 343 // How long we wait until we timeout on key dispatching during instrumentation. 344 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 345 346 // Amount of time we wait for observers to handle a user switch before 347 // giving up on them and unfreezing the screen. 348 static final int USER_SWITCH_TIMEOUT = 2*1000; 349 350 // Maximum number of users we allow to be running at a time. 351 static final int MAX_RUNNING_USERS = 3; 352 353 // How long to wait in getAssistContextExtras for the activity and foreground services 354 // to respond with the result. 355 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 356 357 // Maximum number of persisted Uri grants a package is allowed 358 static final int MAX_PERSISTED_URI_GRANTS = 128; 359 360 static final int MY_PID = Process.myPid(); 361 362 static final String[] EMPTY_STRING_ARRAY = new String[0]; 363 364 // How many bytes to write into the dropbox log before truncating 365 static final int DROPBOX_MAX_SIZE = 256 * 1024; 366 367 // Access modes for handleIncomingUser. 368 static final int ALLOW_NON_FULL = 0; 369 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 370 static final int ALLOW_FULL_ONLY = 2; 371 372 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 373 374 // Delay in notifying task stack change listeners (in millis) 375 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 376 377 /** All system services */ 378 SystemServiceManager mSystemServiceManager; 379 380 private Installer mInstaller; 381 382 /** Run all ActivityStacks through this */ 383 ActivityStackSupervisor mStackSupervisor; 384 385 /** Task stack change listeners. */ 386 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 387 new RemoteCallbackList<ITaskStackListener>(); 388 389 public IntentFirewall mIntentFirewall; 390 391 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 392 // default actuion automatically. Important for devices without direct input 393 // devices. 394 private boolean mShowDialogs = true; 395 396 BroadcastQueue mFgBroadcastQueue; 397 BroadcastQueue mBgBroadcastQueue; 398 // Convenient for easy iteration over the queues. Foreground is first 399 // so that dispatch of foreground broadcasts gets precedence. 400 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 401 402 BroadcastQueue broadcastQueueForIntent(Intent intent) { 403 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 404 if (DEBUG_BACKGROUND_BROADCAST) { 405 Slog.i(TAG, "Broadcast intent " + intent + " on " 406 + (isFg ? "foreground" : "background") 407 + " queue"); 408 } 409 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 410 } 411 412 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 413 for (BroadcastQueue queue : mBroadcastQueues) { 414 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 415 if (r != null) { 416 return r; 417 } 418 } 419 return null; 420 } 421 422 /** 423 * Activity we have told the window manager to have key focus. 424 */ 425 ActivityRecord mFocusedActivity = null; 426 427 /** 428 * List of intents that were used to start the most recent tasks. 429 */ 430 ArrayList<TaskRecord> mRecentTasks; 431 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 432 433 /** 434 * For addAppTask: cached of the last activity component that was added. 435 */ 436 ComponentName mLastAddedTaskComponent; 437 438 /** 439 * For addAppTask: cached of the last activity uid that was added. 440 */ 441 int mLastAddedTaskUid; 442 443 /** 444 * For addAppTask: cached of the last ActivityInfo that was added. 445 */ 446 ActivityInfo mLastAddedTaskActivity; 447 448 public class PendingAssistExtras extends Binder implements Runnable { 449 public final ActivityRecord activity; 450 public final Bundle extras; 451 public final Intent intent; 452 public final String hint; 453 public final int userHandle; 454 public boolean haveResult = false; 455 public Bundle result = null; 456 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 457 String _hint, int _userHandle) { 458 activity = _activity; 459 extras = _extras; 460 intent = _intent; 461 hint = _hint; 462 userHandle = _userHandle; 463 } 464 @Override 465 public void run() { 466 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 467 synchronized (this) { 468 haveResult = true; 469 notifyAll(); 470 } 471 } 472 } 473 474 final ArrayList<PendingAssistExtras> mPendingAssistExtras 475 = new ArrayList<PendingAssistExtras>(); 476 477 /** 478 * Process management. 479 */ 480 final ProcessList mProcessList = new ProcessList(); 481 482 /** 483 * All of the applications we currently have running organized by name. 484 * The keys are strings of the application package name (as 485 * returned by the package manager), and the keys are ApplicationRecord 486 * objects. 487 */ 488 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 489 490 /** 491 * Tracking long-term execution of processes to look for abuse and other 492 * bad app behavior. 493 */ 494 final ProcessStatsService mProcessStats; 495 496 /** 497 * The currently running isolated processes. 498 */ 499 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 500 501 /** 502 * Counter for assigning isolated process uids, to avoid frequently reusing the 503 * same ones. 504 */ 505 int mNextIsolatedProcessUid = 0; 506 507 /** 508 * The currently running heavy-weight process, if any. 509 */ 510 ProcessRecord mHeavyWeightProcess = null; 511 512 /** 513 * The last time that various processes have crashed. 514 */ 515 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 516 517 /** 518 * Information about a process that is currently marked as bad. 519 */ 520 static final class BadProcessInfo { 521 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 522 this.time = time; 523 this.shortMsg = shortMsg; 524 this.longMsg = longMsg; 525 this.stack = stack; 526 } 527 528 final long time; 529 final String shortMsg; 530 final String longMsg; 531 final String stack; 532 } 533 534 /** 535 * Set of applications that we consider to be bad, and will reject 536 * incoming broadcasts from (which the user has no control over). 537 * Processes are added to this set when they have crashed twice within 538 * a minimum amount of time; they are removed from it when they are 539 * later restarted (hopefully due to some user action). The value is the 540 * time it was added to the list. 541 */ 542 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 543 544 /** 545 * All of the processes we currently have running organized by pid. 546 * The keys are the pid running the application. 547 * 548 * <p>NOTE: This object is protected by its own lock, NOT the global 549 * activity manager lock! 550 */ 551 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 552 553 /** 554 * All of the processes that have been forced to be foreground. The key 555 * is the pid of the caller who requested it (we hold a death 556 * link on it). 557 */ 558 abstract class ForegroundToken implements IBinder.DeathRecipient { 559 int pid; 560 IBinder token; 561 } 562 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 563 564 /** 565 * List of records for processes that someone had tried to start before the 566 * system was ready. We don't start them at that point, but ensure they 567 * are started by the time booting is complete. 568 */ 569 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 570 571 /** 572 * List of persistent applications that are in the process 573 * of being started. 574 */ 575 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 576 577 /** 578 * Processes that are being forcibly torn down. 579 */ 580 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 581 582 /** 583 * List of running applications, sorted by recent usage. 584 * The first entry in the list is the least recently used. 585 */ 586 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 587 588 /** 589 * Where in mLruProcesses that the processes hosting activities start. 590 */ 591 int mLruProcessActivityStart = 0; 592 593 /** 594 * Where in mLruProcesses that the processes hosting services start. 595 * This is after (lower index) than mLruProcessesActivityStart. 596 */ 597 int mLruProcessServiceStart = 0; 598 599 /** 600 * List of processes that should gc as soon as things are idle. 601 */ 602 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 603 604 /** 605 * Processes we want to collect PSS data from. 606 */ 607 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 608 609 /** 610 * Last time we requested PSS data of all processes. 611 */ 612 long mLastFullPssTime = SystemClock.uptimeMillis(); 613 614 /** 615 * If set, the next time we collect PSS data we should do a full collection 616 * with data from native processes and the kernel. 617 */ 618 boolean mFullPssPending = false; 619 620 /** 621 * This is the process holding what we currently consider to be 622 * the "home" activity. 623 */ 624 ProcessRecord mHomeProcess; 625 626 /** 627 * This is the process holding the activity the user last visited that 628 * is in a different process from the one they are currently in. 629 */ 630 ProcessRecord mPreviousProcess; 631 632 /** 633 * The time at which the previous process was last visible. 634 */ 635 long mPreviousProcessVisibleTime; 636 637 /** 638 * Which uses have been started, so are allowed to run code. 639 */ 640 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 641 642 /** 643 * LRU list of history of current users. Most recently current is at the end. 644 */ 645 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 646 647 /** 648 * Constant array of the users that are currently started. 649 */ 650 int[] mStartedUserArray = new int[] { 0 }; 651 652 /** 653 * Registered observers of the user switching mechanics. 654 */ 655 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 656 = new RemoteCallbackList<IUserSwitchObserver>(); 657 658 /** 659 * Currently active user switch. 660 */ 661 Object mCurUserSwitchCallback; 662 663 /** 664 * Packages that the user has asked to have run in screen size 665 * compatibility mode instead of filling the screen. 666 */ 667 final CompatModePackages mCompatModePackages; 668 669 /** 670 * Set of IntentSenderRecord objects that are currently active. 671 */ 672 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 673 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 674 675 /** 676 * Fingerprints (hashCode()) of stack traces that we've 677 * already logged DropBox entries for. Guarded by itself. If 678 * something (rogue user app) forces this over 679 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 680 */ 681 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 682 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 683 684 /** 685 * Strict Mode background batched logging state. 686 * 687 * The string buffer is guarded by itself, and its lock is also 688 * used to determine if another batched write is already 689 * in-flight. 690 */ 691 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 692 693 /** 694 * Keeps track of all IIntentReceivers that have been registered for 695 * broadcasts. Hash keys are the receiver IBinder, hash value is 696 * a ReceiverList. 697 */ 698 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 699 new HashMap<IBinder, ReceiverList>(); 700 701 /** 702 * Resolver for broadcast intents to registered receivers. 703 * Holds BroadcastFilter (subclass of IntentFilter). 704 */ 705 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 706 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 707 @Override 708 protected boolean allowFilterResult( 709 BroadcastFilter filter, List<BroadcastFilter> dest) { 710 IBinder target = filter.receiverList.receiver.asBinder(); 711 for (int i=dest.size()-1; i>=0; i--) { 712 if (dest.get(i).receiverList.receiver.asBinder() == target) { 713 return false; 714 } 715 } 716 return true; 717 } 718 719 @Override 720 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 721 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 722 || userId == filter.owningUserId) { 723 return super.newResult(filter, match, userId); 724 } 725 return null; 726 } 727 728 @Override 729 protected BroadcastFilter[] newArray(int size) { 730 return new BroadcastFilter[size]; 731 } 732 733 @Override 734 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 735 return packageName.equals(filter.packageName); 736 } 737 }; 738 739 /** 740 * State of all active sticky broadcasts per user. Keys are the action of the 741 * sticky Intent, values are an ArrayList of all broadcasted intents with 742 * that action (which should usually be one). The SparseArray is keyed 743 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 744 * for stickies that are sent to all users. 745 */ 746 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 747 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 748 749 final ActiveServices mServices; 750 751 /** 752 * Backup/restore process management 753 */ 754 String mBackupAppName = null; 755 BackupRecord mBackupTarget = null; 756 757 final ProviderMap mProviderMap; 758 759 /** 760 * List of content providers who have clients waiting for them. The 761 * application is currently being launched and the provider will be 762 * removed from this list once it is published. 763 */ 764 final ArrayList<ContentProviderRecord> mLaunchingProviders 765 = new ArrayList<ContentProviderRecord>(); 766 767 /** 768 * File storing persisted {@link #mGrantedUriPermissions}. 769 */ 770 private final AtomicFile mGrantFile; 771 772 /** XML constants used in {@link #mGrantFile} */ 773 private static final String TAG_URI_GRANTS = "uri-grants"; 774 private static final String TAG_URI_GRANT = "uri-grant"; 775 private static final String ATTR_USER_HANDLE = "userHandle"; 776 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 777 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 778 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 779 private static final String ATTR_TARGET_PKG = "targetPkg"; 780 private static final String ATTR_URI = "uri"; 781 private static final String ATTR_MODE_FLAGS = "modeFlags"; 782 private static final String ATTR_CREATED_TIME = "createdTime"; 783 private static final String ATTR_PREFIX = "prefix"; 784 785 /** 786 * Global set of specific {@link Uri} permissions that have been granted. 787 * This optimized lookup structure maps from {@link UriPermission#targetUid} 788 * to {@link UriPermission#uri} to {@link UriPermission}. 789 */ 790 @GuardedBy("this") 791 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 792 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 793 794 public static class GrantUri { 795 public final int sourceUserId; 796 public final Uri uri; 797 public boolean prefix; 798 799 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 800 this.sourceUserId = sourceUserId; 801 this.uri = uri; 802 this.prefix = prefix; 803 } 804 805 @Override 806 public int hashCode() { 807 int hashCode = 1; 808 hashCode = 31 * hashCode + sourceUserId; 809 hashCode = 31 * hashCode + uri.hashCode(); 810 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 811 return hashCode; 812 } 813 814 @Override 815 public boolean equals(Object o) { 816 if (o instanceof GrantUri) { 817 GrantUri other = (GrantUri) o; 818 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 819 && prefix == other.prefix; 820 } 821 return false; 822 } 823 824 @Override 825 public String toString() { 826 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 827 if (prefix) result += " [prefix]"; 828 return result; 829 } 830 831 public String toSafeString() { 832 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 833 if (prefix) result += " [prefix]"; 834 return result; 835 } 836 837 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 838 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 839 ContentProvider.getUriWithoutUserId(uri), false); 840 } 841 } 842 843 CoreSettingsObserver mCoreSettingsObserver; 844 845 /** 846 * Thread-local storage used to carry caller permissions over through 847 * indirect content-provider access. 848 */ 849 private class Identity { 850 public final IBinder token; 851 public final int pid; 852 public final int uid; 853 854 Identity(IBinder _token, int _pid, int _uid) { 855 token = _token; 856 pid = _pid; 857 uid = _uid; 858 } 859 } 860 861 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 862 863 /** 864 * All information we have collected about the runtime performance of 865 * any user id that can impact battery performance. 866 */ 867 final BatteryStatsService mBatteryStatsService; 868 869 /** 870 * Information about component usage 871 */ 872 UsageStatsManagerInternal mUsageStatsService; 873 874 /** 875 * Information about and control over application operations 876 */ 877 final AppOpsService mAppOpsService; 878 879 /** 880 * Save recent tasks information across reboots. 881 */ 882 final TaskPersister mTaskPersister; 883 884 /** 885 * Current configuration information. HistoryRecord objects are given 886 * a reference to this object to indicate which configuration they are 887 * currently running in, so this object must be kept immutable. 888 */ 889 Configuration mConfiguration = new Configuration(); 890 891 /** 892 * Current sequencing integer of the configuration, for skipping old 893 * configurations. 894 */ 895 int mConfigurationSeq = 0; 896 897 /** 898 * Hardware-reported OpenGLES version. 899 */ 900 final int GL_ES_VERSION; 901 902 /** 903 * List of initialization arguments to pass to all processes when binding applications to them. 904 * For example, references to the commonly used services. 905 */ 906 HashMap<String, IBinder> mAppBindArgs; 907 908 /** 909 * Temporary to avoid allocations. Protected by main lock. 910 */ 911 final StringBuilder mStringBuilder = new StringBuilder(256); 912 913 /** 914 * Used to control how we initialize the service. 915 */ 916 ComponentName mTopComponent; 917 String mTopAction = Intent.ACTION_MAIN; 918 String mTopData; 919 boolean mProcessesReady = false; 920 boolean mSystemReady = false; 921 boolean mBooting = false; 922 boolean mCallFinishBooting = false; 923 boolean mBootAnimationComplete = false; 924 boolean mWaitingUpdate = false; 925 boolean mDidUpdate = false; 926 boolean mOnBattery = false; 927 boolean mLaunchWarningShown = false; 928 929 Context mContext; 930 931 int mFactoryTest; 932 933 boolean mCheckedForSetup; 934 935 /** 936 * The time at which we will allow normal application switches again, 937 * after a call to {@link #stopAppSwitches()}. 938 */ 939 long mAppSwitchesAllowedTime; 940 941 /** 942 * This is set to true after the first switch after mAppSwitchesAllowedTime 943 * is set; any switches after that will clear the time. 944 */ 945 boolean mDidAppSwitch; 946 947 /** 948 * Last time (in realtime) at which we checked for power usage. 949 */ 950 long mLastPowerCheckRealtime; 951 952 /** 953 * Last time (in uptime) at which we checked for power usage. 954 */ 955 long mLastPowerCheckUptime; 956 957 /** 958 * Set while we are wanting to sleep, to prevent any 959 * activities from being started/resumed. 960 */ 961 private boolean mSleeping = false; 962 963 /** 964 * Set while we are running a voice interaction. This overrides 965 * sleeping while it is active. 966 */ 967 private boolean mRunningVoice = false; 968 969 /** 970 * State of external calls telling us if the device is awake or asleep. 971 */ 972 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 973 974 static final int LOCK_SCREEN_HIDDEN = 0; 975 static final int LOCK_SCREEN_LEAVING = 1; 976 static final int LOCK_SCREEN_SHOWN = 2; 977 /** 978 * State of external call telling us if the lock screen is shown. 979 */ 980 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 981 982 /** 983 * Set if we are shutting down the system, similar to sleeping. 984 */ 985 boolean mShuttingDown = false; 986 987 /** 988 * Current sequence id for oom_adj computation traversal. 989 */ 990 int mAdjSeq = 0; 991 992 /** 993 * Current sequence id for process LRU updating. 994 */ 995 int mLruSeq = 0; 996 997 /** 998 * Keep track of the non-cached/empty process we last found, to help 999 * determine how to distribute cached/empty processes next time. 1000 */ 1001 int mNumNonCachedProcs = 0; 1002 1003 /** 1004 * Keep track of the number of cached hidden procs, to balance oom adj 1005 * distribution between those and empty procs. 1006 */ 1007 int mNumCachedHiddenProcs = 0; 1008 1009 /** 1010 * Keep track of the number of service processes we last found, to 1011 * determine on the next iteration which should be B services. 1012 */ 1013 int mNumServiceProcs = 0; 1014 int mNewNumAServiceProcs = 0; 1015 int mNewNumServiceProcs = 0; 1016 1017 /** 1018 * Allow the current computed overall memory level of the system to go down? 1019 * This is set to false when we are killing processes for reasons other than 1020 * memory management, so that the now smaller process list will not be taken as 1021 * an indication that memory is tighter. 1022 */ 1023 boolean mAllowLowerMemLevel = false; 1024 1025 /** 1026 * The last computed memory level, for holding when we are in a state that 1027 * processes are going away for other reasons. 1028 */ 1029 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1030 1031 /** 1032 * The last total number of process we have, to determine if changes actually look 1033 * like a shrinking number of process due to lower RAM. 1034 */ 1035 int mLastNumProcesses; 1036 1037 /** 1038 * The uptime of the last time we performed idle maintenance. 1039 */ 1040 long mLastIdleTime = SystemClock.uptimeMillis(); 1041 1042 /** 1043 * Total time spent with RAM that has been added in the past since the last idle time. 1044 */ 1045 long mLowRamTimeSinceLastIdle = 0; 1046 1047 /** 1048 * If RAM is currently low, when that horrible situation started. 1049 */ 1050 long mLowRamStartTime = 0; 1051 1052 /** 1053 * For reporting to battery stats the current top application. 1054 */ 1055 private String mCurResumedPackage = null; 1056 private int mCurResumedUid = -1; 1057 1058 /** 1059 * For reporting to battery stats the apps currently running foreground 1060 * service. The ProcessMap is package/uid tuples; each of these contain 1061 * an array of the currently foreground processes. 1062 */ 1063 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1064 = new ProcessMap<ArrayList<ProcessRecord>>(); 1065 1066 /** 1067 * This is set if we had to do a delayed dexopt of an app before launching 1068 * it, to increase the ANR timeouts in that case. 1069 */ 1070 boolean mDidDexOpt; 1071 1072 /** 1073 * Set if the systemServer made a call to enterSafeMode. 1074 */ 1075 boolean mSafeMode; 1076 1077 String mDebugApp = null; 1078 boolean mWaitForDebugger = false; 1079 boolean mDebugTransient = false; 1080 String mOrigDebugApp = null; 1081 boolean mOrigWaitForDebugger = false; 1082 boolean mAlwaysFinishActivities = false; 1083 IActivityController mController = null; 1084 String mProfileApp = null; 1085 ProcessRecord mProfileProc = null; 1086 String mProfileFile; 1087 ParcelFileDescriptor mProfileFd; 1088 int mSamplingInterval = 0; 1089 boolean mAutoStopProfiler = false; 1090 int mProfileType = 0; 1091 String mOpenGlTraceApp = null; 1092 1093 static class ProcessChangeItem { 1094 static final int CHANGE_ACTIVITIES = 1<<0; 1095 static final int CHANGE_PROCESS_STATE = 1<<1; 1096 int changes; 1097 int uid; 1098 int pid; 1099 int processState; 1100 boolean foregroundActivities; 1101 } 1102 1103 final RemoteCallbackList<IProcessObserver> mProcessObservers 1104 = new RemoteCallbackList<IProcessObserver>(); 1105 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1106 1107 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1108 = new ArrayList<ProcessChangeItem>(); 1109 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1110 = new ArrayList<ProcessChangeItem>(); 1111 1112 /** 1113 * Runtime CPU use collection thread. This object's lock is used to 1114 * perform synchronization with the thread (notifying it to run). 1115 */ 1116 final Thread mProcessCpuThread; 1117 1118 /** 1119 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1120 * Must acquire this object's lock when accessing it. 1121 * NOTE: this lock will be held while doing long operations (trawling 1122 * through all processes in /proc), so it should never be acquired by 1123 * any critical paths such as when holding the main activity manager lock. 1124 */ 1125 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1126 MONITOR_THREAD_CPU_USAGE); 1127 final AtomicLong mLastCpuTime = new AtomicLong(0); 1128 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1129 1130 long mLastWriteTime = 0; 1131 1132 /** 1133 * Used to retain an update lock when the foreground activity is in 1134 * immersive mode. 1135 */ 1136 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1137 1138 /** 1139 * Set to true after the system has finished booting. 1140 */ 1141 boolean mBooted = false; 1142 1143 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1144 int mProcessLimitOverride = -1; 1145 1146 WindowManagerService mWindowManager; 1147 1148 final ActivityThread mSystemThread; 1149 1150 // Holds the current foreground user's id 1151 int mCurrentUserId = 0; 1152 // Holds the target user's id during a user switch 1153 int mTargetUserId = UserHandle.USER_NULL; 1154 // If there are multiple profiles for the current user, their ids are here 1155 // Currently only the primary user can have managed profiles 1156 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1157 1158 /** 1159 * Mapping from each known user ID to the profile group ID it is associated with. 1160 */ 1161 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1162 1163 private UserManagerService mUserManager; 1164 1165 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1166 final ProcessRecord mApp; 1167 final int mPid; 1168 final IApplicationThread mAppThread; 1169 1170 AppDeathRecipient(ProcessRecord app, int pid, 1171 IApplicationThread thread) { 1172 if (localLOGV) Slog.v( 1173 TAG, "New death recipient " + this 1174 + " for thread " + thread.asBinder()); 1175 mApp = app; 1176 mPid = pid; 1177 mAppThread = thread; 1178 } 1179 1180 @Override 1181 public void binderDied() { 1182 if (localLOGV) Slog.v( 1183 TAG, "Death received in " + this 1184 + " for thread " + mAppThread.asBinder()); 1185 synchronized(ActivityManagerService.this) { 1186 appDiedLocked(mApp, mPid, mAppThread); 1187 } 1188 } 1189 } 1190 1191 static final int SHOW_ERROR_MSG = 1; 1192 static final int SHOW_NOT_RESPONDING_MSG = 2; 1193 static final int SHOW_FACTORY_ERROR_MSG = 3; 1194 static final int UPDATE_CONFIGURATION_MSG = 4; 1195 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1196 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1197 static final int SERVICE_TIMEOUT_MSG = 12; 1198 static final int UPDATE_TIME_ZONE = 13; 1199 static final int SHOW_UID_ERROR_MSG = 14; 1200 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1201 static final int PROC_START_TIMEOUT_MSG = 20; 1202 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1203 static final int KILL_APPLICATION_MSG = 22; 1204 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1205 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1206 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1207 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1208 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1209 static final int CLEAR_DNS_CACHE_MSG = 28; 1210 static final int UPDATE_HTTP_PROXY_MSG = 29; 1211 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1212 static final int DISPATCH_PROCESSES_CHANGED = 31; 1213 static final int DISPATCH_PROCESS_DIED = 32; 1214 static final int REPORT_MEM_USAGE_MSG = 33; 1215 static final int REPORT_USER_SWITCH_MSG = 34; 1216 static final int CONTINUE_USER_SWITCH_MSG = 35; 1217 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1218 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1219 static final int PERSIST_URI_GRANTS_MSG = 38; 1220 static final int REQUEST_ALL_PSS_MSG = 39; 1221 static final int START_PROFILES_MSG = 40; 1222 static final int UPDATE_TIME = 41; 1223 static final int SYSTEM_USER_START_MSG = 42; 1224 static final int SYSTEM_USER_CURRENT_MSG = 43; 1225 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1226 static final int FINISH_BOOTING_MSG = 45; 1227 static final int START_USER_SWITCH_MSG = 46; 1228 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1229 static final int DISMISS_DIALOG_MSG = 48; 1230 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1231 1232 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1233 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1234 static final int FIRST_COMPAT_MODE_MSG = 300; 1235 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1236 1237 CompatModeDialog mCompatModeDialog; 1238 long mLastMemUsageReportTime = 0; 1239 1240 /** 1241 * Flag whether the current user is a "monkey", i.e. whether 1242 * the UI is driven by a UI automation tool. 1243 */ 1244 private boolean mUserIsMonkey; 1245 1246 /** Flag whether the device has a Recents UI */ 1247 boolean mHasRecents; 1248 1249 /** The dimensions of the thumbnails in the Recents UI. */ 1250 int mThumbnailWidth; 1251 int mThumbnailHeight; 1252 1253 final ServiceThread mHandlerThread; 1254 final MainHandler mHandler; 1255 1256 final class MainHandler extends Handler { 1257 public MainHandler(Looper looper) { 1258 super(looper, null, true); 1259 } 1260 1261 @Override 1262 public void handleMessage(Message msg) { 1263 switch (msg.what) { 1264 case SHOW_ERROR_MSG: { 1265 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1266 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1267 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1268 synchronized (ActivityManagerService.this) { 1269 ProcessRecord proc = (ProcessRecord)data.get("app"); 1270 AppErrorResult res = (AppErrorResult) data.get("result"); 1271 if (proc != null && proc.crashDialog != null) { 1272 Slog.e(TAG, "App already has crash dialog: " + proc); 1273 if (res != null) { 1274 res.set(0); 1275 } 1276 return; 1277 } 1278 boolean isBackground = (UserHandle.getAppId(proc.uid) 1279 >= Process.FIRST_APPLICATION_UID 1280 && proc.pid != MY_PID); 1281 for (int userId : mCurrentProfileIds) { 1282 isBackground &= (proc.userId != userId); 1283 } 1284 if (isBackground && !showBackground) { 1285 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1286 if (res != null) { 1287 res.set(0); 1288 } 1289 return; 1290 } 1291 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1292 Dialog d = new AppErrorDialog(mContext, 1293 ActivityManagerService.this, res, proc); 1294 d.show(); 1295 proc.crashDialog = d; 1296 } else { 1297 // The device is asleep, so just pretend that the user 1298 // saw a crash dialog and hit "force quit". 1299 if (res != null) { 1300 res.set(0); 1301 } 1302 } 1303 } 1304 1305 ensureBootCompleted(); 1306 } break; 1307 case SHOW_NOT_RESPONDING_MSG: { 1308 synchronized (ActivityManagerService.this) { 1309 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1310 ProcessRecord proc = (ProcessRecord)data.get("app"); 1311 if (proc != null && proc.anrDialog != null) { 1312 Slog.e(TAG, "App already has anr dialog: " + proc); 1313 return; 1314 } 1315 1316 Intent intent = new Intent("android.intent.action.ANR"); 1317 if (!mProcessesReady) { 1318 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1319 | Intent.FLAG_RECEIVER_FOREGROUND); 1320 } 1321 broadcastIntentLocked(null, null, intent, 1322 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1323 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1324 1325 if (mShowDialogs) { 1326 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1327 mContext, proc, (ActivityRecord)data.get("activity"), 1328 msg.arg1 != 0); 1329 d.show(); 1330 proc.anrDialog = d; 1331 } else { 1332 // Just kill the app if there is no dialog to be shown. 1333 killAppAtUsersRequest(proc, null); 1334 } 1335 } 1336 1337 ensureBootCompleted(); 1338 } break; 1339 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1340 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1341 synchronized (ActivityManagerService.this) { 1342 ProcessRecord proc = (ProcessRecord) data.get("app"); 1343 if (proc == null) { 1344 Slog.e(TAG, "App not found when showing strict mode dialog."); 1345 break; 1346 } 1347 if (proc.crashDialog != null) { 1348 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1349 return; 1350 } 1351 AppErrorResult res = (AppErrorResult) data.get("result"); 1352 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1353 Dialog d = new StrictModeViolationDialog(mContext, 1354 ActivityManagerService.this, res, proc); 1355 d.show(); 1356 proc.crashDialog = d; 1357 } else { 1358 // The device is asleep, so just pretend that the user 1359 // saw a crash dialog and hit "force quit". 1360 res.set(0); 1361 } 1362 } 1363 ensureBootCompleted(); 1364 } break; 1365 case SHOW_FACTORY_ERROR_MSG: { 1366 Dialog d = new FactoryErrorDialog( 1367 mContext, msg.getData().getCharSequence("msg")); 1368 d.show(); 1369 ensureBootCompleted(); 1370 } break; 1371 case UPDATE_CONFIGURATION_MSG: { 1372 final ContentResolver resolver = mContext.getContentResolver(); 1373 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1374 } break; 1375 case GC_BACKGROUND_PROCESSES_MSG: { 1376 synchronized (ActivityManagerService.this) { 1377 performAppGcsIfAppropriateLocked(); 1378 } 1379 } break; 1380 case WAIT_FOR_DEBUGGER_MSG: { 1381 synchronized (ActivityManagerService.this) { 1382 ProcessRecord app = (ProcessRecord)msg.obj; 1383 if (msg.arg1 != 0) { 1384 if (!app.waitedForDebugger) { 1385 Dialog d = new AppWaitingForDebuggerDialog( 1386 ActivityManagerService.this, 1387 mContext, app); 1388 app.waitDialog = d; 1389 app.waitedForDebugger = true; 1390 d.show(); 1391 } 1392 } else { 1393 if (app.waitDialog != null) { 1394 app.waitDialog.dismiss(); 1395 app.waitDialog = null; 1396 } 1397 } 1398 } 1399 } break; 1400 case SERVICE_TIMEOUT_MSG: { 1401 if (mDidDexOpt) { 1402 mDidDexOpt = false; 1403 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1404 nmsg.obj = msg.obj; 1405 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1406 return; 1407 } 1408 mServices.serviceTimeout((ProcessRecord)msg.obj); 1409 } break; 1410 case UPDATE_TIME_ZONE: { 1411 synchronized (ActivityManagerService.this) { 1412 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1413 ProcessRecord r = mLruProcesses.get(i); 1414 if (r.thread != null) { 1415 try { 1416 r.thread.updateTimeZone(); 1417 } catch (RemoteException ex) { 1418 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1419 } 1420 } 1421 } 1422 } 1423 } break; 1424 case CLEAR_DNS_CACHE_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1427 ProcessRecord r = mLruProcesses.get(i); 1428 if (r.thread != null) { 1429 try { 1430 r.thread.clearDnsCache(); 1431 } catch (RemoteException ex) { 1432 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1433 } 1434 } 1435 } 1436 } 1437 } break; 1438 case UPDATE_HTTP_PROXY_MSG: { 1439 ProxyInfo proxy = (ProxyInfo)msg.obj; 1440 String host = ""; 1441 String port = ""; 1442 String exclList = ""; 1443 Uri pacFileUrl = Uri.EMPTY; 1444 if (proxy != null) { 1445 host = proxy.getHost(); 1446 port = Integer.toString(proxy.getPort()); 1447 exclList = proxy.getExclusionListAsString(); 1448 pacFileUrl = proxy.getPacFileUrl(); 1449 } 1450 synchronized (ActivityManagerService.this) { 1451 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1452 ProcessRecord r = mLruProcesses.get(i); 1453 if (r.thread != null) { 1454 try { 1455 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1456 } catch (RemoteException ex) { 1457 Slog.w(TAG, "Failed to update http proxy for: " + 1458 r.info.processName); 1459 } 1460 } 1461 } 1462 } 1463 } break; 1464 case SHOW_UID_ERROR_MSG: { 1465 if (mShowDialogs) { 1466 AlertDialog d = new BaseErrorDialog(mContext); 1467 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1468 d.setCancelable(false); 1469 d.setTitle(mContext.getText(R.string.android_system_label)); 1470 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1471 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1472 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1473 d.show(); 1474 } 1475 } break; 1476 case SHOW_FINGERPRINT_ERROR_MSG: { 1477 if (mShowDialogs) { 1478 AlertDialog d = new BaseErrorDialog(mContext); 1479 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1480 d.setCancelable(false); 1481 d.setTitle(mContext.getText(R.string.android_system_label)); 1482 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1483 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1484 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1485 d.show(); 1486 } 1487 } break; 1488 case PROC_START_TIMEOUT_MSG: { 1489 if (mDidDexOpt) { 1490 mDidDexOpt = false; 1491 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1492 nmsg.obj = msg.obj; 1493 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1494 return; 1495 } 1496 ProcessRecord app = (ProcessRecord)msg.obj; 1497 synchronized (ActivityManagerService.this) { 1498 processStartTimedOutLocked(app); 1499 } 1500 } break; 1501 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1502 synchronized (ActivityManagerService.this) { 1503 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1504 } 1505 } break; 1506 case KILL_APPLICATION_MSG: { 1507 synchronized (ActivityManagerService.this) { 1508 int appid = msg.arg1; 1509 boolean restart = (msg.arg2 == 1); 1510 Bundle bundle = (Bundle)msg.obj; 1511 String pkg = bundle.getString("pkg"); 1512 String reason = bundle.getString("reason"); 1513 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1514 false, UserHandle.USER_ALL, reason); 1515 } 1516 } break; 1517 case FINALIZE_PENDING_INTENT_MSG: { 1518 ((PendingIntentRecord)msg.obj).completeFinalize(); 1519 } break; 1520 case POST_HEAVY_NOTIFICATION_MSG: { 1521 INotificationManager inm = NotificationManager.getService(); 1522 if (inm == null) { 1523 return; 1524 } 1525 1526 ActivityRecord root = (ActivityRecord)msg.obj; 1527 ProcessRecord process = root.app; 1528 if (process == null) { 1529 return; 1530 } 1531 1532 try { 1533 Context context = mContext.createPackageContext(process.info.packageName, 0); 1534 String text = mContext.getString(R.string.heavy_weight_notification, 1535 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1536 Notification notification = new Notification(); 1537 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1538 notification.when = 0; 1539 notification.flags = Notification.FLAG_ONGOING_EVENT; 1540 notification.tickerText = text; 1541 notification.defaults = 0; // please be quiet 1542 notification.sound = null; 1543 notification.vibrate = null; 1544 notification.color = mContext.getResources().getColor( 1545 com.android.internal.R.color.system_notification_accent_color); 1546 notification.setLatestEventInfo(context, text, 1547 mContext.getText(R.string.heavy_weight_notification_detail), 1548 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1549 PendingIntent.FLAG_CANCEL_CURRENT, null, 1550 new UserHandle(root.userId))); 1551 1552 try { 1553 int[] outId = new int[1]; 1554 inm.enqueueNotificationWithTag("android", "android", null, 1555 R.string.heavy_weight_notification, 1556 notification, outId, root.userId); 1557 } catch (RuntimeException e) { 1558 Slog.w(ActivityManagerService.TAG, 1559 "Error showing notification for heavy-weight app", e); 1560 } catch (RemoteException e) { 1561 } 1562 } catch (NameNotFoundException e) { 1563 Slog.w(TAG, "Unable to create context for heavy notification", e); 1564 } 1565 } break; 1566 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1567 INotificationManager inm = NotificationManager.getService(); 1568 if (inm == null) { 1569 return; 1570 } 1571 try { 1572 inm.cancelNotificationWithTag("android", null, 1573 R.string.heavy_weight_notification, msg.arg1); 1574 } catch (RuntimeException e) { 1575 Slog.w(ActivityManagerService.TAG, 1576 "Error canceling notification for service", e); 1577 } catch (RemoteException e) { 1578 } 1579 } break; 1580 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1581 synchronized (ActivityManagerService.this) { 1582 checkExcessivePowerUsageLocked(true); 1583 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1584 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1585 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1586 } 1587 } break; 1588 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1589 synchronized (ActivityManagerService.this) { 1590 ActivityRecord ar = (ActivityRecord)msg.obj; 1591 if (mCompatModeDialog != null) { 1592 if (mCompatModeDialog.mAppInfo.packageName.equals( 1593 ar.info.applicationInfo.packageName)) { 1594 return; 1595 } 1596 mCompatModeDialog.dismiss(); 1597 mCompatModeDialog = null; 1598 } 1599 if (ar != null && false) { 1600 if (mCompatModePackages.getPackageAskCompatModeLocked( 1601 ar.packageName)) { 1602 int mode = mCompatModePackages.computeCompatModeLocked( 1603 ar.info.applicationInfo); 1604 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1605 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1606 mCompatModeDialog = new CompatModeDialog( 1607 ActivityManagerService.this, mContext, 1608 ar.info.applicationInfo); 1609 mCompatModeDialog.show(); 1610 } 1611 } 1612 } 1613 } 1614 break; 1615 } 1616 case DISPATCH_PROCESSES_CHANGED: { 1617 dispatchProcessesChanged(); 1618 break; 1619 } 1620 case DISPATCH_PROCESS_DIED: { 1621 final int pid = msg.arg1; 1622 final int uid = msg.arg2; 1623 dispatchProcessDied(pid, uid); 1624 break; 1625 } 1626 case REPORT_MEM_USAGE_MSG: { 1627 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1628 Thread thread = new Thread() { 1629 @Override public void run() { 1630 reportMemUsage(memInfos); 1631 } 1632 }; 1633 thread.start(); 1634 break; 1635 } 1636 case START_USER_SWITCH_MSG: { 1637 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1638 break; 1639 } 1640 case REPORT_USER_SWITCH_MSG: { 1641 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1642 break; 1643 } 1644 case CONTINUE_USER_SWITCH_MSG: { 1645 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1646 break; 1647 } 1648 case USER_SWITCH_TIMEOUT_MSG: { 1649 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1650 break; 1651 } 1652 case IMMERSIVE_MODE_LOCK_MSG: { 1653 final boolean nextState = (msg.arg1 != 0); 1654 if (mUpdateLock.isHeld() != nextState) { 1655 if (DEBUG_IMMERSIVE) { 1656 final ActivityRecord r = (ActivityRecord) msg.obj; 1657 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1658 } 1659 if (nextState) { 1660 mUpdateLock.acquire(); 1661 } else { 1662 mUpdateLock.release(); 1663 } 1664 } 1665 break; 1666 } 1667 case PERSIST_URI_GRANTS_MSG: { 1668 writeGrantedUriPermissions(); 1669 break; 1670 } 1671 case REQUEST_ALL_PSS_MSG: { 1672 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1673 break; 1674 } 1675 case START_PROFILES_MSG: { 1676 synchronized (ActivityManagerService.this) { 1677 startProfilesLocked(); 1678 } 1679 break; 1680 } 1681 case UPDATE_TIME: { 1682 synchronized (ActivityManagerService.this) { 1683 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1684 ProcessRecord r = mLruProcesses.get(i); 1685 if (r.thread != null) { 1686 try { 1687 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1688 } catch (RemoteException ex) { 1689 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1690 } 1691 } 1692 } 1693 } 1694 break; 1695 } 1696 case SYSTEM_USER_START_MSG: { 1697 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1698 Integer.toString(msg.arg1), msg.arg1); 1699 mSystemServiceManager.startUser(msg.arg1); 1700 break; 1701 } 1702 case SYSTEM_USER_CURRENT_MSG: { 1703 mBatteryStatsService.noteEvent( 1704 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1705 Integer.toString(msg.arg2), msg.arg2); 1706 mBatteryStatsService.noteEvent( 1707 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1708 Integer.toString(msg.arg1), msg.arg1); 1709 mSystemServiceManager.switchUser(msg.arg1); 1710 break; 1711 } 1712 case ENTER_ANIMATION_COMPLETE_MSG: { 1713 synchronized (ActivityManagerService.this) { 1714 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1715 if (r != null && r.app != null && r.app.thread != null) { 1716 try { 1717 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1718 } catch (RemoteException e) { 1719 } 1720 } 1721 } 1722 break; 1723 } 1724 case FINISH_BOOTING_MSG: { 1725 if (msg.arg1 != 0) { 1726 finishBooting(); 1727 } 1728 if (msg.arg2 != 0) { 1729 enableScreenAfterBoot(); 1730 } 1731 break; 1732 } 1733 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1734 try { 1735 Locale l = (Locale) msg.obj; 1736 IBinder service = ServiceManager.getService("mount"); 1737 IMountService mountService = IMountService.Stub.asInterface(service); 1738 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1739 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1740 } catch (RemoteException e) { 1741 Log.e(TAG, "Error storing locale for decryption UI", e); 1742 } 1743 break; 1744 } 1745 case DISMISS_DIALOG_MSG: { 1746 final Dialog d = (Dialog) msg.obj; 1747 d.dismiss(); 1748 break; 1749 } 1750 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1751 synchronized (ActivityManagerService.this) { 1752 int i = mTaskStackListeners.beginBroadcast(); 1753 while (i > 0) { 1754 i--; 1755 try { 1756 // Make a one-way callback to the listener 1757 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1758 } catch (RemoteException e){ 1759 // Handled by the RemoteCallbackList 1760 } 1761 } 1762 mTaskStackListeners.finishBroadcast(); 1763 } 1764 break; 1765 } 1766 } 1767 } 1768 }; 1769 1770 static final int COLLECT_PSS_BG_MSG = 1; 1771 1772 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1773 @Override 1774 public void handleMessage(Message msg) { 1775 switch (msg.what) { 1776 case COLLECT_PSS_BG_MSG: { 1777 long start = SystemClock.uptimeMillis(); 1778 MemInfoReader memInfo = null; 1779 synchronized (ActivityManagerService.this) { 1780 if (mFullPssPending) { 1781 mFullPssPending = false; 1782 memInfo = new MemInfoReader(); 1783 } 1784 } 1785 if (memInfo != null) { 1786 updateCpuStatsNow(); 1787 long nativeTotalPss = 0; 1788 synchronized (mProcessCpuTracker) { 1789 final int N = mProcessCpuTracker.countStats(); 1790 for (int j=0; j<N; j++) { 1791 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1792 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1793 // This is definitely an application process; skip it. 1794 continue; 1795 } 1796 synchronized (mPidsSelfLocked) { 1797 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1798 // This is one of our own processes; skip it. 1799 continue; 1800 } 1801 } 1802 nativeTotalPss += Debug.getPss(st.pid, null); 1803 } 1804 } 1805 memInfo.readMemInfo(); 1806 synchronized (ActivityManagerService.this) { 1807 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1808 + (SystemClock.uptimeMillis()-start) + "ms"); 1809 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1810 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1811 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1812 } 1813 } 1814 1815 int i = 0; 1816 int num = 0; 1817 long[] tmp = new long[1]; 1818 do { 1819 ProcessRecord proc; 1820 int procState; 1821 int pid; 1822 synchronized (ActivityManagerService.this) { 1823 if (i >= mPendingPssProcesses.size()) { 1824 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1825 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1826 mPendingPssProcesses.clear(); 1827 return; 1828 } 1829 proc = mPendingPssProcesses.get(i); 1830 procState = proc.pssProcState; 1831 if (proc.thread != null && procState == proc.setProcState) { 1832 pid = proc.pid; 1833 } else { 1834 proc = null; 1835 pid = 0; 1836 } 1837 i++; 1838 } 1839 if (proc != null) { 1840 long pss = Debug.getPss(pid, tmp); 1841 synchronized (ActivityManagerService.this) { 1842 if (proc.thread != null && proc.setProcState == procState 1843 && proc.pid == pid) { 1844 num++; 1845 proc.lastPssTime = SystemClock.uptimeMillis(); 1846 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1847 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1848 + ": " + pss + " lastPss=" + proc.lastPss 1849 + " state=" + ProcessList.makeProcStateString(procState)); 1850 if (proc.initialIdlePss == 0) { 1851 proc.initialIdlePss = pss; 1852 } 1853 proc.lastPss = pss; 1854 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1855 proc.lastCachedPss = pss; 1856 } 1857 } 1858 } 1859 } 1860 } while (true); 1861 } 1862 } 1863 } 1864 }; 1865 1866 public void setSystemProcess() { 1867 try { 1868 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1869 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1870 ServiceManager.addService("meminfo", new MemBinder(this)); 1871 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1872 ServiceManager.addService("dbinfo", new DbBinder(this)); 1873 if (MONITOR_CPU_USAGE) { 1874 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1875 } 1876 ServiceManager.addService("permission", new PermissionController(this)); 1877 1878 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1879 "android", STOCK_PM_FLAGS); 1880 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1881 1882 synchronized (this) { 1883 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1884 app.persistent = true; 1885 app.pid = MY_PID; 1886 app.maxAdj = ProcessList.SYSTEM_ADJ; 1887 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1888 mProcessNames.put(app.processName, app.uid, app); 1889 synchronized (mPidsSelfLocked) { 1890 mPidsSelfLocked.put(app.pid, app); 1891 } 1892 updateLruProcessLocked(app, false, null); 1893 updateOomAdjLocked(); 1894 } 1895 } catch (PackageManager.NameNotFoundException e) { 1896 throw new RuntimeException( 1897 "Unable to find android system package", e); 1898 } 1899 } 1900 1901 public void setWindowManager(WindowManagerService wm) { 1902 mWindowManager = wm; 1903 mStackSupervisor.setWindowManager(wm); 1904 } 1905 1906 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1907 mUsageStatsService = usageStatsManager; 1908 } 1909 1910 public void startObservingNativeCrashes() { 1911 final NativeCrashListener ncl = new NativeCrashListener(this); 1912 ncl.start(); 1913 } 1914 1915 public IAppOpsService getAppOpsService() { 1916 return mAppOpsService; 1917 } 1918 1919 static class MemBinder extends Binder { 1920 ActivityManagerService mActivityManagerService; 1921 MemBinder(ActivityManagerService activityManagerService) { 1922 mActivityManagerService = activityManagerService; 1923 } 1924 1925 @Override 1926 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1927 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1928 != PackageManager.PERMISSION_GRANTED) { 1929 pw.println("Permission Denial: can't dump meminfo from from pid=" 1930 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1931 + " without permission " + android.Manifest.permission.DUMP); 1932 return; 1933 } 1934 1935 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1936 } 1937 } 1938 1939 static class GraphicsBinder extends Binder { 1940 ActivityManagerService mActivityManagerService; 1941 GraphicsBinder(ActivityManagerService activityManagerService) { 1942 mActivityManagerService = activityManagerService; 1943 } 1944 1945 @Override 1946 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1947 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1948 != PackageManager.PERMISSION_GRANTED) { 1949 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1950 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1951 + " without permission " + android.Manifest.permission.DUMP); 1952 return; 1953 } 1954 1955 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1956 } 1957 } 1958 1959 static class DbBinder extends Binder { 1960 ActivityManagerService mActivityManagerService; 1961 DbBinder(ActivityManagerService activityManagerService) { 1962 mActivityManagerService = activityManagerService; 1963 } 1964 1965 @Override 1966 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1967 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1968 != PackageManager.PERMISSION_GRANTED) { 1969 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1970 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1971 + " without permission " + android.Manifest.permission.DUMP); 1972 return; 1973 } 1974 1975 mActivityManagerService.dumpDbInfo(fd, pw, args); 1976 } 1977 } 1978 1979 static class CpuBinder extends Binder { 1980 ActivityManagerService mActivityManagerService; 1981 CpuBinder(ActivityManagerService activityManagerService) { 1982 mActivityManagerService = activityManagerService; 1983 } 1984 1985 @Override 1986 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1987 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1988 != PackageManager.PERMISSION_GRANTED) { 1989 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1990 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1991 + " without permission " + android.Manifest.permission.DUMP); 1992 return; 1993 } 1994 1995 synchronized (mActivityManagerService.mProcessCpuTracker) { 1996 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1997 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1998 SystemClock.uptimeMillis())); 1999 } 2000 } 2001 } 2002 2003 public static final class Lifecycle extends SystemService { 2004 private final ActivityManagerService mService; 2005 2006 public Lifecycle(Context context) { 2007 super(context); 2008 mService = new ActivityManagerService(context); 2009 } 2010 2011 @Override 2012 public void onStart() { 2013 mService.start(); 2014 } 2015 2016 public ActivityManagerService getService() { 2017 return mService; 2018 } 2019 } 2020 2021 // Note: This method is invoked on the main thread but may need to attach various 2022 // handlers to other threads. So take care to be explicit about the looper. 2023 public ActivityManagerService(Context systemContext) { 2024 mContext = systemContext; 2025 mFactoryTest = FactoryTest.getMode(); 2026 mSystemThread = ActivityThread.currentActivityThread(); 2027 2028 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2029 2030 mHandlerThread = new ServiceThread(TAG, 2031 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2032 mHandlerThread.start(); 2033 mHandler = new MainHandler(mHandlerThread.getLooper()); 2034 2035 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2036 "foreground", BROADCAST_FG_TIMEOUT, false); 2037 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2038 "background", BROADCAST_BG_TIMEOUT, true); 2039 mBroadcastQueues[0] = mFgBroadcastQueue; 2040 mBroadcastQueues[1] = mBgBroadcastQueue; 2041 2042 mServices = new ActiveServices(this); 2043 mProviderMap = new ProviderMap(this); 2044 2045 // TODO: Move creation of battery stats service outside of activity manager service. 2046 File dataDir = Environment.getDataDirectory(); 2047 File systemDir = new File(dataDir, "system"); 2048 systemDir.mkdirs(); 2049 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2050 mBatteryStatsService.getActiveStatistics().readLocked(); 2051 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2052 mOnBattery = DEBUG_POWER ? true 2053 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2054 mBatteryStatsService.getActiveStatistics().setCallback(this); 2055 2056 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2057 2058 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2059 2060 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2061 2062 // User 0 is the first and only user that runs at boot. 2063 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2064 mUserLru.add(Integer.valueOf(0)); 2065 updateStartedUserArrayLocked(); 2066 2067 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2068 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2069 2070 mConfiguration.setToDefaults(); 2071 mConfiguration.setLocale(Locale.getDefault()); 2072 2073 mConfigurationSeq = mConfiguration.seq = 1; 2074 mProcessCpuTracker.init(); 2075 2076 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2077 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2078 mStackSupervisor = new ActivityStackSupervisor(this); 2079 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2080 2081 mProcessCpuThread = new Thread("CpuTracker") { 2082 @Override 2083 public void run() { 2084 while (true) { 2085 try { 2086 try { 2087 synchronized(this) { 2088 final long now = SystemClock.uptimeMillis(); 2089 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2090 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2091 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2092 // + ", write delay=" + nextWriteDelay); 2093 if (nextWriteDelay < nextCpuDelay) { 2094 nextCpuDelay = nextWriteDelay; 2095 } 2096 if (nextCpuDelay > 0) { 2097 mProcessCpuMutexFree.set(true); 2098 this.wait(nextCpuDelay); 2099 } 2100 } 2101 } catch (InterruptedException e) { 2102 } 2103 updateCpuStatsNow(); 2104 } catch (Exception e) { 2105 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2106 } 2107 } 2108 } 2109 }; 2110 2111 Watchdog.getInstance().addMonitor(this); 2112 Watchdog.getInstance().addThread(mHandler); 2113 } 2114 2115 public void setSystemServiceManager(SystemServiceManager mgr) { 2116 mSystemServiceManager = mgr; 2117 } 2118 2119 public void setInstaller(Installer installer) { 2120 mInstaller = installer; 2121 } 2122 2123 private void start() { 2124 Process.removeAllProcessGroups(); 2125 mProcessCpuThread.start(); 2126 2127 mBatteryStatsService.publish(mContext); 2128 mAppOpsService.publish(mContext); 2129 Slog.d("AppOps", "AppOpsService published"); 2130 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2131 } 2132 2133 public void initPowerManagement() { 2134 mStackSupervisor.initPowerManagement(); 2135 mBatteryStatsService.initPowerManagement(); 2136 } 2137 2138 @Override 2139 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2140 throws RemoteException { 2141 if (code == SYSPROPS_TRANSACTION) { 2142 // We need to tell all apps about the system property change. 2143 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2144 synchronized(this) { 2145 final int NP = mProcessNames.getMap().size(); 2146 for (int ip=0; ip<NP; ip++) { 2147 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2148 final int NA = apps.size(); 2149 for (int ia=0; ia<NA; ia++) { 2150 ProcessRecord app = apps.valueAt(ia); 2151 if (app.thread != null) { 2152 procs.add(app.thread.asBinder()); 2153 } 2154 } 2155 } 2156 } 2157 2158 int N = procs.size(); 2159 for (int i=0; i<N; i++) { 2160 Parcel data2 = Parcel.obtain(); 2161 try { 2162 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2163 } catch (RemoteException e) { 2164 } 2165 data2.recycle(); 2166 } 2167 } 2168 try { 2169 return super.onTransact(code, data, reply, flags); 2170 } catch (RuntimeException e) { 2171 // The activity manager only throws security exceptions, so let's 2172 // log all others. 2173 if (!(e instanceof SecurityException)) { 2174 Slog.wtf(TAG, "Activity Manager Crash", e); 2175 } 2176 throw e; 2177 } 2178 } 2179 2180 void updateCpuStats() { 2181 final long now = SystemClock.uptimeMillis(); 2182 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2183 return; 2184 } 2185 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2186 synchronized (mProcessCpuThread) { 2187 mProcessCpuThread.notify(); 2188 } 2189 } 2190 } 2191 2192 void updateCpuStatsNow() { 2193 synchronized (mProcessCpuTracker) { 2194 mProcessCpuMutexFree.set(false); 2195 final long now = SystemClock.uptimeMillis(); 2196 boolean haveNewCpuStats = false; 2197 2198 if (MONITOR_CPU_USAGE && 2199 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2200 mLastCpuTime.set(now); 2201 haveNewCpuStats = true; 2202 mProcessCpuTracker.update(); 2203 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2204 //Slog.i(TAG, "Total CPU usage: " 2205 // + mProcessCpu.getTotalCpuPercent() + "%"); 2206 2207 // Slog the cpu usage if the property is set. 2208 if ("true".equals(SystemProperties.get("events.cpu"))) { 2209 int user = mProcessCpuTracker.getLastUserTime(); 2210 int system = mProcessCpuTracker.getLastSystemTime(); 2211 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2212 int irq = mProcessCpuTracker.getLastIrqTime(); 2213 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2214 int idle = mProcessCpuTracker.getLastIdleTime(); 2215 2216 int total = user + system + iowait + irq + softIrq + idle; 2217 if (total == 0) total = 1; 2218 2219 EventLog.writeEvent(EventLogTags.CPU, 2220 ((user+system+iowait+irq+softIrq) * 100) / total, 2221 (user * 100) / total, 2222 (system * 100) / total, 2223 (iowait * 100) / total, 2224 (irq * 100) / total, 2225 (softIrq * 100) / total); 2226 } 2227 } 2228 2229 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2230 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2231 synchronized(bstats) { 2232 synchronized(mPidsSelfLocked) { 2233 if (haveNewCpuStats) { 2234 if (mOnBattery) { 2235 int perc = bstats.startAddingCpuLocked(); 2236 int totalUTime = 0; 2237 int totalSTime = 0; 2238 final int N = mProcessCpuTracker.countStats(); 2239 for (int i=0; i<N; i++) { 2240 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2241 if (!st.working) { 2242 continue; 2243 } 2244 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2245 int otherUTime = (st.rel_utime*perc)/100; 2246 int otherSTime = (st.rel_stime*perc)/100; 2247 totalUTime += otherUTime; 2248 totalSTime += otherSTime; 2249 if (pr != null) { 2250 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2251 if (ps == null || !ps.isActive()) { 2252 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2253 pr.info.uid, pr.processName); 2254 } 2255 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2256 st.rel_stime-otherSTime); 2257 ps.addSpeedStepTimes(cpuSpeedTimes); 2258 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2259 } else { 2260 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2261 if (ps == null || !ps.isActive()) { 2262 st.batteryStats = ps = bstats.getProcessStatsLocked( 2263 bstats.mapUid(st.uid), st.name); 2264 } 2265 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2266 st.rel_stime-otherSTime); 2267 ps.addSpeedStepTimes(cpuSpeedTimes); 2268 } 2269 } 2270 bstats.finishAddingCpuLocked(perc, totalUTime, 2271 totalSTime, cpuSpeedTimes); 2272 } 2273 } 2274 } 2275 2276 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2277 mLastWriteTime = now; 2278 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2279 } 2280 } 2281 } 2282 } 2283 2284 @Override 2285 public void batteryNeedsCpuUpdate() { 2286 updateCpuStatsNow(); 2287 } 2288 2289 @Override 2290 public void batteryPowerChanged(boolean onBattery) { 2291 // When plugging in, update the CPU stats first before changing 2292 // the plug state. 2293 updateCpuStatsNow(); 2294 synchronized (this) { 2295 synchronized(mPidsSelfLocked) { 2296 mOnBattery = DEBUG_POWER ? true : onBattery; 2297 } 2298 } 2299 } 2300 2301 /** 2302 * Initialize the application bind args. These are passed to each 2303 * process when the bindApplication() IPC is sent to the process. They're 2304 * lazily setup to make sure the services are running when they're asked for. 2305 */ 2306 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2307 if (mAppBindArgs == null) { 2308 mAppBindArgs = new HashMap<>(); 2309 2310 // Isolated processes won't get this optimization, so that we don't 2311 // violate the rules about which services they have access to. 2312 if (!isolated) { 2313 // Setup the application init args 2314 mAppBindArgs.put("package", ServiceManager.getService("package")); 2315 mAppBindArgs.put("window", ServiceManager.getService("window")); 2316 mAppBindArgs.put(Context.ALARM_SERVICE, 2317 ServiceManager.getService(Context.ALARM_SERVICE)); 2318 } 2319 } 2320 return mAppBindArgs; 2321 } 2322 2323 final void setFocusedActivityLocked(ActivityRecord r) { 2324 if (mFocusedActivity != r) { 2325 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2326 mFocusedActivity = r; 2327 if (r.task != null && r.task.voiceInteractor != null) { 2328 startRunningVoiceLocked(); 2329 } else { 2330 finishRunningVoiceLocked(); 2331 } 2332 mStackSupervisor.setFocusedStack(r); 2333 if (r != null) { 2334 mWindowManager.setFocusedApp(r.appToken, true); 2335 } 2336 applyUpdateLockStateLocked(r); 2337 } 2338 } 2339 2340 final void clearFocusedActivity(ActivityRecord r) { 2341 if (mFocusedActivity == r) { 2342 mFocusedActivity = null; 2343 } 2344 } 2345 2346 @Override 2347 public void setFocusedStack(int stackId) { 2348 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2349 synchronized (ActivityManagerService.this) { 2350 ActivityStack stack = mStackSupervisor.getStack(stackId); 2351 if (stack != null) { 2352 ActivityRecord r = stack.topRunningActivityLocked(null); 2353 if (r != null) { 2354 setFocusedActivityLocked(r); 2355 } 2356 } 2357 } 2358 } 2359 2360 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2361 @Override 2362 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2363 synchronized (ActivityManagerService.this) { 2364 if (listener != null) { 2365 mTaskStackListeners.register(listener); 2366 } 2367 } 2368 } 2369 2370 @Override 2371 public void notifyActivityDrawn(IBinder token) { 2372 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2373 synchronized (this) { 2374 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2375 if (r != null) { 2376 r.task.stack.notifyActivityDrawnLocked(r); 2377 } 2378 } 2379 } 2380 2381 final void applyUpdateLockStateLocked(ActivityRecord r) { 2382 // Modifications to the UpdateLock state are done on our handler, outside 2383 // the activity manager's locks. The new state is determined based on the 2384 // state *now* of the relevant activity record. The object is passed to 2385 // the handler solely for logging detail, not to be consulted/modified. 2386 final boolean nextState = r != null && r.immersive; 2387 mHandler.sendMessage( 2388 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2389 } 2390 2391 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2392 Message msg = Message.obtain(); 2393 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2394 msg.obj = r.task.askedCompatMode ? null : r; 2395 mHandler.sendMessage(msg); 2396 } 2397 2398 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2399 String what, Object obj, ProcessRecord srcApp) { 2400 app.lastActivityTime = now; 2401 2402 if (app.activities.size() > 0) { 2403 // Don't want to touch dependent processes that are hosting activities. 2404 return index; 2405 } 2406 2407 int lrui = mLruProcesses.lastIndexOf(app); 2408 if (lrui < 0) { 2409 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2410 + what + " " + obj + " from " + srcApp); 2411 return index; 2412 } 2413 2414 if (lrui >= index) { 2415 // Don't want to cause this to move dependent processes *back* in the 2416 // list as if they were less frequently used. 2417 return index; 2418 } 2419 2420 if (lrui >= mLruProcessActivityStart) { 2421 // Don't want to touch dependent processes that are hosting activities. 2422 return index; 2423 } 2424 2425 mLruProcesses.remove(lrui); 2426 if (index > 0) { 2427 index--; 2428 } 2429 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2430 + " in LRU list: " + app); 2431 mLruProcesses.add(index, app); 2432 return index; 2433 } 2434 2435 final void removeLruProcessLocked(ProcessRecord app) { 2436 int lrui = mLruProcesses.lastIndexOf(app); 2437 if (lrui >= 0) { 2438 if (!app.killed) { 2439 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2440 Process.killProcessQuiet(app.pid); 2441 Process.killProcessGroup(app.info.uid, app.pid); 2442 } 2443 if (lrui <= mLruProcessActivityStart) { 2444 mLruProcessActivityStart--; 2445 } 2446 if (lrui <= mLruProcessServiceStart) { 2447 mLruProcessServiceStart--; 2448 } 2449 mLruProcesses.remove(lrui); 2450 } 2451 } 2452 2453 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2454 ProcessRecord client) { 2455 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2456 || app.treatLikeActivity; 2457 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2458 if (!activityChange && hasActivity) { 2459 // The process has activities, so we are only allowing activity-based adjustments 2460 // to move it. It should be kept in the front of the list with other 2461 // processes that have activities, and we don't want those to change their 2462 // order except due to activity operations. 2463 return; 2464 } 2465 2466 mLruSeq++; 2467 final long now = SystemClock.uptimeMillis(); 2468 app.lastActivityTime = now; 2469 2470 // First a quick reject: if the app is already at the position we will 2471 // put it, then there is nothing to do. 2472 if (hasActivity) { 2473 final int N = mLruProcesses.size(); 2474 if (N > 0 && mLruProcesses.get(N-1) == app) { 2475 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2476 return; 2477 } 2478 } else { 2479 if (mLruProcessServiceStart > 0 2480 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2481 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2482 return; 2483 } 2484 } 2485 2486 int lrui = mLruProcesses.lastIndexOf(app); 2487 2488 if (app.persistent && lrui >= 0) { 2489 // We don't care about the position of persistent processes, as long as 2490 // they are in the list. 2491 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2492 return; 2493 } 2494 2495 /* In progress: compute new position first, so we can avoid doing work 2496 if the process is not actually going to move. Not yet working. 2497 int addIndex; 2498 int nextIndex; 2499 boolean inActivity = false, inService = false; 2500 if (hasActivity) { 2501 // Process has activities, put it at the very tipsy-top. 2502 addIndex = mLruProcesses.size(); 2503 nextIndex = mLruProcessServiceStart; 2504 inActivity = true; 2505 } else if (hasService) { 2506 // Process has services, put it at the top of the service list. 2507 addIndex = mLruProcessActivityStart; 2508 nextIndex = mLruProcessServiceStart; 2509 inActivity = true; 2510 inService = true; 2511 } else { 2512 // Process not otherwise of interest, it goes to the top of the non-service area. 2513 addIndex = mLruProcessServiceStart; 2514 if (client != null) { 2515 int clientIndex = mLruProcesses.lastIndexOf(client); 2516 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2517 + app); 2518 if (clientIndex >= 0 && addIndex > clientIndex) { 2519 addIndex = clientIndex; 2520 } 2521 } 2522 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2523 } 2524 2525 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2526 + mLruProcessActivityStart + "): " + app); 2527 */ 2528 2529 if (lrui >= 0) { 2530 if (lrui < mLruProcessActivityStart) { 2531 mLruProcessActivityStart--; 2532 } 2533 if (lrui < mLruProcessServiceStart) { 2534 mLruProcessServiceStart--; 2535 } 2536 /* 2537 if (addIndex > lrui) { 2538 addIndex--; 2539 } 2540 if (nextIndex > lrui) { 2541 nextIndex--; 2542 } 2543 */ 2544 mLruProcesses.remove(lrui); 2545 } 2546 2547 /* 2548 mLruProcesses.add(addIndex, app); 2549 if (inActivity) { 2550 mLruProcessActivityStart++; 2551 } 2552 if (inService) { 2553 mLruProcessActivityStart++; 2554 } 2555 */ 2556 2557 int nextIndex; 2558 if (hasActivity) { 2559 final int N = mLruProcesses.size(); 2560 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2561 // Process doesn't have activities, but has clients with 2562 // activities... move it up, but one below the top (the top 2563 // should always have a real activity). 2564 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2565 mLruProcesses.add(N-1, app); 2566 // To keep it from spamming the LRU list (by making a bunch of clients), 2567 // we will push down any other entries owned by the app. 2568 final int uid = app.info.uid; 2569 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2570 ProcessRecord subProc = mLruProcesses.get(i); 2571 if (subProc.info.uid == uid) { 2572 // We want to push this one down the list. If the process after 2573 // it is for the same uid, however, don't do so, because we don't 2574 // want them internally to be re-ordered. 2575 if (mLruProcesses.get(i-1).info.uid != uid) { 2576 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2577 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2578 ProcessRecord tmp = mLruProcesses.get(i); 2579 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2580 mLruProcesses.set(i-1, tmp); 2581 i--; 2582 } 2583 } else { 2584 // A gap, we can stop here. 2585 break; 2586 } 2587 } 2588 } else { 2589 // Process has activities, put it at the very tipsy-top. 2590 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2591 mLruProcesses.add(app); 2592 } 2593 nextIndex = mLruProcessServiceStart; 2594 } else if (hasService) { 2595 // Process has services, put it at the top of the service list. 2596 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2597 mLruProcesses.add(mLruProcessActivityStart, app); 2598 nextIndex = mLruProcessServiceStart; 2599 mLruProcessActivityStart++; 2600 } else { 2601 // Process not otherwise of interest, it goes to the top of the non-service area. 2602 int index = mLruProcessServiceStart; 2603 if (client != null) { 2604 // If there is a client, don't allow the process to be moved up higher 2605 // in the list than that client. 2606 int clientIndex = mLruProcesses.lastIndexOf(client); 2607 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2608 + " when updating " + app); 2609 if (clientIndex <= lrui) { 2610 // Don't allow the client index restriction to push it down farther in the 2611 // list than it already is. 2612 clientIndex = lrui; 2613 } 2614 if (clientIndex >= 0 && index > clientIndex) { 2615 index = clientIndex; 2616 } 2617 } 2618 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2619 mLruProcesses.add(index, app); 2620 nextIndex = index-1; 2621 mLruProcessActivityStart++; 2622 mLruProcessServiceStart++; 2623 } 2624 2625 // If the app is currently using a content provider or service, 2626 // bump those processes as well. 2627 for (int j=app.connections.size()-1; j>=0; j--) { 2628 ConnectionRecord cr = app.connections.valueAt(j); 2629 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2630 && cr.binding.service.app != null 2631 && cr.binding.service.app.lruSeq != mLruSeq 2632 && !cr.binding.service.app.persistent) { 2633 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2634 "service connection", cr, app); 2635 } 2636 } 2637 for (int j=app.conProviders.size()-1; j>=0; j--) { 2638 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2639 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2640 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2641 "provider reference", cpr, app); 2642 } 2643 } 2644 } 2645 2646 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2647 if (uid == Process.SYSTEM_UID) { 2648 // The system gets to run in any process. If there are multiple 2649 // processes with the same uid, just pick the first (this 2650 // should never happen). 2651 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2652 if (procs == null) return null; 2653 final int N = procs.size(); 2654 for (int i = 0; i < N; i++) { 2655 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2656 } 2657 } 2658 ProcessRecord proc = mProcessNames.get(processName, uid); 2659 if (false && proc != null && !keepIfLarge 2660 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2661 && proc.lastCachedPss >= 4000) { 2662 // Turn this condition on to cause killing to happen regularly, for testing. 2663 if (proc.baseProcessTracker != null) { 2664 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2665 } 2666 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2667 } else if (proc != null && !keepIfLarge 2668 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2669 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2670 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2671 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2672 if (proc.baseProcessTracker != null) { 2673 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2674 } 2675 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2676 } 2677 } 2678 return proc; 2679 } 2680 2681 void ensurePackageDexOpt(String packageName) { 2682 IPackageManager pm = AppGlobals.getPackageManager(); 2683 try { 2684 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2685 mDidDexOpt = true; 2686 } 2687 } catch (RemoteException e) { 2688 } 2689 } 2690 2691 boolean isNextTransitionForward() { 2692 int transit = mWindowManager.getPendingAppTransition(); 2693 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2694 || transit == AppTransition.TRANSIT_TASK_OPEN 2695 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2696 } 2697 2698 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2699 String processName, String abiOverride, int uid, Runnable crashHandler) { 2700 synchronized(this) { 2701 ApplicationInfo info = new ApplicationInfo(); 2702 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2703 // For isolated processes, the former contains the parent's uid and the latter the 2704 // actual uid of the isolated process. 2705 // In the special case introduced by this method (which is, starting an isolated 2706 // process directly from the SystemServer without an actual parent app process) the 2707 // closest thing to a parent's uid is SYSTEM_UID. 2708 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2709 // the |isolated| logic in the ProcessRecord constructor. 2710 info.uid = Process.SYSTEM_UID; 2711 info.processName = processName; 2712 info.className = entryPoint; 2713 info.packageName = "android"; 2714 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2715 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2716 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2717 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2718 crashHandler); 2719 return proc != null ? proc.pid : 0; 2720 } 2721 } 2722 2723 final ProcessRecord startProcessLocked(String processName, 2724 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2725 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2726 boolean isolated, boolean keepIfLarge) { 2727 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2728 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2729 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2730 null /* crashHandler */); 2731 } 2732 2733 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2734 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2735 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2736 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2737 long startTime = SystemClock.elapsedRealtime(); 2738 ProcessRecord app; 2739 if (!isolated) { 2740 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2741 checkTime(startTime, "startProcess: after getProcessRecord"); 2742 } else { 2743 // If this is an isolated process, it can't re-use an existing process. 2744 app = null; 2745 } 2746 // We don't have to do anything more if: 2747 // (1) There is an existing application record; and 2748 // (2) The caller doesn't think it is dead, OR there is no thread 2749 // object attached to it so we know it couldn't have crashed; and 2750 // (3) There is a pid assigned to it, so it is either starting or 2751 // already running. 2752 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2753 + " app=" + app + " knownToBeDead=" + knownToBeDead 2754 + " thread=" + (app != null ? app.thread : null) 2755 + " pid=" + (app != null ? app.pid : -1)); 2756 if (app != null && app.pid > 0) { 2757 if (!knownToBeDead || app.thread == null) { 2758 // We already have the app running, or are waiting for it to 2759 // come up (we have a pid but not yet its thread), so keep it. 2760 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2761 // If this is a new package in the process, add the package to the list 2762 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2763 checkTime(startTime, "startProcess: done, added package to proc"); 2764 return app; 2765 } 2766 2767 // An application record is attached to a previous process, 2768 // clean it up now. 2769 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2770 checkTime(startTime, "startProcess: bad proc running, killing"); 2771 Process.killProcessGroup(app.info.uid, app.pid); 2772 handleAppDiedLocked(app, true, true); 2773 checkTime(startTime, "startProcess: done killing old proc"); 2774 } 2775 2776 String hostingNameStr = hostingName != null 2777 ? hostingName.flattenToShortString() : null; 2778 2779 if (!isolated) { 2780 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2781 // If we are in the background, then check to see if this process 2782 // is bad. If so, we will just silently fail. 2783 if (mBadProcesses.get(info.processName, info.uid) != null) { 2784 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2785 + "/" + info.processName); 2786 return null; 2787 } 2788 } else { 2789 // When the user is explicitly starting a process, then clear its 2790 // crash count so that we won't make it bad until they see at 2791 // least one crash dialog again, and make the process good again 2792 // if it had been bad. 2793 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2794 + "/" + info.processName); 2795 mProcessCrashTimes.remove(info.processName, info.uid); 2796 if (mBadProcesses.get(info.processName, info.uid) != null) { 2797 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2798 UserHandle.getUserId(info.uid), info.uid, 2799 info.processName); 2800 mBadProcesses.remove(info.processName, info.uid); 2801 if (app != null) { 2802 app.bad = false; 2803 } 2804 } 2805 } 2806 } 2807 2808 if (app == null) { 2809 checkTime(startTime, "startProcess: creating new process record"); 2810 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2811 app.crashHandler = crashHandler; 2812 if (app == null) { 2813 Slog.w(TAG, "Failed making new process record for " 2814 + processName + "/" + info.uid + " isolated=" + isolated); 2815 return null; 2816 } 2817 mProcessNames.put(processName, app.uid, app); 2818 if (isolated) { 2819 mIsolatedProcesses.put(app.uid, app); 2820 } 2821 checkTime(startTime, "startProcess: done creating new process record"); 2822 } else { 2823 // If this is a new package in the process, add the package to the list 2824 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2825 checkTime(startTime, "startProcess: added package to existing proc"); 2826 } 2827 2828 // If the system is not ready yet, then hold off on starting this 2829 // process until it is. 2830 if (!mProcessesReady 2831 && !isAllowedWhileBooting(info) 2832 && !allowWhileBooting) { 2833 if (!mProcessesOnHold.contains(app)) { 2834 mProcessesOnHold.add(app); 2835 } 2836 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2837 checkTime(startTime, "startProcess: returning with proc on hold"); 2838 return app; 2839 } 2840 2841 checkTime(startTime, "startProcess: stepping in to startProcess"); 2842 startProcessLocked( 2843 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2844 checkTime(startTime, "startProcess: done starting proc!"); 2845 return (app.pid != 0) ? app : null; 2846 } 2847 2848 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2849 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2850 } 2851 2852 private final void startProcessLocked(ProcessRecord app, 2853 String hostingType, String hostingNameStr) { 2854 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2855 null /* entryPoint */, null /* entryPointArgs */); 2856 } 2857 2858 private final void startProcessLocked(ProcessRecord app, String hostingType, 2859 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2860 long startTime = SystemClock.elapsedRealtime(); 2861 if (app.pid > 0 && app.pid != MY_PID) { 2862 checkTime(startTime, "startProcess: removing from pids map"); 2863 synchronized (mPidsSelfLocked) { 2864 mPidsSelfLocked.remove(app.pid); 2865 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2866 } 2867 checkTime(startTime, "startProcess: done removing from pids map"); 2868 app.setPid(0); 2869 } 2870 2871 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2872 "startProcessLocked removing on hold: " + app); 2873 mProcessesOnHold.remove(app); 2874 2875 checkTime(startTime, "startProcess: starting to update cpu stats"); 2876 updateCpuStats(); 2877 checkTime(startTime, "startProcess: done updating cpu stats"); 2878 2879 try { 2880 int uid = app.uid; 2881 2882 int[] gids = null; 2883 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2884 if (!app.isolated) { 2885 int[] permGids = null; 2886 try { 2887 checkTime(startTime, "startProcess: getting gids from package manager"); 2888 final PackageManager pm = mContext.getPackageManager(); 2889 permGids = pm.getPackageGids(app.info.packageName); 2890 2891 if (Environment.isExternalStorageEmulated()) { 2892 checkTime(startTime, "startProcess: checking external storage perm"); 2893 if (pm.checkPermission( 2894 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2895 app.info.packageName) == PERMISSION_GRANTED) { 2896 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2897 } else { 2898 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2899 } 2900 } 2901 } catch (PackageManager.NameNotFoundException e) { 2902 Slog.w(TAG, "Unable to retrieve gids", e); 2903 } 2904 2905 /* 2906 * Add shared application and profile GIDs so applications can share some 2907 * resources like shared libraries and access user-wide resources 2908 */ 2909 if (permGids == null) { 2910 gids = new int[2]; 2911 } else { 2912 gids = new int[permGids.length + 2]; 2913 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2914 } 2915 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2916 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2917 } 2918 checkTime(startTime, "startProcess: building args"); 2919 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2920 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2921 && mTopComponent != null 2922 && app.processName.equals(mTopComponent.getPackageName())) { 2923 uid = 0; 2924 } 2925 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2926 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2927 uid = 0; 2928 } 2929 } 2930 int debugFlags = 0; 2931 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2932 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2933 // Also turn on CheckJNI for debuggable apps. It's quite 2934 // awkward to turn on otherwise. 2935 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2936 } 2937 // Run the app in safe mode if its manifest requests so or the 2938 // system is booted in safe mode. 2939 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2940 mSafeMode == true) { 2941 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2942 } 2943 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2944 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2945 } 2946 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2947 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2948 } 2949 if ("1".equals(SystemProperties.get("debug.assert"))) { 2950 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2951 } 2952 2953 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2954 if (requiredAbi == null) { 2955 requiredAbi = Build.SUPPORTED_ABIS[0]; 2956 } 2957 2958 String instructionSet = null; 2959 if (app.info.primaryCpuAbi != null) { 2960 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2961 } 2962 2963 // Start the process. It will either succeed and return a result containing 2964 // the PID of the new process, or else throw a RuntimeException. 2965 boolean isActivityProcess = (entryPoint == null); 2966 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2967 checkTime(startTime, "startProcess: asking zygote to start proc"); 2968 Process.ProcessStartResult startResult = Process.start(entryPoint, 2969 app.processName, uid, uid, gids, debugFlags, mountExternal, 2970 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2971 app.info.dataDir, entryPointArgs); 2972 checkTime(startTime, "startProcess: returned from zygote!"); 2973 2974 if (app.isolated) { 2975 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2976 } 2977 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2978 checkTime(startTime, "startProcess: done updating battery stats"); 2979 2980 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2981 UserHandle.getUserId(uid), startResult.pid, uid, 2982 app.processName, hostingType, 2983 hostingNameStr != null ? hostingNameStr : ""); 2984 2985 if (app.persistent) { 2986 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2987 } 2988 2989 checkTime(startTime, "startProcess: building log message"); 2990 StringBuilder buf = mStringBuilder; 2991 buf.setLength(0); 2992 buf.append("Start proc "); 2993 buf.append(app.processName); 2994 if (!isActivityProcess) { 2995 buf.append(" ["); 2996 buf.append(entryPoint); 2997 buf.append("]"); 2998 } 2999 buf.append(" for "); 3000 buf.append(hostingType); 3001 if (hostingNameStr != null) { 3002 buf.append(" "); 3003 buf.append(hostingNameStr); 3004 } 3005 buf.append(": pid="); 3006 buf.append(startResult.pid); 3007 buf.append(" uid="); 3008 buf.append(uid); 3009 buf.append(" gids={"); 3010 if (gids != null) { 3011 for (int gi=0; gi<gids.length; gi++) { 3012 if (gi != 0) buf.append(", "); 3013 buf.append(gids[gi]); 3014 3015 } 3016 } 3017 buf.append("}"); 3018 if (requiredAbi != null) { 3019 buf.append(" abi="); 3020 buf.append(requiredAbi); 3021 } 3022 Slog.i(TAG, buf.toString()); 3023 app.setPid(startResult.pid); 3024 app.usingWrapper = startResult.usingWrapper; 3025 app.removed = false; 3026 app.killed = false; 3027 app.killedByAm = false; 3028 checkTime(startTime, "startProcess: starting to update pids map"); 3029 synchronized (mPidsSelfLocked) { 3030 this.mPidsSelfLocked.put(startResult.pid, app); 3031 if (isActivityProcess) { 3032 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3033 msg.obj = app; 3034 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3035 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3036 } 3037 } 3038 checkTime(startTime, "startProcess: done updating pids map"); 3039 } catch (RuntimeException e) { 3040 // XXX do better error recovery. 3041 app.setPid(0); 3042 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3043 if (app.isolated) { 3044 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3045 } 3046 Slog.e(TAG, "Failure starting process " + app.processName, e); 3047 } 3048 } 3049 3050 void updateUsageStats(ActivityRecord component, boolean resumed) { 3051 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3052 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3053 if (resumed) { 3054 if (mUsageStatsService != null) { 3055 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3056 UsageEvents.Event.MOVE_TO_FOREGROUND); 3057 } 3058 synchronized (stats) { 3059 stats.noteActivityResumedLocked(component.app.uid); 3060 } 3061 } else { 3062 if (mUsageStatsService != null) { 3063 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3064 UsageEvents.Event.MOVE_TO_BACKGROUND); 3065 } 3066 synchronized (stats) { 3067 stats.noteActivityPausedLocked(component.app.uid); 3068 } 3069 } 3070 } 3071 3072 Intent getHomeIntent() { 3073 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3074 intent.setComponent(mTopComponent); 3075 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3076 intent.addCategory(Intent.CATEGORY_HOME); 3077 } 3078 return intent; 3079 } 3080 3081 boolean startHomeActivityLocked(int userId) { 3082 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3083 && mTopAction == null) { 3084 // We are running in factory test mode, but unable to find 3085 // the factory test app, so just sit around displaying the 3086 // error message and don't try to start anything. 3087 return false; 3088 } 3089 Intent intent = getHomeIntent(); 3090 ActivityInfo aInfo = 3091 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3092 if (aInfo != null) { 3093 intent.setComponent(new ComponentName( 3094 aInfo.applicationInfo.packageName, aInfo.name)); 3095 // Don't do this if the home app is currently being 3096 // instrumented. 3097 aInfo = new ActivityInfo(aInfo); 3098 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3099 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3100 aInfo.applicationInfo.uid, true); 3101 if (app == null || app.instrumentationClass == null) { 3102 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3103 mStackSupervisor.startHomeActivity(intent, aInfo); 3104 } 3105 } 3106 3107 return true; 3108 } 3109 3110 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3111 ActivityInfo ai = null; 3112 ComponentName comp = intent.getComponent(); 3113 try { 3114 if (comp != null) { 3115 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3116 } else { 3117 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3118 intent, 3119 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3120 flags, userId); 3121 3122 if (info != null) { 3123 ai = info.activityInfo; 3124 } 3125 } 3126 } catch (RemoteException e) { 3127 // ignore 3128 } 3129 3130 return ai; 3131 } 3132 3133 /** 3134 * Starts the "new version setup screen" if appropriate. 3135 */ 3136 void startSetupActivityLocked() { 3137 // Only do this once per boot. 3138 if (mCheckedForSetup) { 3139 return; 3140 } 3141 3142 // We will show this screen if the current one is a different 3143 // version than the last one shown, and we are not running in 3144 // low-level factory test mode. 3145 final ContentResolver resolver = mContext.getContentResolver(); 3146 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3147 Settings.Global.getInt(resolver, 3148 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3149 mCheckedForSetup = true; 3150 3151 // See if we should be showing the platform update setup UI. 3152 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3153 List<ResolveInfo> ris = mContext.getPackageManager() 3154 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3155 3156 // We don't allow third party apps to replace this. 3157 ResolveInfo ri = null; 3158 for (int i=0; ris != null && i<ris.size(); i++) { 3159 if ((ris.get(i).activityInfo.applicationInfo.flags 3160 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3161 ri = ris.get(i); 3162 break; 3163 } 3164 } 3165 3166 if (ri != null) { 3167 String vers = ri.activityInfo.metaData != null 3168 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3169 : null; 3170 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3171 vers = ri.activityInfo.applicationInfo.metaData.getString( 3172 Intent.METADATA_SETUP_VERSION); 3173 } 3174 String lastVers = Settings.Secure.getString( 3175 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3176 if (vers != null && !vers.equals(lastVers)) { 3177 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3178 intent.setComponent(new ComponentName( 3179 ri.activityInfo.packageName, ri.activityInfo.name)); 3180 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3181 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3182 null); 3183 } 3184 } 3185 } 3186 } 3187 3188 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3189 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3190 } 3191 3192 void enforceNotIsolatedCaller(String caller) { 3193 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3194 throw new SecurityException("Isolated process not allowed to call " + caller); 3195 } 3196 } 3197 3198 void enforceShellRestriction(String restriction, int userHandle) { 3199 if (Binder.getCallingUid() == Process.SHELL_UID) { 3200 if (userHandle < 0 3201 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3202 throw new SecurityException("Shell does not have permission to access user " 3203 + userHandle); 3204 } 3205 } 3206 } 3207 3208 @Override 3209 public int getFrontActivityScreenCompatMode() { 3210 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3211 synchronized (this) { 3212 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3213 } 3214 } 3215 3216 @Override 3217 public void setFrontActivityScreenCompatMode(int mode) { 3218 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3219 "setFrontActivityScreenCompatMode"); 3220 synchronized (this) { 3221 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3222 } 3223 } 3224 3225 @Override 3226 public int getPackageScreenCompatMode(String packageName) { 3227 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3228 synchronized (this) { 3229 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3230 } 3231 } 3232 3233 @Override 3234 public void setPackageScreenCompatMode(String packageName, int mode) { 3235 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3236 "setPackageScreenCompatMode"); 3237 synchronized (this) { 3238 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3239 } 3240 } 3241 3242 @Override 3243 public boolean getPackageAskScreenCompat(String packageName) { 3244 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3245 synchronized (this) { 3246 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3247 } 3248 } 3249 3250 @Override 3251 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3252 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3253 "setPackageAskScreenCompat"); 3254 synchronized (this) { 3255 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3256 } 3257 } 3258 3259 private void dispatchProcessesChanged() { 3260 int N; 3261 synchronized (this) { 3262 N = mPendingProcessChanges.size(); 3263 if (mActiveProcessChanges.length < N) { 3264 mActiveProcessChanges = new ProcessChangeItem[N]; 3265 } 3266 mPendingProcessChanges.toArray(mActiveProcessChanges); 3267 mAvailProcessChanges.addAll(mPendingProcessChanges); 3268 mPendingProcessChanges.clear(); 3269 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3270 } 3271 3272 int i = mProcessObservers.beginBroadcast(); 3273 while (i > 0) { 3274 i--; 3275 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3276 if (observer != null) { 3277 try { 3278 for (int j=0; j<N; j++) { 3279 ProcessChangeItem item = mActiveProcessChanges[j]; 3280 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3281 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3282 + item.pid + " uid=" + item.uid + ": " 3283 + item.foregroundActivities); 3284 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3285 item.foregroundActivities); 3286 } 3287 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3289 + item.pid + " uid=" + item.uid + ": " + item.processState); 3290 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3291 } 3292 } 3293 } catch (RemoteException e) { 3294 } 3295 } 3296 } 3297 mProcessObservers.finishBroadcast(); 3298 } 3299 3300 private void dispatchProcessDied(int pid, int uid) { 3301 int i = mProcessObservers.beginBroadcast(); 3302 while (i > 0) { 3303 i--; 3304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3305 if (observer != null) { 3306 try { 3307 observer.onProcessDied(pid, uid); 3308 } catch (RemoteException e) { 3309 } 3310 } 3311 } 3312 mProcessObservers.finishBroadcast(); 3313 } 3314 3315 @Override 3316 public final int startActivity(IApplicationThread caller, String callingPackage, 3317 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3318 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3319 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3320 resultWho, requestCode, startFlags, profilerInfo, options, 3321 UserHandle.getCallingUserId()); 3322 } 3323 3324 @Override 3325 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3326 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3327 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3328 enforceNotIsolatedCaller("startActivity"); 3329 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3330 false, ALLOW_FULL_ONLY, "startActivity", null); 3331 // TODO: Switch to user app stacks here. 3332 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3333 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3334 profilerInfo, null, null, options, userId, null, null); 3335 } 3336 3337 @Override 3338 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3339 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3340 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3341 3342 // This is very dangerous -- it allows you to perform a start activity (including 3343 // permission grants) as any app that may launch one of your own activities. So 3344 // we will only allow this to be done from activities that are part of the core framework, 3345 // and then only when they are running as the system. 3346 final ActivityRecord sourceRecord; 3347 final int targetUid; 3348 final String targetPackage; 3349 synchronized (this) { 3350 if (resultTo == null) { 3351 throw new SecurityException("Must be called from an activity"); 3352 } 3353 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3354 if (sourceRecord == null) { 3355 throw new SecurityException("Called with bad activity token: " + resultTo); 3356 } 3357 if (!sourceRecord.info.packageName.equals("android")) { 3358 throw new SecurityException( 3359 "Must be called from an activity that is declared in the android package"); 3360 } 3361 if (sourceRecord.app == null) { 3362 throw new SecurityException("Called without a process attached to activity"); 3363 } 3364 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3365 // This is still okay, as long as this activity is running under the 3366 // uid of the original calling activity. 3367 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3368 throw new SecurityException( 3369 "Calling activity in uid " + sourceRecord.app.uid 3370 + " must be system uid or original calling uid " 3371 + sourceRecord.launchedFromUid); 3372 } 3373 } 3374 targetUid = sourceRecord.launchedFromUid; 3375 targetPackage = sourceRecord.launchedFromPackage; 3376 } 3377 3378 if (userId == UserHandle.USER_NULL) { 3379 userId = UserHandle.getUserId(sourceRecord.app.uid); 3380 } 3381 3382 // TODO: Switch to user app stacks here. 3383 try { 3384 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3385 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3386 null, null, options, userId, null, null); 3387 return ret; 3388 } catch (SecurityException e) { 3389 // XXX need to figure out how to propagate to original app. 3390 // A SecurityException here is generally actually a fault of the original 3391 // calling activity (such as a fairly granting permissions), so propagate it 3392 // back to them. 3393 /* 3394 StringBuilder msg = new StringBuilder(); 3395 msg.append("While launching"); 3396 msg.append(intent.toString()); 3397 msg.append(": "); 3398 msg.append(e.getMessage()); 3399 */ 3400 throw e; 3401 } 3402 } 3403 3404 @Override 3405 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3406 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3407 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3408 enforceNotIsolatedCaller("startActivityAndWait"); 3409 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3410 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3411 WaitResult res = new WaitResult(); 3412 // TODO: Switch to user app stacks here. 3413 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3414 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3415 options, userId, null, null); 3416 return res; 3417 } 3418 3419 @Override 3420 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3421 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3422 int startFlags, Configuration config, Bundle options, int userId) { 3423 enforceNotIsolatedCaller("startActivityWithConfig"); 3424 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3425 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3426 // TODO: Switch to user app stacks here. 3427 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3428 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3429 null, null, config, options, userId, null, null); 3430 return ret; 3431 } 3432 3433 @Override 3434 public int startActivityIntentSender(IApplicationThread caller, 3435 IntentSender intent, Intent fillInIntent, String resolvedType, 3436 IBinder resultTo, String resultWho, int requestCode, 3437 int flagsMask, int flagsValues, Bundle options) { 3438 enforceNotIsolatedCaller("startActivityIntentSender"); 3439 // Refuse possible leaked file descriptors 3440 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3441 throw new IllegalArgumentException("File descriptors passed in Intent"); 3442 } 3443 3444 IIntentSender sender = intent.getTarget(); 3445 if (!(sender instanceof PendingIntentRecord)) { 3446 throw new IllegalArgumentException("Bad PendingIntent object"); 3447 } 3448 3449 PendingIntentRecord pir = (PendingIntentRecord)sender; 3450 3451 synchronized (this) { 3452 // If this is coming from the currently resumed activity, it is 3453 // effectively saying that app switches are allowed at this point. 3454 final ActivityStack stack = getFocusedStack(); 3455 if (stack.mResumedActivity != null && 3456 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3457 mAppSwitchesAllowedTime = 0; 3458 } 3459 } 3460 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3461 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3462 return ret; 3463 } 3464 3465 @Override 3466 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3467 Intent intent, String resolvedType, IVoiceInteractionSession session, 3468 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3469 Bundle options, int userId) { 3470 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3471 != PackageManager.PERMISSION_GRANTED) { 3472 String msg = "Permission Denial: startVoiceActivity() from pid=" 3473 + Binder.getCallingPid() 3474 + ", uid=" + Binder.getCallingUid() 3475 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3476 Slog.w(TAG, msg); 3477 throw new SecurityException(msg); 3478 } 3479 if (session == null || interactor == null) { 3480 throw new NullPointerException("null session or interactor"); 3481 } 3482 userId = handleIncomingUser(callingPid, callingUid, userId, 3483 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3484 // TODO: Switch to user app stacks here. 3485 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3486 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3487 null, options, userId, null, null); 3488 } 3489 3490 @Override 3491 public boolean startNextMatchingActivity(IBinder callingActivity, 3492 Intent intent, Bundle options) { 3493 // Refuse possible leaked file descriptors 3494 if (intent != null && intent.hasFileDescriptors() == true) { 3495 throw new IllegalArgumentException("File descriptors passed in Intent"); 3496 } 3497 3498 synchronized (this) { 3499 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3500 if (r == null) { 3501 ActivityOptions.abort(options); 3502 return false; 3503 } 3504 if (r.app == null || r.app.thread == null) { 3505 // The caller is not running... d'oh! 3506 ActivityOptions.abort(options); 3507 return false; 3508 } 3509 intent = new Intent(intent); 3510 // The caller is not allowed to change the data. 3511 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3512 // And we are resetting to find the next component... 3513 intent.setComponent(null); 3514 3515 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3516 3517 ActivityInfo aInfo = null; 3518 try { 3519 List<ResolveInfo> resolves = 3520 AppGlobals.getPackageManager().queryIntentActivities( 3521 intent, r.resolvedType, 3522 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3523 UserHandle.getCallingUserId()); 3524 3525 // Look for the original activity in the list... 3526 final int N = resolves != null ? resolves.size() : 0; 3527 for (int i=0; i<N; i++) { 3528 ResolveInfo rInfo = resolves.get(i); 3529 if (rInfo.activityInfo.packageName.equals(r.packageName) 3530 && rInfo.activityInfo.name.equals(r.info.name)) { 3531 // We found the current one... the next matching is 3532 // after it. 3533 i++; 3534 if (i<N) { 3535 aInfo = resolves.get(i).activityInfo; 3536 } 3537 if (debug) { 3538 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3539 + "/" + r.info.name); 3540 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3541 + "/" + aInfo.name); 3542 } 3543 break; 3544 } 3545 } 3546 } catch (RemoteException e) { 3547 } 3548 3549 if (aInfo == null) { 3550 // Nobody who is next! 3551 ActivityOptions.abort(options); 3552 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3553 return false; 3554 } 3555 3556 intent.setComponent(new ComponentName( 3557 aInfo.applicationInfo.packageName, aInfo.name)); 3558 intent.setFlags(intent.getFlags()&~( 3559 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3560 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3561 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3562 Intent.FLAG_ACTIVITY_NEW_TASK)); 3563 3564 // Okay now we need to start the new activity, replacing the 3565 // currently running activity. This is a little tricky because 3566 // we want to start the new one as if the current one is finished, 3567 // but not finish the current one first so that there is no flicker. 3568 // And thus... 3569 final boolean wasFinishing = r.finishing; 3570 r.finishing = true; 3571 3572 // Propagate reply information over to the new activity. 3573 final ActivityRecord resultTo = r.resultTo; 3574 final String resultWho = r.resultWho; 3575 final int requestCode = r.requestCode; 3576 r.resultTo = null; 3577 if (resultTo != null) { 3578 resultTo.removeResultsLocked(r, resultWho, requestCode); 3579 } 3580 3581 final long origId = Binder.clearCallingIdentity(); 3582 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3583 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3584 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3585 -1, r.launchedFromUid, 0, options, false, null, null, null); 3586 Binder.restoreCallingIdentity(origId); 3587 3588 r.finishing = wasFinishing; 3589 if (res != ActivityManager.START_SUCCESS) { 3590 return false; 3591 } 3592 return true; 3593 } 3594 } 3595 3596 @Override 3597 public final int startActivityFromRecents(int taskId, Bundle options) { 3598 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3599 String msg = "Permission Denial: startActivityFromRecents called without " + 3600 START_TASKS_FROM_RECENTS; 3601 Slog.w(TAG, msg); 3602 throw new SecurityException(msg); 3603 } 3604 return startActivityFromRecentsInner(taskId, options); 3605 } 3606 3607 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3608 final TaskRecord task; 3609 final int callingUid; 3610 final String callingPackage; 3611 final Intent intent; 3612 final int userId; 3613 synchronized (this) { 3614 task = recentTaskForIdLocked(taskId); 3615 if (task == null) { 3616 throw new IllegalArgumentException("Task " + taskId + " not found."); 3617 } 3618 callingUid = task.mCallingUid; 3619 callingPackage = task.mCallingPackage; 3620 intent = task.intent; 3621 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3622 userId = task.userId; 3623 } 3624 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3625 options, userId, null, task); 3626 } 3627 3628 final int startActivityInPackage(int uid, String callingPackage, 3629 Intent intent, String resolvedType, IBinder resultTo, 3630 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3631 IActivityContainer container, TaskRecord inTask) { 3632 3633 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3634 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3635 3636 // TODO: Switch to user app stacks here. 3637 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3638 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3639 null, null, null, options, userId, container, inTask); 3640 return ret; 3641 } 3642 3643 @Override 3644 public final int startActivities(IApplicationThread caller, String callingPackage, 3645 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3646 int userId) { 3647 enforceNotIsolatedCaller("startActivities"); 3648 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3649 false, ALLOW_FULL_ONLY, "startActivity", null); 3650 // TODO: Switch to user app stacks here. 3651 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3652 resolvedTypes, resultTo, options, userId); 3653 return ret; 3654 } 3655 3656 final int startActivitiesInPackage(int uid, String callingPackage, 3657 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3658 Bundle options, int userId) { 3659 3660 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3661 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3662 // TODO: Switch to user app stacks here. 3663 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3664 resultTo, options, userId); 3665 return ret; 3666 } 3667 3668 //explicitly remove thd old information in mRecentTasks when removing existing user. 3669 private void removeRecentTasksForUserLocked(int userId) { 3670 if(userId <= 0) { 3671 Slog.i(TAG, "Can't remove recent task on user " + userId); 3672 return; 3673 } 3674 3675 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3676 TaskRecord tr = mRecentTasks.get(i); 3677 if (tr.userId == userId) { 3678 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3679 + " when finishing user" + userId); 3680 mRecentTasks.remove(i); 3681 tr.removedFromRecents(); 3682 } 3683 } 3684 3685 // Remove tasks from persistent storage. 3686 notifyTaskPersisterLocked(null, true); 3687 } 3688 3689 // Sort by taskId 3690 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3691 @Override 3692 public int compare(TaskRecord lhs, TaskRecord rhs) { 3693 return rhs.taskId - lhs.taskId; 3694 } 3695 }; 3696 3697 // Extract the affiliates of the chain containing mRecentTasks[start]. 3698 private int processNextAffiliateChainLocked(int start) { 3699 final TaskRecord startTask = mRecentTasks.get(start); 3700 final int affiliateId = startTask.mAffiliatedTaskId; 3701 3702 // Quick identification of isolated tasks. I.e. those not launched behind. 3703 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3704 startTask.mNextAffiliate == null) { 3705 // There is still a slim chance that there are other tasks that point to this task 3706 // and that the chain is so messed up that this task no longer points to them but 3707 // the gain of this optimization outweighs the risk. 3708 startTask.inRecents = true; 3709 return start + 1; 3710 } 3711 3712 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3713 mTmpRecents.clear(); 3714 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3715 final TaskRecord task = mRecentTasks.get(i); 3716 if (task.mAffiliatedTaskId == affiliateId) { 3717 mRecentTasks.remove(i); 3718 mTmpRecents.add(task); 3719 } 3720 } 3721 3722 // Sort them all by taskId. That is the order they were create in and that order will 3723 // always be correct. 3724 Collections.sort(mTmpRecents, mTaskRecordComparator); 3725 3726 // Go through and fix up the linked list. 3727 // The first one is the end of the chain and has no next. 3728 final TaskRecord first = mTmpRecents.get(0); 3729 first.inRecents = true; 3730 if (first.mNextAffiliate != null) { 3731 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3732 first.setNextAffiliate(null); 3733 notifyTaskPersisterLocked(first, false); 3734 } 3735 // Everything in the middle is doubly linked from next to prev. 3736 final int tmpSize = mTmpRecents.size(); 3737 for (int i = 0; i < tmpSize - 1; ++i) { 3738 final TaskRecord next = mTmpRecents.get(i); 3739 final TaskRecord prev = mTmpRecents.get(i + 1); 3740 if (next.mPrevAffiliate != prev) { 3741 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3742 " setting prev=" + prev); 3743 next.setPrevAffiliate(prev); 3744 notifyTaskPersisterLocked(next, false); 3745 } 3746 if (prev.mNextAffiliate != next) { 3747 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3748 " setting next=" + next); 3749 prev.setNextAffiliate(next); 3750 notifyTaskPersisterLocked(prev, false); 3751 } 3752 prev.inRecents = true; 3753 } 3754 // The last one is the beginning of the list and has no prev. 3755 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3756 if (last.mPrevAffiliate != null) { 3757 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3758 last.setPrevAffiliate(null); 3759 notifyTaskPersisterLocked(last, false); 3760 } 3761 3762 // Insert the group back into mRecentTasks at start. 3763 mRecentTasks.addAll(start, mTmpRecents); 3764 3765 // Let the caller know where we left off. 3766 return start + tmpSize; 3767 } 3768 3769 /** 3770 * Update the recent tasks lists: make sure tasks should still be here (their 3771 * applications / activities still exist), update their availability, fixup ordering 3772 * of affiliations. 3773 */ 3774 void cleanupRecentTasksLocked(int userId) { 3775 if (mRecentTasks == null) { 3776 // Happens when called from the packagemanager broadcast before boot. 3777 return; 3778 } 3779 3780 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3781 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3782 final IPackageManager pm = AppGlobals.getPackageManager(); 3783 final ActivityInfo dummyAct = new ActivityInfo(); 3784 final ApplicationInfo dummyApp = new ApplicationInfo(); 3785 3786 int N = mRecentTasks.size(); 3787 3788 int[] users = userId == UserHandle.USER_ALL 3789 ? getUsersLocked() : new int[] { userId }; 3790 for (int user : users) { 3791 for (int i = 0; i < N; i++) { 3792 TaskRecord task = mRecentTasks.get(i); 3793 if (task.userId != user) { 3794 // Only look at tasks for the user ID of interest. 3795 continue; 3796 } 3797 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3798 // This situation is broken, and we should just get rid of it now. 3799 mRecentTasks.remove(i); 3800 task.removedFromRecents(); 3801 i--; 3802 N--; 3803 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3804 continue; 3805 } 3806 // Check whether this activity is currently available. 3807 if (task.realActivity != null) { 3808 ActivityInfo ai = availActCache.get(task.realActivity); 3809 if (ai == null) { 3810 try { 3811 ai = pm.getActivityInfo(task.realActivity, 3812 PackageManager.GET_UNINSTALLED_PACKAGES 3813 | PackageManager.GET_DISABLED_COMPONENTS, user); 3814 } catch (RemoteException e) { 3815 // Will never happen. 3816 continue; 3817 } 3818 if (ai == null) { 3819 ai = dummyAct; 3820 } 3821 availActCache.put(task.realActivity, ai); 3822 } 3823 if (ai == dummyAct) { 3824 // This could be either because the activity no longer exists, or the 3825 // app is temporarily gone. For the former we want to remove the recents 3826 // entry; for the latter we want to mark it as unavailable. 3827 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3828 if (app == null) { 3829 try { 3830 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3831 PackageManager.GET_UNINSTALLED_PACKAGES 3832 | PackageManager.GET_DISABLED_COMPONENTS, user); 3833 } catch (RemoteException e) { 3834 // Will never happen. 3835 continue; 3836 } 3837 if (app == null) { 3838 app = dummyApp; 3839 } 3840 availAppCache.put(task.realActivity.getPackageName(), app); 3841 } 3842 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3843 // Doesn't exist any more! Good-bye. 3844 mRecentTasks.remove(i); 3845 task.removedFromRecents(); 3846 i--; 3847 N--; 3848 Slog.w(TAG, "Removing no longer valid recent: " + task); 3849 continue; 3850 } else { 3851 // Otherwise just not available for now. 3852 if (task.isAvailable) { 3853 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3854 + task); 3855 } 3856 task.isAvailable = false; 3857 } 3858 } else { 3859 if (!ai.enabled || !ai.applicationInfo.enabled 3860 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3861 if (task.isAvailable) { 3862 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3863 + task + " (enabled=" + ai.enabled + "/" 3864 + ai.applicationInfo.enabled + " flags=" 3865 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3866 } 3867 task.isAvailable = false; 3868 } else { 3869 if (!task.isAvailable) { 3870 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3871 + task); 3872 } 3873 task.isAvailable = true; 3874 } 3875 } 3876 } 3877 } 3878 } 3879 3880 // Verify the affiliate chain for each task. 3881 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3882 } 3883 3884 mTmpRecents.clear(); 3885 // mRecentTasks is now in sorted, affiliated order. 3886 } 3887 3888 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3889 int N = mRecentTasks.size(); 3890 TaskRecord top = task; 3891 int topIndex = taskIndex; 3892 while (top.mNextAffiliate != null && topIndex > 0) { 3893 top = top.mNextAffiliate; 3894 topIndex--; 3895 } 3896 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3897 + topIndex + " from intial " + taskIndex); 3898 // Find the end of the chain, doing a sanity check along the way. 3899 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3900 int endIndex = topIndex; 3901 TaskRecord prev = top; 3902 while (endIndex < N) { 3903 TaskRecord cur = mRecentTasks.get(endIndex); 3904 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3905 + endIndex + " " + cur); 3906 if (cur == top) { 3907 // Verify start of the chain. 3908 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3909 Slog.wtf(TAG, "Bad chain @" + endIndex 3910 + ": first task has next affiliate: " + prev); 3911 sane = false; 3912 break; 3913 } 3914 } else { 3915 // Verify middle of the chain's next points back to the one before. 3916 if (cur.mNextAffiliate != prev 3917 || cur.mNextAffiliateTaskId != prev.taskId) { 3918 Slog.wtf(TAG, "Bad chain @" + endIndex 3919 + ": middle task " + cur + " @" + endIndex 3920 + " has bad next affiliate " 3921 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3922 + ", expected " + prev); 3923 sane = false; 3924 break; 3925 } 3926 } 3927 if (cur.mPrevAffiliateTaskId == -1) { 3928 // Chain ends here. 3929 if (cur.mPrevAffiliate != null) { 3930 Slog.wtf(TAG, "Bad chain @" + endIndex 3931 + ": last task " + cur + " has previous affiliate " 3932 + cur.mPrevAffiliate); 3933 sane = false; 3934 } 3935 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3936 break; 3937 } else { 3938 // Verify middle of the chain's prev points to a valid item. 3939 if (cur.mPrevAffiliate == null) { 3940 Slog.wtf(TAG, "Bad chain @" + endIndex 3941 + ": task " + cur + " has previous affiliate " 3942 + cur.mPrevAffiliate + " but should be id " 3943 + cur.mPrevAffiliate); 3944 sane = false; 3945 break; 3946 } 3947 } 3948 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3949 Slog.wtf(TAG, "Bad chain @" + endIndex 3950 + ": task " + cur + " has affiliated id " 3951 + cur.mAffiliatedTaskId + " but should be " 3952 + task.mAffiliatedTaskId); 3953 sane = false; 3954 break; 3955 } 3956 prev = cur; 3957 endIndex++; 3958 if (endIndex >= N) { 3959 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3960 + ": last task " + prev); 3961 sane = false; 3962 break; 3963 } 3964 } 3965 if (sane) { 3966 if (endIndex < taskIndex) { 3967 Slog.wtf(TAG, "Bad chain @" + endIndex 3968 + ": did not extend to task " + task + " @" + taskIndex); 3969 sane = false; 3970 } 3971 } 3972 if (sane) { 3973 // All looks good, we can just move all of the affiliated tasks 3974 // to the top. 3975 for (int i=topIndex; i<=endIndex; i++) { 3976 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3977 + " from " + i + " to " + (i-topIndex)); 3978 TaskRecord cur = mRecentTasks.remove(i); 3979 mRecentTasks.add(i-topIndex, cur); 3980 } 3981 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3982 + " to " + endIndex); 3983 return true; 3984 } 3985 3986 // Whoops, couldn't do it. 3987 return false; 3988 } 3989 3990 final void addRecentTaskLocked(TaskRecord task) { 3991 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3992 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3993 3994 int N = mRecentTasks.size(); 3995 // Quick case: check if the top-most recent task is the same. 3996 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3997 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 3998 return; 3999 } 4000 // Another quick case: check if this is part of a set of affiliated 4001 // tasks that are at the top. 4002 if (isAffiliated && N > 0 && task.inRecents 4003 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4004 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4005 + " at top when adding " + task); 4006 return; 4007 } 4008 // Another quick case: never add voice sessions. 4009 if (task.voiceSession != null) { 4010 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4011 return; 4012 } 4013 4014 boolean needAffiliationFix = false; 4015 4016 // Slightly less quick case: the task is already in recents, so all we need 4017 // to do is move it. 4018 if (task.inRecents) { 4019 int taskIndex = mRecentTasks.indexOf(task); 4020 if (taskIndex >= 0) { 4021 if (!isAffiliated) { 4022 // Simple case: this is not an affiliated task, so we just move it to the front. 4023 mRecentTasks.remove(taskIndex); 4024 mRecentTasks.add(0, task); 4025 notifyTaskPersisterLocked(task, false); 4026 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4027 + " from " + taskIndex); 4028 return; 4029 } else { 4030 // More complicated: need to keep all affiliated tasks together. 4031 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4032 // All went well. 4033 return; 4034 } 4035 4036 // Uh oh... something bad in the affiliation chain, try to rebuild 4037 // everything and then go through our general path of adding a new task. 4038 needAffiliationFix = true; 4039 } 4040 } else { 4041 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4042 needAffiliationFix = true; 4043 } 4044 } 4045 4046 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4047 trimRecentsForTaskLocked(task, true); 4048 4049 N = mRecentTasks.size(); 4050 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4051 final TaskRecord tr = mRecentTasks.remove(N - 1); 4052 tr.removedFromRecents(); 4053 N--; 4054 } 4055 task.inRecents = true; 4056 if (!isAffiliated || needAffiliationFix) { 4057 // If this is a simple non-affiliated task, or we had some failure trying to 4058 // handle it as part of an affilated task, then just place it at the top. 4059 mRecentTasks.add(0, task); 4060 } else if (isAffiliated) { 4061 // If this is a new affiliated task, then move all of the affiliated tasks 4062 // to the front and insert this new one. 4063 TaskRecord other = task.mNextAffiliate; 4064 if (other == null) { 4065 other = task.mPrevAffiliate; 4066 } 4067 if (other != null) { 4068 int otherIndex = mRecentTasks.indexOf(other); 4069 if (otherIndex >= 0) { 4070 // Insert new task at appropriate location. 4071 int taskIndex; 4072 if (other == task.mNextAffiliate) { 4073 // We found the index of our next affiliation, which is who is 4074 // before us in the list, so add after that point. 4075 taskIndex = otherIndex+1; 4076 } else { 4077 // We found the index of our previous affiliation, which is who is 4078 // after us in the list, so add at their position. 4079 taskIndex = otherIndex; 4080 } 4081 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4082 + taskIndex + ": " + task); 4083 mRecentTasks.add(taskIndex, task); 4084 4085 // Now move everything to the front. 4086 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4087 // All went well. 4088 return; 4089 } 4090 4091 // Uh oh... something bad in the affiliation chain, try to rebuild 4092 // everything and then go through our general path of adding a new task. 4093 needAffiliationFix = true; 4094 } else { 4095 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4096 + other); 4097 needAffiliationFix = true; 4098 } 4099 } else { 4100 if (DEBUG_RECENTS) Slog.d(TAG, 4101 "addRecent: adding affiliated task without next/prev:" + task); 4102 needAffiliationFix = true; 4103 } 4104 } 4105 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4106 4107 if (needAffiliationFix) { 4108 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4109 cleanupRecentTasksLocked(task.userId); 4110 } 4111 } 4112 4113 /** 4114 * If needed, remove oldest existing entries in recents that are for the same kind 4115 * of task as the given one. 4116 */ 4117 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4118 int N = mRecentTasks.size(); 4119 final Intent intent = task.intent; 4120 final boolean document = intent != null && intent.isDocument(); 4121 4122 int maxRecents = task.maxRecents - 1; 4123 for (int i=0; i<N; i++) { 4124 final TaskRecord tr = mRecentTasks.get(i); 4125 if (task != tr) { 4126 if (task.userId != tr.userId) { 4127 continue; 4128 } 4129 if (i > MAX_RECENT_BITMAPS) { 4130 tr.freeLastThumbnail(); 4131 } 4132 final Intent trIntent = tr.intent; 4133 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4134 (intent == null || !intent.filterEquals(trIntent))) { 4135 continue; 4136 } 4137 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4138 if (document && trIsDocument) { 4139 // These are the same document activity (not necessarily the same doc). 4140 if (maxRecents > 0) { 4141 --maxRecents; 4142 continue; 4143 } 4144 // Hit the maximum number of documents for this task. Fall through 4145 // and remove this document from recents. 4146 } else if (document || trIsDocument) { 4147 // Only one of these is a document. Not the droid we're looking for. 4148 continue; 4149 } 4150 } 4151 4152 if (!doTrim) { 4153 // If the caller is not actually asking for a trim, just tell them we reached 4154 // a point where the trim would happen. 4155 return i; 4156 } 4157 4158 // Either task and tr are the same or, their affinities match or their intents match 4159 // and neither of them is a document, or they are documents using the same activity 4160 // and their maxRecents has been reached. 4161 tr.disposeThumbnail(); 4162 mRecentTasks.remove(i); 4163 if (task != tr) { 4164 tr.removedFromRecents(); 4165 } 4166 i--; 4167 N--; 4168 if (task.intent == null) { 4169 // If the new recent task we are adding is not fully 4170 // specified, then replace it with the existing recent task. 4171 task = tr; 4172 } 4173 notifyTaskPersisterLocked(tr, false); 4174 } 4175 4176 return -1; 4177 } 4178 4179 @Override 4180 public void reportActivityFullyDrawn(IBinder token) { 4181 synchronized (this) { 4182 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4183 if (r == null) { 4184 return; 4185 } 4186 r.reportFullyDrawnLocked(); 4187 } 4188 } 4189 4190 @Override 4191 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4192 synchronized (this) { 4193 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4194 if (r == null) { 4195 return; 4196 } 4197 final long origId = Binder.clearCallingIdentity(); 4198 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4199 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4200 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4201 if (config != null) { 4202 r.frozenBeforeDestroy = true; 4203 if (!updateConfigurationLocked(config, r, false, false)) { 4204 mStackSupervisor.resumeTopActivitiesLocked(); 4205 } 4206 } 4207 Binder.restoreCallingIdentity(origId); 4208 } 4209 } 4210 4211 @Override 4212 public int getRequestedOrientation(IBinder token) { 4213 synchronized (this) { 4214 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4215 if (r == null) { 4216 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4217 } 4218 return mWindowManager.getAppOrientation(r.appToken); 4219 } 4220 } 4221 4222 /** 4223 * This is the internal entry point for handling Activity.finish(). 4224 * 4225 * @param token The Binder token referencing the Activity we want to finish. 4226 * @param resultCode Result code, if any, from this Activity. 4227 * @param resultData Result data (Intent), if any, from this Activity. 4228 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4229 * the root Activity in the task. 4230 * 4231 * @return Returns true if the activity successfully finished, or false if it is still running. 4232 */ 4233 @Override 4234 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4235 boolean finishTask) { 4236 // Refuse possible leaked file descriptors 4237 if (resultData != null && resultData.hasFileDescriptors() == true) { 4238 throw new IllegalArgumentException("File descriptors passed in Intent"); 4239 } 4240 4241 synchronized(this) { 4242 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4243 if (r == null) { 4244 return true; 4245 } 4246 // Keep track of the root activity of the task before we finish it 4247 TaskRecord tr = r.task; 4248 ActivityRecord rootR = tr.getRootActivity(); 4249 if (rootR == null) { 4250 Slog.w(TAG, "Finishing task with all activities already finished"); 4251 } 4252 // Do not allow task to finish in Lock Task mode. 4253 if (tr == mStackSupervisor.mLockTaskModeTask) { 4254 if (rootR == r) { 4255 Slog.i(TAG, "Not finishing task in lock task mode"); 4256 mStackSupervisor.showLockTaskToast(); 4257 return false; 4258 } 4259 } 4260 if (mController != null) { 4261 // Find the first activity that is not finishing. 4262 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4263 if (next != null) { 4264 // ask watcher if this is allowed 4265 boolean resumeOK = true; 4266 try { 4267 resumeOK = mController.activityResuming(next.packageName); 4268 } catch (RemoteException e) { 4269 mController = null; 4270 Watchdog.getInstance().setActivityController(null); 4271 } 4272 4273 if (!resumeOK) { 4274 Slog.i(TAG, "Not finishing activity because controller resumed"); 4275 return false; 4276 } 4277 } 4278 } 4279 final long origId = Binder.clearCallingIdentity(); 4280 try { 4281 boolean res; 4282 if (finishTask && r == rootR) { 4283 // If requested, remove the task that is associated to this activity only if it 4284 // was the root activity in the task. The result code and data is ignored 4285 // because we don't support returning them across task boundaries. 4286 res = removeTaskByIdLocked(tr.taskId, false); 4287 if (!res) { 4288 Slog.i(TAG, "Removing task failed to finish activity"); 4289 } 4290 } else { 4291 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4292 resultData, "app-request", true); 4293 if (!res) { 4294 Slog.i(TAG, "Failed to finish by app-request"); 4295 } 4296 } 4297 return res; 4298 } finally { 4299 Binder.restoreCallingIdentity(origId); 4300 } 4301 } 4302 } 4303 4304 @Override 4305 public final void finishHeavyWeightApp() { 4306 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4307 != PackageManager.PERMISSION_GRANTED) { 4308 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4309 + Binder.getCallingPid() 4310 + ", uid=" + Binder.getCallingUid() 4311 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4312 Slog.w(TAG, msg); 4313 throw new SecurityException(msg); 4314 } 4315 4316 synchronized(this) { 4317 if (mHeavyWeightProcess == null) { 4318 return; 4319 } 4320 4321 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4322 mHeavyWeightProcess.activities); 4323 for (int i=0; i<activities.size(); i++) { 4324 ActivityRecord r = activities.get(i); 4325 if (!r.finishing) { 4326 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4327 null, "finish-heavy", true); 4328 } 4329 } 4330 4331 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4332 mHeavyWeightProcess.userId, 0)); 4333 mHeavyWeightProcess = null; 4334 } 4335 } 4336 4337 @Override 4338 public void crashApplication(int uid, int initialPid, String packageName, 4339 String message) { 4340 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4341 != PackageManager.PERMISSION_GRANTED) { 4342 String msg = "Permission Denial: crashApplication() from pid=" 4343 + Binder.getCallingPid() 4344 + ", uid=" + Binder.getCallingUid() 4345 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4346 Slog.w(TAG, msg); 4347 throw new SecurityException(msg); 4348 } 4349 4350 synchronized(this) { 4351 ProcessRecord proc = null; 4352 4353 // Figure out which process to kill. We don't trust that initialPid 4354 // still has any relation to current pids, so must scan through the 4355 // list. 4356 synchronized (mPidsSelfLocked) { 4357 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4358 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4359 if (p.uid != uid) { 4360 continue; 4361 } 4362 if (p.pid == initialPid) { 4363 proc = p; 4364 break; 4365 } 4366 if (p.pkgList.containsKey(packageName)) { 4367 proc = p; 4368 } 4369 } 4370 } 4371 4372 if (proc == null) { 4373 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4374 + " initialPid=" + initialPid 4375 + " packageName=" + packageName); 4376 return; 4377 } 4378 4379 if (proc.thread != null) { 4380 if (proc.pid == Process.myPid()) { 4381 Log.w(TAG, "crashApplication: trying to crash self!"); 4382 return; 4383 } 4384 long ident = Binder.clearCallingIdentity(); 4385 try { 4386 proc.thread.scheduleCrash(message); 4387 } catch (RemoteException e) { 4388 } 4389 Binder.restoreCallingIdentity(ident); 4390 } 4391 } 4392 } 4393 4394 @Override 4395 public final void finishSubActivity(IBinder token, String resultWho, 4396 int requestCode) { 4397 synchronized(this) { 4398 final long origId = Binder.clearCallingIdentity(); 4399 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4400 if (r != null) { 4401 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4402 } 4403 Binder.restoreCallingIdentity(origId); 4404 } 4405 } 4406 4407 @Override 4408 public boolean finishActivityAffinity(IBinder token) { 4409 synchronized(this) { 4410 final long origId = Binder.clearCallingIdentity(); 4411 try { 4412 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4413 4414 ActivityRecord rootR = r.task.getRootActivity(); 4415 // Do not allow task to finish in Lock Task mode. 4416 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4417 if (rootR == r) { 4418 mStackSupervisor.showLockTaskToast(); 4419 return false; 4420 } 4421 } 4422 boolean res = false; 4423 if (r != null) { 4424 res = r.task.stack.finishActivityAffinityLocked(r); 4425 } 4426 return res; 4427 } finally { 4428 Binder.restoreCallingIdentity(origId); 4429 } 4430 } 4431 } 4432 4433 @Override 4434 public void finishVoiceTask(IVoiceInteractionSession session) { 4435 synchronized(this) { 4436 final long origId = Binder.clearCallingIdentity(); 4437 try { 4438 mStackSupervisor.finishVoiceTask(session); 4439 } finally { 4440 Binder.restoreCallingIdentity(origId); 4441 } 4442 } 4443 4444 } 4445 4446 @Override 4447 public boolean releaseActivityInstance(IBinder token) { 4448 synchronized(this) { 4449 final long origId = Binder.clearCallingIdentity(); 4450 try { 4451 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4452 if (r.task == null || r.task.stack == null) { 4453 return false; 4454 } 4455 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4456 } finally { 4457 Binder.restoreCallingIdentity(origId); 4458 } 4459 } 4460 } 4461 4462 @Override 4463 public void releaseSomeActivities(IApplicationThread appInt) { 4464 synchronized(this) { 4465 final long origId = Binder.clearCallingIdentity(); 4466 try { 4467 ProcessRecord app = getRecordForAppLocked(appInt); 4468 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4469 } finally { 4470 Binder.restoreCallingIdentity(origId); 4471 } 4472 } 4473 } 4474 4475 @Override 4476 public boolean willActivityBeVisible(IBinder token) { 4477 synchronized(this) { 4478 ActivityStack stack = ActivityRecord.getStackLocked(token); 4479 if (stack != null) { 4480 return stack.willActivityBeVisibleLocked(token); 4481 } 4482 return false; 4483 } 4484 } 4485 4486 @Override 4487 public void overridePendingTransition(IBinder token, String packageName, 4488 int enterAnim, int exitAnim) { 4489 synchronized(this) { 4490 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4491 if (self == null) { 4492 return; 4493 } 4494 4495 final long origId = Binder.clearCallingIdentity(); 4496 4497 if (self.state == ActivityState.RESUMED 4498 || self.state == ActivityState.PAUSING) { 4499 mWindowManager.overridePendingAppTransition(packageName, 4500 enterAnim, exitAnim, null); 4501 } 4502 4503 Binder.restoreCallingIdentity(origId); 4504 } 4505 } 4506 4507 /** 4508 * Main function for removing an existing process from the activity manager 4509 * as a result of that process going away. Clears out all connections 4510 * to the process. 4511 */ 4512 private final void handleAppDiedLocked(ProcessRecord app, 4513 boolean restarting, boolean allowRestart) { 4514 int pid = app.pid; 4515 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4516 if (!kept && !restarting) { 4517 removeLruProcessLocked(app); 4518 if (pid > 0) { 4519 ProcessList.remove(pid); 4520 } 4521 } 4522 4523 if (mProfileProc == app) { 4524 clearProfilerLocked(); 4525 } 4526 4527 // Remove this application's activities from active lists. 4528 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4529 4530 app.activities.clear(); 4531 4532 if (app.instrumentationClass != null) { 4533 Slog.w(TAG, "Crash of app " + app.processName 4534 + " running instrumentation " + app.instrumentationClass); 4535 Bundle info = new Bundle(); 4536 info.putString("shortMsg", "Process crashed."); 4537 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4538 } 4539 4540 if (!restarting) { 4541 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4542 // If there was nothing to resume, and we are not already 4543 // restarting this process, but there is a visible activity that 4544 // is hosted by the process... then make sure all visible 4545 // activities are running, taking care of restarting this 4546 // process. 4547 if (hasVisibleActivities) { 4548 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4549 } 4550 } 4551 } 4552 } 4553 4554 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4555 IBinder threadBinder = thread.asBinder(); 4556 // Find the application record. 4557 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4558 ProcessRecord rec = mLruProcesses.get(i); 4559 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4560 return i; 4561 } 4562 } 4563 return -1; 4564 } 4565 4566 final ProcessRecord getRecordForAppLocked( 4567 IApplicationThread thread) { 4568 if (thread == null) { 4569 return null; 4570 } 4571 4572 int appIndex = getLRURecordIndexForAppLocked(thread); 4573 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4574 } 4575 4576 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4577 // If there are no longer any background processes running, 4578 // and the app that died was not running instrumentation, 4579 // then tell everyone we are now low on memory. 4580 boolean haveBg = false; 4581 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4582 ProcessRecord rec = mLruProcesses.get(i); 4583 if (rec.thread != null 4584 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4585 haveBg = true; 4586 break; 4587 } 4588 } 4589 4590 if (!haveBg) { 4591 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4592 if (doReport) { 4593 long now = SystemClock.uptimeMillis(); 4594 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4595 doReport = false; 4596 } else { 4597 mLastMemUsageReportTime = now; 4598 } 4599 } 4600 final ArrayList<ProcessMemInfo> memInfos 4601 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4602 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4603 long now = SystemClock.uptimeMillis(); 4604 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4605 ProcessRecord rec = mLruProcesses.get(i); 4606 if (rec == dyingProc || rec.thread == null) { 4607 continue; 4608 } 4609 if (doReport) { 4610 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4611 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4612 } 4613 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4614 // The low memory report is overriding any current 4615 // state for a GC request. Make sure to do 4616 // heavy/important/visible/foreground processes first. 4617 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4618 rec.lastRequestedGc = 0; 4619 } else { 4620 rec.lastRequestedGc = rec.lastLowMemory; 4621 } 4622 rec.reportLowMemory = true; 4623 rec.lastLowMemory = now; 4624 mProcessesToGc.remove(rec); 4625 addProcessToGcListLocked(rec); 4626 } 4627 } 4628 if (doReport) { 4629 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4630 mHandler.sendMessage(msg); 4631 } 4632 scheduleAppGcsLocked(); 4633 } 4634 } 4635 4636 final void appDiedLocked(ProcessRecord app) { 4637 appDiedLocked(app, app.pid, app.thread); 4638 } 4639 4640 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4641 // First check if this ProcessRecord is actually active for the pid. 4642 synchronized (mPidsSelfLocked) { 4643 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4644 if (curProc != app) { 4645 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4646 return; 4647 } 4648 } 4649 4650 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4651 synchronized (stats) { 4652 stats.noteProcessDiedLocked(app.info.uid, pid); 4653 } 4654 4655 Process.killProcessQuiet(pid); 4656 Process.killProcessGroup(app.info.uid, pid); 4657 app.killed = true; 4658 4659 // Clean up already done if the process has been re-started. 4660 if (app.pid == pid && app.thread != null && 4661 app.thread.asBinder() == thread.asBinder()) { 4662 boolean doLowMem = app.instrumentationClass == null; 4663 boolean doOomAdj = doLowMem; 4664 if (!app.killedByAm) { 4665 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4666 + ") has died"); 4667 mAllowLowerMemLevel = true; 4668 } else { 4669 // Note that we always want to do oom adj to update our state with the 4670 // new number of procs. 4671 mAllowLowerMemLevel = false; 4672 doLowMem = false; 4673 } 4674 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4675 if (DEBUG_CLEANUP) Slog.v( 4676 TAG, "Dying app: " + app + ", pid: " + pid 4677 + ", thread: " + thread.asBinder()); 4678 handleAppDiedLocked(app, false, true); 4679 4680 if (doOomAdj) { 4681 updateOomAdjLocked(); 4682 } 4683 if (doLowMem) { 4684 doLowMemReportIfNeededLocked(app); 4685 } 4686 } else if (app.pid != pid) { 4687 // A new process has already been started. 4688 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4689 + ") has died and restarted (pid " + app.pid + ")."); 4690 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4691 } else if (DEBUG_PROCESSES) { 4692 Slog.d(TAG, "Received spurious death notification for thread " 4693 + thread.asBinder()); 4694 } 4695 } 4696 4697 /** 4698 * If a stack trace dump file is configured, dump process stack traces. 4699 * @param clearTraces causes the dump file to be erased prior to the new 4700 * traces being written, if true; when false, the new traces will be 4701 * appended to any existing file content. 4702 * @param firstPids of dalvik VM processes to dump stack traces for first 4703 * @param lastPids of dalvik VM processes to dump stack traces for last 4704 * @param nativeProcs optional list of native process names to dump stack crawls 4705 * @return file containing stack traces, or null if no dump file is configured 4706 */ 4707 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4708 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4709 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4710 if (tracesPath == null || tracesPath.length() == 0) { 4711 return null; 4712 } 4713 4714 File tracesFile = new File(tracesPath); 4715 try { 4716 File tracesDir = tracesFile.getParentFile(); 4717 if (!tracesDir.exists()) { 4718 tracesDir.mkdirs(); 4719 if (!SELinux.restorecon(tracesDir)) { 4720 return null; 4721 } 4722 } 4723 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4724 4725 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4726 tracesFile.createNewFile(); 4727 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4728 } catch (IOException e) { 4729 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4730 return null; 4731 } 4732 4733 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4734 return tracesFile; 4735 } 4736 4737 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4738 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4739 // Use a FileObserver to detect when traces finish writing. 4740 // The order of traces is considered important to maintain for legibility. 4741 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4742 @Override 4743 public synchronized void onEvent(int event, String path) { notify(); } 4744 }; 4745 4746 try { 4747 observer.startWatching(); 4748 4749 // First collect all of the stacks of the most important pids. 4750 if (firstPids != null) { 4751 try { 4752 int num = firstPids.size(); 4753 for (int i = 0; i < num; i++) { 4754 synchronized (observer) { 4755 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4756 observer.wait(200); // Wait for write-close, give up after 200msec 4757 } 4758 } 4759 } catch (InterruptedException e) { 4760 Slog.wtf(TAG, e); 4761 } 4762 } 4763 4764 // Next collect the stacks of the native pids 4765 if (nativeProcs != null) { 4766 int[] pids = Process.getPidsForCommands(nativeProcs); 4767 if (pids != null) { 4768 for (int pid : pids) { 4769 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4770 } 4771 } 4772 } 4773 4774 // Lastly, measure CPU usage. 4775 if (processCpuTracker != null) { 4776 processCpuTracker.init(); 4777 System.gc(); 4778 processCpuTracker.update(); 4779 try { 4780 synchronized (processCpuTracker) { 4781 processCpuTracker.wait(500); // measure over 1/2 second. 4782 } 4783 } catch (InterruptedException e) { 4784 } 4785 processCpuTracker.update(); 4786 4787 // We'll take the stack crawls of just the top apps using CPU. 4788 final int N = processCpuTracker.countWorkingStats(); 4789 int numProcs = 0; 4790 for (int i=0; i<N && numProcs<5; i++) { 4791 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4792 if (lastPids.indexOfKey(stats.pid) >= 0) { 4793 numProcs++; 4794 try { 4795 synchronized (observer) { 4796 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4797 observer.wait(200); // Wait for write-close, give up after 200msec 4798 } 4799 } catch (InterruptedException e) { 4800 Slog.wtf(TAG, e); 4801 } 4802 4803 } 4804 } 4805 } 4806 } finally { 4807 observer.stopWatching(); 4808 } 4809 } 4810 4811 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4812 if (true || IS_USER_BUILD) { 4813 return; 4814 } 4815 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4816 if (tracesPath == null || tracesPath.length() == 0) { 4817 return; 4818 } 4819 4820 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4821 StrictMode.allowThreadDiskWrites(); 4822 try { 4823 final File tracesFile = new File(tracesPath); 4824 final File tracesDir = tracesFile.getParentFile(); 4825 final File tracesTmp = new File(tracesDir, "__tmp__"); 4826 try { 4827 if (!tracesDir.exists()) { 4828 tracesDir.mkdirs(); 4829 if (!SELinux.restorecon(tracesDir.getPath())) { 4830 return; 4831 } 4832 } 4833 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4834 4835 if (tracesFile.exists()) { 4836 tracesTmp.delete(); 4837 tracesFile.renameTo(tracesTmp); 4838 } 4839 StringBuilder sb = new StringBuilder(); 4840 Time tobj = new Time(); 4841 tobj.set(System.currentTimeMillis()); 4842 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4843 sb.append(": "); 4844 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4845 sb.append(" since "); 4846 sb.append(msg); 4847 FileOutputStream fos = new FileOutputStream(tracesFile); 4848 fos.write(sb.toString().getBytes()); 4849 if (app == null) { 4850 fos.write("\n*** No application process!".getBytes()); 4851 } 4852 fos.close(); 4853 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4854 } catch (IOException e) { 4855 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4856 return; 4857 } 4858 4859 if (app != null) { 4860 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4861 firstPids.add(app.pid); 4862 dumpStackTraces(tracesPath, firstPids, null, null, null); 4863 } 4864 4865 File lastTracesFile = null; 4866 File curTracesFile = null; 4867 for (int i=9; i>=0; i--) { 4868 String name = String.format(Locale.US, "slow%02d.txt", i); 4869 curTracesFile = new File(tracesDir, name); 4870 if (curTracesFile.exists()) { 4871 if (lastTracesFile != null) { 4872 curTracesFile.renameTo(lastTracesFile); 4873 } else { 4874 curTracesFile.delete(); 4875 } 4876 } 4877 lastTracesFile = curTracesFile; 4878 } 4879 tracesFile.renameTo(curTracesFile); 4880 if (tracesTmp.exists()) { 4881 tracesTmp.renameTo(tracesFile); 4882 } 4883 } finally { 4884 StrictMode.setThreadPolicy(oldPolicy); 4885 } 4886 } 4887 4888 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4889 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4890 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4891 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4892 4893 if (mController != null) { 4894 try { 4895 // 0 == continue, -1 = kill process immediately 4896 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4897 if (res < 0 && app.pid != MY_PID) { 4898 app.kill("anr", true); 4899 } 4900 } catch (RemoteException e) { 4901 mController = null; 4902 Watchdog.getInstance().setActivityController(null); 4903 } 4904 } 4905 4906 long anrTime = SystemClock.uptimeMillis(); 4907 if (MONITOR_CPU_USAGE) { 4908 updateCpuStatsNow(); 4909 } 4910 4911 synchronized (this) { 4912 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4913 if (mShuttingDown) { 4914 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4915 return; 4916 } else if (app.notResponding) { 4917 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4918 return; 4919 } else if (app.crashing) { 4920 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4921 return; 4922 } 4923 4924 // In case we come through here for the same app before completing 4925 // this one, mark as anring now so we will bail out. 4926 app.notResponding = true; 4927 4928 // Log the ANR to the event log. 4929 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4930 app.processName, app.info.flags, annotation); 4931 4932 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4933 firstPids.add(app.pid); 4934 4935 int parentPid = app.pid; 4936 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4937 if (parentPid != app.pid) firstPids.add(parentPid); 4938 4939 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4940 4941 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4942 ProcessRecord r = mLruProcesses.get(i); 4943 if (r != null && r.thread != null) { 4944 int pid = r.pid; 4945 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4946 if (r.persistent) { 4947 firstPids.add(pid); 4948 } else { 4949 lastPids.put(pid, Boolean.TRUE); 4950 } 4951 } 4952 } 4953 } 4954 } 4955 4956 // Log the ANR to the main log. 4957 StringBuilder info = new StringBuilder(); 4958 info.setLength(0); 4959 info.append("ANR in ").append(app.processName); 4960 if (activity != null && activity.shortComponentName != null) { 4961 info.append(" (").append(activity.shortComponentName).append(")"); 4962 } 4963 info.append("\n"); 4964 info.append("PID: ").append(app.pid).append("\n"); 4965 if (annotation != null) { 4966 info.append("Reason: ").append(annotation).append("\n"); 4967 } 4968 if (parent != null && parent != activity) { 4969 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4970 } 4971 4972 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4973 4974 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4975 NATIVE_STACKS_OF_INTEREST); 4976 4977 String cpuInfo = null; 4978 if (MONITOR_CPU_USAGE) { 4979 updateCpuStatsNow(); 4980 synchronized (mProcessCpuTracker) { 4981 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4982 } 4983 info.append(processCpuTracker.printCurrentLoad()); 4984 info.append(cpuInfo); 4985 } 4986 4987 info.append(processCpuTracker.printCurrentState(anrTime)); 4988 4989 Slog.e(TAG, info.toString()); 4990 if (tracesFile == null) { 4991 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4992 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4993 } 4994 4995 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4996 cpuInfo, tracesFile, null); 4997 4998 if (mController != null) { 4999 try { 5000 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5001 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5002 if (res != 0) { 5003 if (res < 0 && app.pid != MY_PID) { 5004 app.kill("anr", true); 5005 } else { 5006 synchronized (this) { 5007 mServices.scheduleServiceTimeoutLocked(app); 5008 } 5009 } 5010 return; 5011 } 5012 } catch (RemoteException e) { 5013 mController = null; 5014 Watchdog.getInstance().setActivityController(null); 5015 } 5016 } 5017 5018 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5019 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5020 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5021 5022 synchronized (this) { 5023 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5024 app.kill("bg anr", true); 5025 return; 5026 } 5027 5028 // Set the app's notResponding state, and look up the errorReportReceiver 5029 makeAppNotRespondingLocked(app, 5030 activity != null ? activity.shortComponentName : null, 5031 annotation != null ? "ANR " + annotation : "ANR", 5032 info.toString()); 5033 5034 // Bring up the infamous App Not Responding dialog 5035 Message msg = Message.obtain(); 5036 HashMap<String, Object> map = new HashMap<String, Object>(); 5037 msg.what = SHOW_NOT_RESPONDING_MSG; 5038 msg.obj = map; 5039 msg.arg1 = aboveSystem ? 1 : 0; 5040 map.put("app", app); 5041 if (activity != null) { 5042 map.put("activity", activity); 5043 } 5044 5045 mHandler.sendMessage(msg); 5046 } 5047 } 5048 5049 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5050 if (!mLaunchWarningShown) { 5051 mLaunchWarningShown = true; 5052 mHandler.post(new Runnable() { 5053 @Override 5054 public void run() { 5055 synchronized (ActivityManagerService.this) { 5056 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5057 d.show(); 5058 mHandler.postDelayed(new Runnable() { 5059 @Override 5060 public void run() { 5061 synchronized (ActivityManagerService.this) { 5062 d.dismiss(); 5063 mLaunchWarningShown = false; 5064 } 5065 } 5066 }, 4000); 5067 } 5068 } 5069 }); 5070 } 5071 } 5072 5073 @Override 5074 public boolean clearApplicationUserData(final String packageName, 5075 final IPackageDataObserver observer, int userId) { 5076 enforceNotIsolatedCaller("clearApplicationUserData"); 5077 int uid = Binder.getCallingUid(); 5078 int pid = Binder.getCallingPid(); 5079 userId = handleIncomingUser(pid, uid, 5080 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5081 long callingId = Binder.clearCallingIdentity(); 5082 try { 5083 IPackageManager pm = AppGlobals.getPackageManager(); 5084 int pkgUid = -1; 5085 synchronized(this) { 5086 try { 5087 pkgUid = pm.getPackageUid(packageName, userId); 5088 } catch (RemoteException e) { 5089 } 5090 if (pkgUid == -1) { 5091 Slog.w(TAG, "Invalid packageName: " + packageName); 5092 if (observer != null) { 5093 try { 5094 observer.onRemoveCompleted(packageName, false); 5095 } catch (RemoteException e) { 5096 Slog.i(TAG, "Observer no longer exists."); 5097 } 5098 } 5099 return false; 5100 } 5101 if (uid == pkgUid || checkComponentPermission( 5102 android.Manifest.permission.CLEAR_APP_USER_DATA, 5103 pid, uid, -1, true) 5104 == PackageManager.PERMISSION_GRANTED) { 5105 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5106 } else { 5107 throw new SecurityException("PID " + pid + " does not have permission " 5108 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5109 + " of package " + packageName); 5110 } 5111 5112 // Remove all tasks match the cleared application package and user 5113 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5114 final TaskRecord tr = mRecentTasks.get(i); 5115 final String taskPackageName = 5116 tr.getBaseIntent().getComponent().getPackageName(); 5117 if (tr.userId != userId) continue; 5118 if (!taskPackageName.equals(packageName)) continue; 5119 removeTaskByIdLocked(tr.taskId, false); 5120 } 5121 } 5122 5123 try { 5124 // Clear application user data 5125 pm.clearApplicationUserData(packageName, observer, userId); 5126 5127 synchronized(this) { 5128 // Remove all permissions granted from/to this package 5129 removeUriPermissionsForPackageLocked(packageName, userId, true); 5130 } 5131 5132 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5133 Uri.fromParts("package", packageName, null)); 5134 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5135 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5136 null, null, 0, null, null, null, false, false, userId); 5137 } catch (RemoteException e) { 5138 } 5139 } finally { 5140 Binder.restoreCallingIdentity(callingId); 5141 } 5142 return true; 5143 } 5144 5145 @Override 5146 public void killBackgroundProcesses(final String packageName, int userId) { 5147 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5148 != PackageManager.PERMISSION_GRANTED && 5149 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5150 != PackageManager.PERMISSION_GRANTED) { 5151 String msg = "Permission Denial: killBackgroundProcesses() 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 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5160 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5161 long callingId = Binder.clearCallingIdentity(); 5162 try { 5163 IPackageManager pm = AppGlobals.getPackageManager(); 5164 synchronized(this) { 5165 int appId = -1; 5166 try { 5167 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5168 } catch (RemoteException e) { 5169 } 5170 if (appId == -1) { 5171 Slog.w(TAG, "Invalid packageName: " + packageName); 5172 return; 5173 } 5174 killPackageProcessesLocked(packageName, appId, userId, 5175 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5176 } 5177 } finally { 5178 Binder.restoreCallingIdentity(callingId); 5179 } 5180 } 5181 5182 @Override 5183 public void killAllBackgroundProcesses() { 5184 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5185 != PackageManager.PERMISSION_GRANTED) { 5186 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5187 + Binder.getCallingPid() 5188 + ", uid=" + Binder.getCallingUid() 5189 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5190 Slog.w(TAG, msg); 5191 throw new SecurityException(msg); 5192 } 5193 5194 long callingId = Binder.clearCallingIdentity(); 5195 try { 5196 synchronized(this) { 5197 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5198 final int NP = mProcessNames.getMap().size(); 5199 for (int ip=0; ip<NP; ip++) { 5200 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5201 final int NA = apps.size(); 5202 for (int ia=0; ia<NA; ia++) { 5203 ProcessRecord app = apps.valueAt(ia); 5204 if (app.persistent) { 5205 // we don't kill persistent processes 5206 continue; 5207 } 5208 if (app.removed) { 5209 procs.add(app); 5210 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5211 app.removed = true; 5212 procs.add(app); 5213 } 5214 } 5215 } 5216 5217 int N = procs.size(); 5218 for (int i=0; i<N; i++) { 5219 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5220 } 5221 mAllowLowerMemLevel = true; 5222 updateOomAdjLocked(); 5223 doLowMemReportIfNeededLocked(null); 5224 } 5225 } finally { 5226 Binder.restoreCallingIdentity(callingId); 5227 } 5228 } 5229 5230 @Override 5231 public void forceStopPackage(final String packageName, int userId) { 5232 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5233 != PackageManager.PERMISSION_GRANTED) { 5234 String msg = "Permission Denial: forceStopPackage() from pid=" 5235 + Binder.getCallingPid() 5236 + ", uid=" + Binder.getCallingUid() 5237 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5238 Slog.w(TAG, msg); 5239 throw new SecurityException(msg); 5240 } 5241 final int callingPid = Binder.getCallingPid(); 5242 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5243 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5244 long callingId = Binder.clearCallingIdentity(); 5245 try { 5246 IPackageManager pm = AppGlobals.getPackageManager(); 5247 synchronized(this) { 5248 int[] users = userId == UserHandle.USER_ALL 5249 ? getUsersLocked() : new int[] { userId }; 5250 for (int user : users) { 5251 int pkgUid = -1; 5252 try { 5253 pkgUid = pm.getPackageUid(packageName, user); 5254 } catch (RemoteException e) { 5255 } 5256 if (pkgUid == -1) { 5257 Slog.w(TAG, "Invalid packageName: " + packageName); 5258 continue; 5259 } 5260 try { 5261 pm.setPackageStoppedState(packageName, true, user); 5262 } catch (RemoteException e) { 5263 } catch (IllegalArgumentException e) { 5264 Slog.w(TAG, "Failed trying to unstop package " 5265 + packageName + ": " + e); 5266 } 5267 if (isUserRunningLocked(user, false)) { 5268 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5269 } 5270 } 5271 } 5272 } finally { 5273 Binder.restoreCallingIdentity(callingId); 5274 } 5275 } 5276 5277 @Override 5278 public void addPackageDependency(String packageName) { 5279 synchronized (this) { 5280 int callingPid = Binder.getCallingPid(); 5281 if (callingPid == Process.myPid()) { 5282 // Yeah, um, no. 5283 Slog.w(TAG, "Can't addPackageDependency on system process"); 5284 return; 5285 } 5286 ProcessRecord proc; 5287 synchronized (mPidsSelfLocked) { 5288 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5289 } 5290 if (proc != null) { 5291 if (proc.pkgDeps == null) { 5292 proc.pkgDeps = new ArraySet<String>(1); 5293 } 5294 proc.pkgDeps.add(packageName); 5295 } 5296 } 5297 } 5298 5299 /* 5300 * The pkg name and app id have to be specified. 5301 */ 5302 @Override 5303 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5304 if (pkg == null) { 5305 return; 5306 } 5307 // Make sure the uid is valid. 5308 if (appid < 0) { 5309 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5310 return; 5311 } 5312 int callerUid = Binder.getCallingUid(); 5313 // Only the system server can kill an application 5314 if (callerUid == Process.SYSTEM_UID) { 5315 // Post an aysnc message to kill the application 5316 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5317 msg.arg1 = appid; 5318 msg.arg2 = 0; 5319 Bundle bundle = new Bundle(); 5320 bundle.putString("pkg", pkg); 5321 bundle.putString("reason", reason); 5322 msg.obj = bundle; 5323 mHandler.sendMessage(msg); 5324 } else { 5325 throw new SecurityException(callerUid + " cannot kill pkg: " + 5326 pkg); 5327 } 5328 } 5329 5330 @Override 5331 public void closeSystemDialogs(String reason) { 5332 enforceNotIsolatedCaller("closeSystemDialogs"); 5333 5334 final int pid = Binder.getCallingPid(); 5335 final int uid = Binder.getCallingUid(); 5336 final long origId = Binder.clearCallingIdentity(); 5337 try { 5338 synchronized (this) { 5339 // Only allow this from foreground processes, so that background 5340 // applications can't abuse it to prevent system UI from being shown. 5341 if (uid >= Process.FIRST_APPLICATION_UID) { 5342 ProcessRecord proc; 5343 synchronized (mPidsSelfLocked) { 5344 proc = mPidsSelfLocked.get(pid); 5345 } 5346 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5347 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5348 + " from background process " + proc); 5349 return; 5350 } 5351 } 5352 closeSystemDialogsLocked(reason); 5353 } 5354 } finally { 5355 Binder.restoreCallingIdentity(origId); 5356 } 5357 } 5358 5359 void closeSystemDialogsLocked(String reason) { 5360 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5361 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5362 | Intent.FLAG_RECEIVER_FOREGROUND); 5363 if (reason != null) { 5364 intent.putExtra("reason", reason); 5365 } 5366 mWindowManager.closeSystemDialogs(reason); 5367 5368 mStackSupervisor.closeSystemDialogsLocked(); 5369 5370 broadcastIntentLocked(null, null, intent, null, 5371 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5372 Process.SYSTEM_UID, UserHandle.USER_ALL); 5373 } 5374 5375 @Override 5376 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5377 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5378 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5379 for (int i=pids.length-1; i>=0; i--) { 5380 ProcessRecord proc; 5381 int oomAdj; 5382 synchronized (this) { 5383 synchronized (mPidsSelfLocked) { 5384 proc = mPidsSelfLocked.get(pids[i]); 5385 oomAdj = proc != null ? proc.setAdj : 0; 5386 } 5387 } 5388 infos[i] = new Debug.MemoryInfo(); 5389 Debug.getMemoryInfo(pids[i], infos[i]); 5390 if (proc != null) { 5391 synchronized (this) { 5392 if (proc.thread != null && proc.setAdj == oomAdj) { 5393 // Record this for posterity if the process has been stable. 5394 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5395 infos[i].getTotalUss(), false, proc.pkgList); 5396 } 5397 } 5398 } 5399 } 5400 return infos; 5401 } 5402 5403 @Override 5404 public long[] getProcessPss(int[] pids) { 5405 enforceNotIsolatedCaller("getProcessPss"); 5406 long[] pss = new long[pids.length]; 5407 for (int i=pids.length-1; i>=0; i--) { 5408 ProcessRecord proc; 5409 int oomAdj; 5410 synchronized (this) { 5411 synchronized (mPidsSelfLocked) { 5412 proc = mPidsSelfLocked.get(pids[i]); 5413 oomAdj = proc != null ? proc.setAdj : 0; 5414 } 5415 } 5416 long[] tmpUss = new long[1]; 5417 pss[i] = Debug.getPss(pids[i], tmpUss); 5418 if (proc != null) { 5419 synchronized (this) { 5420 if (proc.thread != null && proc.setAdj == oomAdj) { 5421 // Record this for posterity if the process has been stable. 5422 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5423 } 5424 } 5425 } 5426 } 5427 return pss; 5428 } 5429 5430 @Override 5431 public void killApplicationProcess(String processName, int uid) { 5432 if (processName == null) { 5433 return; 5434 } 5435 5436 int callerUid = Binder.getCallingUid(); 5437 // Only the system server can kill an application 5438 if (callerUid == Process.SYSTEM_UID) { 5439 synchronized (this) { 5440 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5441 if (app != null && app.thread != null) { 5442 try { 5443 app.thread.scheduleSuicide(); 5444 } catch (RemoteException e) { 5445 // If the other end already died, then our work here is done. 5446 } 5447 } else { 5448 Slog.w(TAG, "Process/uid not found attempting kill of " 5449 + processName + " / " + uid); 5450 } 5451 } 5452 } else { 5453 throw new SecurityException(callerUid + " cannot kill app process: " + 5454 processName); 5455 } 5456 } 5457 5458 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5459 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5460 false, true, false, false, UserHandle.getUserId(uid), reason); 5461 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5462 Uri.fromParts("package", packageName, null)); 5463 if (!mProcessesReady) { 5464 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5465 | Intent.FLAG_RECEIVER_FOREGROUND); 5466 } 5467 intent.putExtra(Intent.EXTRA_UID, uid); 5468 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5469 broadcastIntentLocked(null, null, intent, 5470 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5471 false, false, 5472 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5473 } 5474 5475 private void forceStopUserLocked(int userId, String reason) { 5476 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5477 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5478 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5479 | Intent.FLAG_RECEIVER_FOREGROUND); 5480 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5481 broadcastIntentLocked(null, null, intent, 5482 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5483 false, false, 5484 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5485 } 5486 5487 private final boolean killPackageProcessesLocked(String packageName, int appId, 5488 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5489 boolean doit, boolean evenPersistent, String reason) { 5490 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5491 5492 // Remove all processes this package may have touched: all with the 5493 // same UID (except for the system or root user), and all whose name 5494 // matches the package name. 5495 final int NP = mProcessNames.getMap().size(); 5496 for (int ip=0; ip<NP; ip++) { 5497 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5498 final int NA = apps.size(); 5499 for (int ia=0; ia<NA; ia++) { 5500 ProcessRecord app = apps.valueAt(ia); 5501 if (app.persistent && !evenPersistent) { 5502 // we don't kill persistent processes 5503 continue; 5504 } 5505 if (app.removed) { 5506 if (doit) { 5507 procs.add(app); 5508 } 5509 continue; 5510 } 5511 5512 // Skip process if it doesn't meet our oom adj requirement. 5513 if (app.setAdj < minOomAdj) { 5514 continue; 5515 } 5516 5517 // If no package is specified, we call all processes under the 5518 // give user id. 5519 if (packageName == null) { 5520 if (app.userId != userId) { 5521 continue; 5522 } 5523 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5524 continue; 5525 } 5526 // Package has been specified, we want to hit all processes 5527 // that match it. We need to qualify this by the processes 5528 // that are running under the specified app and user ID. 5529 } else { 5530 final boolean isDep = app.pkgDeps != null 5531 && app.pkgDeps.contains(packageName); 5532 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5533 continue; 5534 } 5535 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5536 continue; 5537 } 5538 if (!app.pkgList.containsKey(packageName) && !isDep) { 5539 continue; 5540 } 5541 } 5542 5543 // Process has passed all conditions, kill it! 5544 if (!doit) { 5545 return true; 5546 } 5547 app.removed = true; 5548 procs.add(app); 5549 } 5550 } 5551 5552 int N = procs.size(); 5553 for (int i=0; i<N; i++) { 5554 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5555 } 5556 updateOomAdjLocked(); 5557 return N > 0; 5558 } 5559 5560 private final boolean forceStopPackageLocked(String name, int appId, 5561 boolean callerWillRestart, boolean purgeCache, boolean doit, 5562 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5563 int i; 5564 int N; 5565 5566 if (userId == UserHandle.USER_ALL && name == null) { 5567 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5568 } 5569 5570 if (appId < 0 && name != null) { 5571 try { 5572 appId = UserHandle.getAppId( 5573 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5574 } catch (RemoteException e) { 5575 } 5576 } 5577 5578 if (doit) { 5579 if (name != null) { 5580 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5581 + " user=" + userId + ": " + reason); 5582 } else { 5583 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5584 } 5585 5586 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5587 for (int ip=pmap.size()-1; ip>=0; ip--) { 5588 SparseArray<Long> ba = pmap.valueAt(ip); 5589 for (i=ba.size()-1; i>=0; i--) { 5590 boolean remove = false; 5591 final int entUid = ba.keyAt(i); 5592 if (name != null) { 5593 if (userId == UserHandle.USER_ALL) { 5594 if (UserHandle.getAppId(entUid) == appId) { 5595 remove = true; 5596 } 5597 } else { 5598 if (entUid == UserHandle.getUid(userId, appId)) { 5599 remove = true; 5600 } 5601 } 5602 } else if (UserHandle.getUserId(entUid) == userId) { 5603 remove = true; 5604 } 5605 if (remove) { 5606 ba.removeAt(i); 5607 } 5608 } 5609 if (ba.size() == 0) { 5610 pmap.removeAt(ip); 5611 } 5612 } 5613 } 5614 5615 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5616 -100, callerWillRestart, true, doit, evenPersistent, 5617 name == null ? ("stop user " + userId) : ("stop " + name)); 5618 5619 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5620 if (!doit) { 5621 return true; 5622 } 5623 didSomething = true; 5624 } 5625 5626 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5627 if (!doit) { 5628 return true; 5629 } 5630 didSomething = true; 5631 } 5632 5633 if (name == null) { 5634 // Remove all sticky broadcasts from this user. 5635 mStickyBroadcasts.remove(userId); 5636 } 5637 5638 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5639 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5640 userId, providers)) { 5641 if (!doit) { 5642 return true; 5643 } 5644 didSomething = true; 5645 } 5646 N = providers.size(); 5647 for (i=0; i<N; i++) { 5648 removeDyingProviderLocked(null, providers.get(i), true); 5649 } 5650 5651 // Remove transient permissions granted from/to this package/user 5652 removeUriPermissionsForPackageLocked(name, userId, false); 5653 5654 if (name == null || uninstalling) { 5655 // Remove pending intents. For now we only do this when force 5656 // stopping users, because we have some problems when doing this 5657 // for packages -- app widgets are not currently cleaned up for 5658 // such packages, so they can be left with bad pending intents. 5659 if (mIntentSenderRecords.size() > 0) { 5660 Iterator<WeakReference<PendingIntentRecord>> it 5661 = mIntentSenderRecords.values().iterator(); 5662 while (it.hasNext()) { 5663 WeakReference<PendingIntentRecord> wpir = it.next(); 5664 if (wpir == null) { 5665 it.remove(); 5666 continue; 5667 } 5668 PendingIntentRecord pir = wpir.get(); 5669 if (pir == null) { 5670 it.remove(); 5671 continue; 5672 } 5673 if (name == null) { 5674 // Stopping user, remove all objects for the user. 5675 if (pir.key.userId != userId) { 5676 // Not the same user, skip it. 5677 continue; 5678 } 5679 } else { 5680 if (UserHandle.getAppId(pir.uid) != appId) { 5681 // Different app id, skip it. 5682 continue; 5683 } 5684 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5685 // Different user, skip it. 5686 continue; 5687 } 5688 if (!pir.key.packageName.equals(name)) { 5689 // Different package, skip it. 5690 continue; 5691 } 5692 } 5693 if (!doit) { 5694 return true; 5695 } 5696 didSomething = true; 5697 it.remove(); 5698 pir.canceled = true; 5699 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5700 pir.key.activity.pendingResults.remove(pir.ref); 5701 } 5702 } 5703 } 5704 } 5705 5706 if (doit) { 5707 if (purgeCache && name != null) { 5708 AttributeCache ac = AttributeCache.instance(); 5709 if (ac != null) { 5710 ac.removePackage(name); 5711 } 5712 } 5713 if (mBooted) { 5714 mStackSupervisor.resumeTopActivitiesLocked(); 5715 mStackSupervisor.scheduleIdleLocked(); 5716 } 5717 } 5718 5719 return didSomething; 5720 } 5721 5722 private final boolean removeProcessLocked(ProcessRecord app, 5723 boolean callerWillRestart, boolean allowRestart, String reason) { 5724 final String name = app.processName; 5725 final int uid = app.uid; 5726 if (DEBUG_PROCESSES) Slog.d( 5727 TAG, "Force removing proc " + app.toShortString() + " (" + name 5728 + "/" + uid + ")"); 5729 5730 mProcessNames.remove(name, uid); 5731 mIsolatedProcesses.remove(app.uid); 5732 if (mHeavyWeightProcess == app) { 5733 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5734 mHeavyWeightProcess.userId, 0)); 5735 mHeavyWeightProcess = null; 5736 } 5737 boolean needRestart = false; 5738 if (app.pid > 0 && app.pid != MY_PID) { 5739 int pid = app.pid; 5740 synchronized (mPidsSelfLocked) { 5741 mPidsSelfLocked.remove(pid); 5742 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5743 } 5744 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5745 if (app.isolated) { 5746 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5747 } 5748 app.kill(reason, true); 5749 handleAppDiedLocked(app, true, allowRestart); 5750 removeLruProcessLocked(app); 5751 5752 if (app.persistent && !app.isolated) { 5753 if (!callerWillRestart) { 5754 addAppLocked(app.info, false, null /* ABI override */); 5755 } else { 5756 needRestart = true; 5757 } 5758 } 5759 } else { 5760 mRemovedProcesses.add(app); 5761 } 5762 5763 return needRestart; 5764 } 5765 5766 private final void processStartTimedOutLocked(ProcessRecord app) { 5767 final int pid = app.pid; 5768 boolean gone = false; 5769 synchronized (mPidsSelfLocked) { 5770 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5771 if (knownApp != null && knownApp.thread == null) { 5772 mPidsSelfLocked.remove(pid); 5773 gone = true; 5774 } 5775 } 5776 5777 if (gone) { 5778 Slog.w(TAG, "Process " + app + " failed to attach"); 5779 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5780 pid, app.uid, app.processName); 5781 mProcessNames.remove(app.processName, app.uid); 5782 mIsolatedProcesses.remove(app.uid); 5783 if (mHeavyWeightProcess == app) { 5784 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5785 mHeavyWeightProcess.userId, 0)); 5786 mHeavyWeightProcess = null; 5787 } 5788 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5789 if (app.isolated) { 5790 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5791 } 5792 // Take care of any launching providers waiting for this process. 5793 checkAppInLaunchingProvidersLocked(app, true); 5794 // Take care of any services that are waiting for the process. 5795 mServices.processStartTimedOutLocked(app); 5796 app.kill("start timeout", true); 5797 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5798 Slog.w(TAG, "Unattached app died before backup, skipping"); 5799 try { 5800 IBackupManager bm = IBackupManager.Stub.asInterface( 5801 ServiceManager.getService(Context.BACKUP_SERVICE)); 5802 bm.agentDisconnected(app.info.packageName); 5803 } catch (RemoteException e) { 5804 // Can't happen; the backup manager is local 5805 } 5806 } 5807 if (isPendingBroadcastProcessLocked(pid)) { 5808 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5809 skipPendingBroadcastLocked(pid); 5810 } 5811 } else { 5812 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5813 } 5814 } 5815 5816 private final boolean attachApplicationLocked(IApplicationThread thread, 5817 int pid) { 5818 5819 // Find the application record that is being attached... either via 5820 // the pid if we are running in multiple processes, or just pull the 5821 // next app record if we are emulating process with anonymous threads. 5822 ProcessRecord app; 5823 if (pid != MY_PID && pid >= 0) { 5824 synchronized (mPidsSelfLocked) { 5825 app = mPidsSelfLocked.get(pid); 5826 } 5827 } else { 5828 app = null; 5829 } 5830 5831 if (app == null) { 5832 Slog.w(TAG, "No pending application record for pid " + pid 5833 + " (IApplicationThread " + thread + "); dropping process"); 5834 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5835 if (pid > 0 && pid != MY_PID) { 5836 Process.killProcessQuiet(pid); 5837 //TODO: Process.killProcessGroup(app.info.uid, pid); 5838 } else { 5839 try { 5840 thread.scheduleExit(); 5841 } catch (Exception e) { 5842 // Ignore exceptions. 5843 } 5844 } 5845 return false; 5846 } 5847 5848 // If this application record is still attached to a previous 5849 // process, clean it up now. 5850 if (app.thread != null) { 5851 handleAppDiedLocked(app, true, true); 5852 } 5853 5854 // Tell the process all about itself. 5855 5856 if (localLOGV) Slog.v( 5857 TAG, "Binding process pid " + pid + " to record " + app); 5858 5859 final String processName = app.processName; 5860 try { 5861 AppDeathRecipient adr = new AppDeathRecipient( 5862 app, pid, thread); 5863 thread.asBinder().linkToDeath(adr, 0); 5864 app.deathRecipient = adr; 5865 } catch (RemoteException e) { 5866 app.resetPackageList(mProcessStats); 5867 startProcessLocked(app, "link fail", processName); 5868 return false; 5869 } 5870 5871 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5872 5873 app.makeActive(thread, mProcessStats); 5874 app.curAdj = app.setAdj = -100; 5875 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5876 app.forcingToForeground = null; 5877 updateProcessForegroundLocked(app, false, false); 5878 app.hasShownUi = false; 5879 app.debugging = false; 5880 app.cached = false; 5881 app.killedByAm = false; 5882 5883 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5884 5885 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5886 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5887 5888 if (!normalMode) { 5889 Slog.i(TAG, "Launching preboot mode app: " + app); 5890 } 5891 5892 if (localLOGV) Slog.v( 5893 TAG, "New app record " + app 5894 + " thread=" + thread.asBinder() + " pid=" + pid); 5895 try { 5896 int testMode = IApplicationThread.DEBUG_OFF; 5897 if (mDebugApp != null && mDebugApp.equals(processName)) { 5898 testMode = mWaitForDebugger 5899 ? IApplicationThread.DEBUG_WAIT 5900 : IApplicationThread.DEBUG_ON; 5901 app.debugging = true; 5902 if (mDebugTransient) { 5903 mDebugApp = mOrigDebugApp; 5904 mWaitForDebugger = mOrigWaitForDebugger; 5905 } 5906 } 5907 String profileFile = app.instrumentationProfileFile; 5908 ParcelFileDescriptor profileFd = null; 5909 int samplingInterval = 0; 5910 boolean profileAutoStop = false; 5911 if (mProfileApp != null && mProfileApp.equals(processName)) { 5912 mProfileProc = app; 5913 profileFile = mProfileFile; 5914 profileFd = mProfileFd; 5915 samplingInterval = mSamplingInterval; 5916 profileAutoStop = mAutoStopProfiler; 5917 } 5918 boolean enableOpenGlTrace = false; 5919 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5920 enableOpenGlTrace = true; 5921 mOpenGlTraceApp = null; 5922 } 5923 5924 // If the app is being launched for restore or full backup, set it up specially 5925 boolean isRestrictedBackupMode = false; 5926 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5927 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5928 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5929 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5930 } 5931 5932 ensurePackageDexOpt(app.instrumentationInfo != null 5933 ? app.instrumentationInfo.packageName 5934 : app.info.packageName); 5935 if (app.instrumentationClass != null) { 5936 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5937 } 5938 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5939 + processName + " with config " + mConfiguration); 5940 ApplicationInfo appInfo = app.instrumentationInfo != null 5941 ? app.instrumentationInfo : app.info; 5942 app.compat = compatibilityInfoForPackageLocked(appInfo); 5943 if (profileFd != null) { 5944 profileFd = profileFd.dup(); 5945 } 5946 ProfilerInfo profilerInfo = profileFile == null ? null 5947 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5948 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5949 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5950 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5951 isRestrictedBackupMode || !normalMode, app.persistent, 5952 new Configuration(mConfiguration), app.compat, 5953 getCommonServicesLocked(app.isolated), 5954 mCoreSettingsObserver.getCoreSettingsLocked()); 5955 updateLruProcessLocked(app, false, null); 5956 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5957 } catch (Exception e) { 5958 // todo: Yikes! What should we do? For now we will try to 5959 // start another process, but that could easily get us in 5960 // an infinite loop of restarting processes... 5961 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5962 5963 app.resetPackageList(mProcessStats); 5964 app.unlinkDeathRecipient(); 5965 startProcessLocked(app, "bind fail", processName); 5966 return false; 5967 } 5968 5969 // Remove this record from the list of starting applications. 5970 mPersistentStartingProcesses.remove(app); 5971 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5972 "Attach application locked removing on hold: " + app); 5973 mProcessesOnHold.remove(app); 5974 5975 boolean badApp = false; 5976 boolean didSomething = false; 5977 5978 // See if the top visible activity is waiting to run in this process... 5979 if (normalMode) { 5980 try { 5981 if (mStackSupervisor.attachApplicationLocked(app)) { 5982 didSomething = true; 5983 } 5984 } catch (Exception e) { 5985 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5986 badApp = true; 5987 } 5988 } 5989 5990 // Find any services that should be running in this process... 5991 if (!badApp) { 5992 try { 5993 didSomething |= mServices.attachApplicationLocked(app, processName); 5994 } catch (Exception e) { 5995 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5996 badApp = true; 5997 } 5998 } 5999 6000 // Check if a next-broadcast receiver is in this process... 6001 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6002 try { 6003 didSomething |= sendPendingBroadcastsLocked(app); 6004 } catch (Exception e) { 6005 // If the app died trying to launch the receiver we declare it 'bad' 6006 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6007 badApp = true; 6008 } 6009 } 6010 6011 // Check whether the next backup agent is in this process... 6012 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6013 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6014 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6015 try { 6016 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6017 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6018 mBackupTarget.backupMode); 6019 } catch (Exception e) { 6020 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6021 badApp = true; 6022 } 6023 } 6024 6025 if (badApp) { 6026 app.kill("error during init", true); 6027 handleAppDiedLocked(app, false, true); 6028 return false; 6029 } 6030 6031 if (!didSomething) { 6032 updateOomAdjLocked(); 6033 } 6034 6035 return true; 6036 } 6037 6038 @Override 6039 public final void attachApplication(IApplicationThread thread) { 6040 synchronized (this) { 6041 int callingPid = Binder.getCallingPid(); 6042 final long origId = Binder.clearCallingIdentity(); 6043 attachApplicationLocked(thread, callingPid); 6044 Binder.restoreCallingIdentity(origId); 6045 } 6046 } 6047 6048 @Override 6049 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6050 final long origId = Binder.clearCallingIdentity(); 6051 synchronized (this) { 6052 ActivityStack stack = ActivityRecord.getStackLocked(token); 6053 if (stack != null) { 6054 ActivityRecord r = 6055 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6056 if (stopProfiling) { 6057 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6058 try { 6059 mProfileFd.close(); 6060 } catch (IOException e) { 6061 } 6062 clearProfilerLocked(); 6063 } 6064 } 6065 } 6066 } 6067 Binder.restoreCallingIdentity(origId); 6068 } 6069 6070 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6071 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6072 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6073 } 6074 6075 void enableScreenAfterBoot() { 6076 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6077 SystemClock.uptimeMillis()); 6078 mWindowManager.enableScreenAfterBoot(); 6079 6080 synchronized (this) { 6081 updateEventDispatchingLocked(); 6082 } 6083 } 6084 6085 @Override 6086 public void showBootMessage(final CharSequence msg, final boolean always) { 6087 enforceNotIsolatedCaller("showBootMessage"); 6088 mWindowManager.showBootMessage(msg, always); 6089 } 6090 6091 @Override 6092 public void keyguardWaitingForActivityDrawn() { 6093 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6094 final long token = Binder.clearCallingIdentity(); 6095 try { 6096 synchronized (this) { 6097 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6098 mWindowManager.keyguardWaitingForActivityDrawn(); 6099 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6100 mLockScreenShown = LOCK_SCREEN_LEAVING; 6101 updateSleepIfNeededLocked(); 6102 } 6103 } 6104 } finally { 6105 Binder.restoreCallingIdentity(token); 6106 } 6107 } 6108 6109 final void finishBooting() { 6110 synchronized (this) { 6111 if (!mBootAnimationComplete) { 6112 mCallFinishBooting = true; 6113 return; 6114 } 6115 mCallFinishBooting = false; 6116 } 6117 6118 ArraySet<String> completedIsas = new ArraySet<String>(); 6119 for (String abi : Build.SUPPORTED_ABIS) { 6120 Process.establishZygoteConnectionForAbi(abi); 6121 final String instructionSet = VMRuntime.getInstructionSet(abi); 6122 if (!completedIsas.contains(instructionSet)) { 6123 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6124 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6125 } 6126 completedIsas.add(instructionSet); 6127 } 6128 } 6129 6130 IntentFilter pkgFilter = new IntentFilter(); 6131 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6132 pkgFilter.addDataScheme("package"); 6133 mContext.registerReceiver(new BroadcastReceiver() { 6134 @Override 6135 public void onReceive(Context context, Intent intent) { 6136 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6137 if (pkgs != null) { 6138 for (String pkg : pkgs) { 6139 synchronized (ActivityManagerService.this) { 6140 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6141 0, "finished booting")) { 6142 setResultCode(Activity.RESULT_OK); 6143 return; 6144 } 6145 } 6146 } 6147 } 6148 } 6149 }, pkgFilter); 6150 6151 // Let system services know. 6152 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6153 6154 synchronized (this) { 6155 // Ensure that any processes we had put on hold are now started 6156 // up. 6157 final int NP = mProcessesOnHold.size(); 6158 if (NP > 0) { 6159 ArrayList<ProcessRecord> procs = 6160 new ArrayList<ProcessRecord>(mProcessesOnHold); 6161 for (int ip=0; ip<NP; ip++) { 6162 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6163 + procs.get(ip)); 6164 startProcessLocked(procs.get(ip), "on-hold", null); 6165 } 6166 } 6167 6168 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6169 // Start looking for apps that are abusing wake locks. 6170 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6171 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6172 // Tell anyone interested that we are done booting! 6173 SystemProperties.set("sys.boot_completed", "1"); 6174 6175 // And trigger dev.bootcomplete if we are not showing encryption progress 6176 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6177 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6178 SystemProperties.set("dev.bootcomplete", "1"); 6179 } 6180 for (int i=0; i<mStartedUsers.size(); i++) { 6181 UserStartedState uss = mStartedUsers.valueAt(i); 6182 if (uss.mState == UserStartedState.STATE_BOOTING) { 6183 uss.mState = UserStartedState.STATE_RUNNING; 6184 final int userId = mStartedUsers.keyAt(i); 6185 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6186 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6187 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6188 broadcastIntentLocked(null, null, intent, null, 6189 new IIntentReceiver.Stub() { 6190 @Override 6191 public void performReceive(Intent intent, int resultCode, 6192 String data, Bundle extras, boolean ordered, 6193 boolean sticky, int sendingUser) { 6194 synchronized (ActivityManagerService.this) { 6195 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6196 true, false); 6197 } 6198 } 6199 }, 6200 0, null, null, 6201 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6202 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6203 userId); 6204 } 6205 } 6206 scheduleStartProfilesLocked(); 6207 } 6208 } 6209 } 6210 6211 @Override 6212 public void bootAnimationComplete() { 6213 final boolean callFinishBooting; 6214 synchronized (this) { 6215 callFinishBooting = mCallFinishBooting; 6216 mBootAnimationComplete = true; 6217 } 6218 if (callFinishBooting) { 6219 finishBooting(); 6220 } 6221 } 6222 6223 final void ensureBootCompleted() { 6224 boolean booting; 6225 boolean enableScreen; 6226 synchronized (this) { 6227 booting = mBooting; 6228 mBooting = false; 6229 enableScreen = !mBooted; 6230 mBooted = true; 6231 } 6232 6233 if (booting) { 6234 finishBooting(); 6235 } 6236 6237 if (enableScreen) { 6238 enableScreenAfterBoot(); 6239 } 6240 } 6241 6242 @Override 6243 public final void activityResumed(IBinder token) { 6244 final long origId = Binder.clearCallingIdentity(); 6245 synchronized(this) { 6246 ActivityStack stack = ActivityRecord.getStackLocked(token); 6247 if (stack != null) { 6248 ActivityRecord.activityResumedLocked(token); 6249 } 6250 } 6251 Binder.restoreCallingIdentity(origId); 6252 } 6253 6254 @Override 6255 public final void activityPaused(IBinder token) { 6256 final long origId = Binder.clearCallingIdentity(); 6257 synchronized(this) { 6258 ActivityStack stack = ActivityRecord.getStackLocked(token); 6259 if (stack != null) { 6260 stack.activityPausedLocked(token, false); 6261 } 6262 } 6263 Binder.restoreCallingIdentity(origId); 6264 } 6265 6266 @Override 6267 public final void activityStopped(IBinder token, Bundle icicle, 6268 PersistableBundle persistentState, CharSequence description) { 6269 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6270 6271 // Refuse possible leaked file descriptors 6272 if (icicle != null && icicle.hasFileDescriptors()) { 6273 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6274 } 6275 6276 final long origId = Binder.clearCallingIdentity(); 6277 6278 synchronized (this) { 6279 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6280 if (r != null) { 6281 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6282 } 6283 } 6284 6285 trimApplications(); 6286 6287 Binder.restoreCallingIdentity(origId); 6288 } 6289 6290 @Override 6291 public final void activityDestroyed(IBinder token) { 6292 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6293 synchronized (this) { 6294 ActivityStack stack = ActivityRecord.getStackLocked(token); 6295 if (stack != null) { 6296 stack.activityDestroyedLocked(token); 6297 } 6298 } 6299 } 6300 6301 @Override 6302 public final void backgroundResourcesReleased(IBinder token) { 6303 final long origId = Binder.clearCallingIdentity(); 6304 try { 6305 synchronized (this) { 6306 ActivityStack stack = ActivityRecord.getStackLocked(token); 6307 if (stack != null) { 6308 stack.backgroundResourcesReleased(); 6309 } 6310 } 6311 } finally { 6312 Binder.restoreCallingIdentity(origId); 6313 } 6314 } 6315 6316 @Override 6317 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6318 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6319 } 6320 6321 @Override 6322 public final void notifyEnterAnimationComplete(IBinder token) { 6323 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6324 } 6325 6326 @Override 6327 public String getCallingPackage(IBinder token) { 6328 synchronized (this) { 6329 ActivityRecord r = getCallingRecordLocked(token); 6330 return r != null ? r.info.packageName : null; 6331 } 6332 } 6333 6334 @Override 6335 public ComponentName getCallingActivity(IBinder token) { 6336 synchronized (this) { 6337 ActivityRecord r = getCallingRecordLocked(token); 6338 return r != null ? r.intent.getComponent() : null; 6339 } 6340 } 6341 6342 private ActivityRecord getCallingRecordLocked(IBinder token) { 6343 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6344 if (r == null) { 6345 return null; 6346 } 6347 return r.resultTo; 6348 } 6349 6350 @Override 6351 public ComponentName getActivityClassForToken(IBinder token) { 6352 synchronized(this) { 6353 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6354 if (r == null) { 6355 return null; 6356 } 6357 return r.intent.getComponent(); 6358 } 6359 } 6360 6361 @Override 6362 public String getPackageForToken(IBinder token) { 6363 synchronized(this) { 6364 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6365 if (r == null) { 6366 return null; 6367 } 6368 return r.packageName; 6369 } 6370 } 6371 6372 @Override 6373 public IIntentSender getIntentSender(int type, 6374 String packageName, IBinder token, String resultWho, 6375 int requestCode, Intent[] intents, String[] resolvedTypes, 6376 int flags, Bundle options, int userId) { 6377 enforceNotIsolatedCaller("getIntentSender"); 6378 // Refuse possible leaked file descriptors 6379 if (intents != null) { 6380 if (intents.length < 1) { 6381 throw new IllegalArgumentException("Intents array length must be >= 1"); 6382 } 6383 for (int i=0; i<intents.length; i++) { 6384 Intent intent = intents[i]; 6385 if (intent != null) { 6386 if (intent.hasFileDescriptors()) { 6387 throw new IllegalArgumentException("File descriptors passed in Intent"); 6388 } 6389 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6390 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6391 throw new IllegalArgumentException( 6392 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6393 } 6394 intents[i] = new Intent(intent); 6395 } 6396 } 6397 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6398 throw new IllegalArgumentException( 6399 "Intent array length does not match resolvedTypes length"); 6400 } 6401 } 6402 if (options != null) { 6403 if (options.hasFileDescriptors()) { 6404 throw new IllegalArgumentException("File descriptors passed in options"); 6405 } 6406 } 6407 6408 synchronized(this) { 6409 int callingUid = Binder.getCallingUid(); 6410 int origUserId = userId; 6411 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6412 type == ActivityManager.INTENT_SENDER_BROADCAST, 6413 ALLOW_NON_FULL, "getIntentSender", null); 6414 if (origUserId == UserHandle.USER_CURRENT) { 6415 // We don't want to evaluate this until the pending intent is 6416 // actually executed. However, we do want to always do the 6417 // security checking for it above. 6418 userId = UserHandle.USER_CURRENT; 6419 } 6420 try { 6421 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6422 int uid = AppGlobals.getPackageManager() 6423 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6424 if (!UserHandle.isSameApp(callingUid, uid)) { 6425 String msg = "Permission Denial: getIntentSender() from pid=" 6426 + Binder.getCallingPid() 6427 + ", uid=" + Binder.getCallingUid() 6428 + ", (need uid=" + uid + ")" 6429 + " is not allowed to send as package " + packageName; 6430 Slog.w(TAG, msg); 6431 throw new SecurityException(msg); 6432 } 6433 } 6434 6435 return getIntentSenderLocked(type, packageName, callingUid, userId, 6436 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6437 6438 } catch (RemoteException e) { 6439 throw new SecurityException(e); 6440 } 6441 } 6442 } 6443 6444 IIntentSender getIntentSenderLocked(int type, String packageName, 6445 int callingUid, int userId, IBinder token, String resultWho, 6446 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6447 Bundle options) { 6448 if (DEBUG_MU) 6449 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6450 ActivityRecord activity = null; 6451 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6452 activity = ActivityRecord.isInStackLocked(token); 6453 if (activity == null) { 6454 return null; 6455 } 6456 if (activity.finishing) { 6457 return null; 6458 } 6459 } 6460 6461 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6462 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6463 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6464 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6465 |PendingIntent.FLAG_UPDATE_CURRENT); 6466 6467 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6468 type, packageName, activity, resultWho, 6469 requestCode, intents, resolvedTypes, flags, options, userId); 6470 WeakReference<PendingIntentRecord> ref; 6471 ref = mIntentSenderRecords.get(key); 6472 PendingIntentRecord rec = ref != null ? ref.get() : null; 6473 if (rec != null) { 6474 if (!cancelCurrent) { 6475 if (updateCurrent) { 6476 if (rec.key.requestIntent != null) { 6477 rec.key.requestIntent.replaceExtras(intents != null ? 6478 intents[intents.length - 1] : null); 6479 } 6480 if (intents != null) { 6481 intents[intents.length-1] = rec.key.requestIntent; 6482 rec.key.allIntents = intents; 6483 rec.key.allResolvedTypes = resolvedTypes; 6484 } else { 6485 rec.key.allIntents = null; 6486 rec.key.allResolvedTypes = null; 6487 } 6488 } 6489 return rec; 6490 } 6491 rec.canceled = true; 6492 mIntentSenderRecords.remove(key); 6493 } 6494 if (noCreate) { 6495 return rec; 6496 } 6497 rec = new PendingIntentRecord(this, key, callingUid); 6498 mIntentSenderRecords.put(key, rec.ref); 6499 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6500 if (activity.pendingResults == null) { 6501 activity.pendingResults 6502 = new HashSet<WeakReference<PendingIntentRecord>>(); 6503 } 6504 activity.pendingResults.add(rec.ref); 6505 } 6506 return rec; 6507 } 6508 6509 @Override 6510 public void cancelIntentSender(IIntentSender sender) { 6511 if (!(sender instanceof PendingIntentRecord)) { 6512 return; 6513 } 6514 synchronized(this) { 6515 PendingIntentRecord rec = (PendingIntentRecord)sender; 6516 try { 6517 int uid = AppGlobals.getPackageManager() 6518 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6519 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6520 String msg = "Permission Denial: cancelIntentSender() from pid=" 6521 + Binder.getCallingPid() 6522 + ", uid=" + Binder.getCallingUid() 6523 + " is not allowed to cancel packges " 6524 + rec.key.packageName; 6525 Slog.w(TAG, msg); 6526 throw new SecurityException(msg); 6527 } 6528 } catch (RemoteException e) { 6529 throw new SecurityException(e); 6530 } 6531 cancelIntentSenderLocked(rec, true); 6532 } 6533 } 6534 6535 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6536 rec.canceled = true; 6537 mIntentSenderRecords.remove(rec.key); 6538 if (cleanActivity && rec.key.activity != null) { 6539 rec.key.activity.pendingResults.remove(rec.ref); 6540 } 6541 } 6542 6543 @Override 6544 public String getPackageForIntentSender(IIntentSender pendingResult) { 6545 if (!(pendingResult instanceof PendingIntentRecord)) { 6546 return null; 6547 } 6548 try { 6549 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6550 return res.key.packageName; 6551 } catch (ClassCastException e) { 6552 } 6553 return null; 6554 } 6555 6556 @Override 6557 public int getUidForIntentSender(IIntentSender sender) { 6558 if (sender instanceof PendingIntentRecord) { 6559 try { 6560 PendingIntentRecord res = (PendingIntentRecord)sender; 6561 return res.uid; 6562 } catch (ClassCastException e) { 6563 } 6564 } 6565 return -1; 6566 } 6567 6568 @Override 6569 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6570 if (!(pendingResult instanceof PendingIntentRecord)) { 6571 return false; 6572 } 6573 try { 6574 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6575 if (res.key.allIntents == null) { 6576 return false; 6577 } 6578 for (int i=0; i<res.key.allIntents.length; i++) { 6579 Intent intent = res.key.allIntents[i]; 6580 if (intent.getPackage() != null && intent.getComponent() != null) { 6581 return false; 6582 } 6583 } 6584 return true; 6585 } catch (ClassCastException e) { 6586 } 6587 return false; 6588 } 6589 6590 @Override 6591 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6592 if (!(pendingResult instanceof PendingIntentRecord)) { 6593 return false; 6594 } 6595 try { 6596 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6597 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6598 return true; 6599 } 6600 return false; 6601 } catch (ClassCastException e) { 6602 } 6603 return false; 6604 } 6605 6606 @Override 6607 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6608 if (!(pendingResult instanceof PendingIntentRecord)) { 6609 return null; 6610 } 6611 try { 6612 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6613 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6614 } catch (ClassCastException e) { 6615 } 6616 return null; 6617 } 6618 6619 @Override 6620 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6621 if (!(pendingResult instanceof PendingIntentRecord)) { 6622 return null; 6623 } 6624 try { 6625 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6626 Intent intent = res.key.requestIntent; 6627 if (intent != null) { 6628 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6629 || res.lastTagPrefix.equals(prefix))) { 6630 return res.lastTag; 6631 } 6632 res.lastTagPrefix = prefix; 6633 StringBuilder sb = new StringBuilder(128); 6634 if (prefix != null) { 6635 sb.append(prefix); 6636 } 6637 if (intent.getAction() != null) { 6638 sb.append(intent.getAction()); 6639 } else if (intent.getComponent() != null) { 6640 intent.getComponent().appendShortString(sb); 6641 } else { 6642 sb.append("?"); 6643 } 6644 return res.lastTag = sb.toString(); 6645 } 6646 } catch (ClassCastException e) { 6647 } 6648 return null; 6649 } 6650 6651 @Override 6652 public void setProcessLimit(int max) { 6653 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6654 "setProcessLimit()"); 6655 synchronized (this) { 6656 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6657 mProcessLimitOverride = max; 6658 } 6659 trimApplications(); 6660 } 6661 6662 @Override 6663 public int getProcessLimit() { 6664 synchronized (this) { 6665 return mProcessLimitOverride; 6666 } 6667 } 6668 6669 void foregroundTokenDied(ForegroundToken token) { 6670 synchronized (ActivityManagerService.this) { 6671 synchronized (mPidsSelfLocked) { 6672 ForegroundToken cur 6673 = mForegroundProcesses.get(token.pid); 6674 if (cur != token) { 6675 return; 6676 } 6677 mForegroundProcesses.remove(token.pid); 6678 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6679 if (pr == null) { 6680 return; 6681 } 6682 pr.forcingToForeground = null; 6683 updateProcessForegroundLocked(pr, false, false); 6684 } 6685 updateOomAdjLocked(); 6686 } 6687 } 6688 6689 @Override 6690 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6691 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6692 "setProcessForeground()"); 6693 synchronized(this) { 6694 boolean changed = false; 6695 6696 synchronized (mPidsSelfLocked) { 6697 ProcessRecord pr = mPidsSelfLocked.get(pid); 6698 if (pr == null && isForeground) { 6699 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6700 return; 6701 } 6702 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6703 if (oldToken != null) { 6704 oldToken.token.unlinkToDeath(oldToken, 0); 6705 mForegroundProcesses.remove(pid); 6706 if (pr != null) { 6707 pr.forcingToForeground = null; 6708 } 6709 changed = true; 6710 } 6711 if (isForeground && token != null) { 6712 ForegroundToken newToken = new ForegroundToken() { 6713 @Override 6714 public void binderDied() { 6715 foregroundTokenDied(this); 6716 } 6717 }; 6718 newToken.pid = pid; 6719 newToken.token = token; 6720 try { 6721 token.linkToDeath(newToken, 0); 6722 mForegroundProcesses.put(pid, newToken); 6723 pr.forcingToForeground = token; 6724 changed = true; 6725 } catch (RemoteException e) { 6726 // If the process died while doing this, we will later 6727 // do the cleanup with the process death link. 6728 } 6729 } 6730 } 6731 6732 if (changed) { 6733 updateOomAdjLocked(); 6734 } 6735 } 6736 } 6737 6738 // ========================================================= 6739 // PERMISSIONS 6740 // ========================================================= 6741 6742 static class PermissionController extends IPermissionController.Stub { 6743 ActivityManagerService mActivityManagerService; 6744 PermissionController(ActivityManagerService activityManagerService) { 6745 mActivityManagerService = activityManagerService; 6746 } 6747 6748 @Override 6749 public boolean checkPermission(String permission, int pid, int uid) { 6750 return mActivityManagerService.checkPermission(permission, pid, 6751 uid) == PackageManager.PERMISSION_GRANTED; 6752 } 6753 } 6754 6755 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6756 @Override 6757 public int checkComponentPermission(String permission, int pid, int uid, 6758 int owningUid, boolean exported) { 6759 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6760 owningUid, exported); 6761 } 6762 6763 @Override 6764 public Object getAMSLock() { 6765 return ActivityManagerService.this; 6766 } 6767 } 6768 6769 /** 6770 * This can be called with or without the global lock held. 6771 */ 6772 int checkComponentPermission(String permission, int pid, int uid, 6773 int owningUid, boolean exported) { 6774 if (pid == MY_PID) { 6775 return PackageManager.PERMISSION_GRANTED; 6776 } 6777 return ActivityManager.checkComponentPermission(permission, uid, 6778 owningUid, exported); 6779 } 6780 6781 /** 6782 * As the only public entry point for permissions checking, this method 6783 * can enforce the semantic that requesting a check on a null global 6784 * permission is automatically denied. (Internally a null permission 6785 * string is used when calling {@link #checkComponentPermission} in cases 6786 * when only uid-based security is needed.) 6787 * 6788 * This can be called with or without the global lock held. 6789 */ 6790 @Override 6791 public int checkPermission(String permission, int pid, int uid) { 6792 if (permission == null) { 6793 return PackageManager.PERMISSION_DENIED; 6794 } 6795 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6796 } 6797 6798 @Override 6799 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6800 if (permission == null) { 6801 return PackageManager.PERMISSION_DENIED; 6802 } 6803 6804 // We might be performing an operation on behalf of an indirect binder 6805 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6806 // client identity accordingly before proceeding. 6807 Identity tlsIdentity = sCallerIdentity.get(); 6808 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6809 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6810 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6811 uid = tlsIdentity.uid; 6812 pid = tlsIdentity.pid; 6813 } 6814 6815 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6816 } 6817 6818 /** 6819 * Binder IPC calls go through the public entry point. 6820 * This can be called with or without the global lock held. 6821 */ 6822 int checkCallingPermission(String permission) { 6823 return checkPermission(permission, 6824 Binder.getCallingPid(), 6825 UserHandle.getAppId(Binder.getCallingUid())); 6826 } 6827 6828 /** 6829 * This can be called with or without the global lock held. 6830 */ 6831 void enforceCallingPermission(String permission, String func) { 6832 if (checkCallingPermission(permission) 6833 == PackageManager.PERMISSION_GRANTED) { 6834 return; 6835 } 6836 6837 String msg = "Permission Denial: " + func + " from pid=" 6838 + Binder.getCallingPid() 6839 + ", uid=" + Binder.getCallingUid() 6840 + " requires " + permission; 6841 Slog.w(TAG, msg); 6842 throw new SecurityException(msg); 6843 } 6844 6845 /** 6846 * Determine if UID is holding permissions required to access {@link Uri} in 6847 * the given {@link ProviderInfo}. Final permission checking is always done 6848 * in {@link ContentProvider}. 6849 */ 6850 private final boolean checkHoldingPermissionsLocked( 6851 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6852 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6853 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6854 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6855 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6856 != PERMISSION_GRANTED) { 6857 return false; 6858 } 6859 } 6860 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6861 } 6862 6863 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6864 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6865 if (pi.applicationInfo.uid == uid) { 6866 return true; 6867 } else if (!pi.exported) { 6868 return false; 6869 } 6870 6871 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6872 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6873 try { 6874 // check if target holds top-level <provider> permissions 6875 if (!readMet && pi.readPermission != null && considerUidPermissions 6876 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6877 readMet = true; 6878 } 6879 if (!writeMet && pi.writePermission != null && considerUidPermissions 6880 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6881 writeMet = true; 6882 } 6883 6884 // track if unprotected read/write is allowed; any denied 6885 // <path-permission> below removes this ability 6886 boolean allowDefaultRead = pi.readPermission == null; 6887 boolean allowDefaultWrite = pi.writePermission == null; 6888 6889 // check if target holds any <path-permission> that match uri 6890 final PathPermission[] pps = pi.pathPermissions; 6891 if (pps != null) { 6892 final String path = grantUri.uri.getPath(); 6893 int i = pps.length; 6894 while (i > 0 && (!readMet || !writeMet)) { 6895 i--; 6896 PathPermission pp = pps[i]; 6897 if (pp.match(path)) { 6898 if (!readMet) { 6899 final String pprperm = pp.getReadPermission(); 6900 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6901 + pprperm + " for " + pp.getPath() 6902 + ": match=" + pp.match(path) 6903 + " check=" + pm.checkUidPermission(pprperm, uid)); 6904 if (pprperm != null) { 6905 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6906 == PERMISSION_GRANTED) { 6907 readMet = true; 6908 } else { 6909 allowDefaultRead = false; 6910 } 6911 } 6912 } 6913 if (!writeMet) { 6914 final String ppwperm = pp.getWritePermission(); 6915 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6916 + ppwperm + " for " + pp.getPath() 6917 + ": match=" + pp.match(path) 6918 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6919 if (ppwperm != null) { 6920 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6921 == PERMISSION_GRANTED) { 6922 writeMet = true; 6923 } else { 6924 allowDefaultWrite = false; 6925 } 6926 } 6927 } 6928 } 6929 } 6930 } 6931 6932 // grant unprotected <provider> read/write, if not blocked by 6933 // <path-permission> above 6934 if (allowDefaultRead) readMet = true; 6935 if (allowDefaultWrite) writeMet = true; 6936 6937 } catch (RemoteException e) { 6938 return false; 6939 } 6940 6941 return readMet && writeMet; 6942 } 6943 6944 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6945 ProviderInfo pi = null; 6946 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6947 if (cpr != null) { 6948 pi = cpr.info; 6949 } else { 6950 try { 6951 pi = AppGlobals.getPackageManager().resolveContentProvider( 6952 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6953 } catch (RemoteException ex) { 6954 } 6955 } 6956 return pi; 6957 } 6958 6959 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6960 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6961 if (targetUris != null) { 6962 return targetUris.get(grantUri); 6963 } 6964 return null; 6965 } 6966 6967 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6968 String targetPkg, int targetUid, GrantUri grantUri) { 6969 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6970 if (targetUris == null) { 6971 targetUris = Maps.newArrayMap(); 6972 mGrantedUriPermissions.put(targetUid, targetUris); 6973 } 6974 6975 UriPermission perm = targetUris.get(grantUri); 6976 if (perm == null) { 6977 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6978 targetUris.put(grantUri, perm); 6979 } 6980 6981 return perm; 6982 } 6983 6984 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6985 final int modeFlags) { 6986 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6987 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6988 : UriPermission.STRENGTH_OWNED; 6989 6990 // Root gets to do everything. 6991 if (uid == 0) { 6992 return true; 6993 } 6994 6995 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6996 if (perms == null) return false; 6997 6998 // First look for exact match 6999 final UriPermission exactPerm = perms.get(grantUri); 7000 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7001 return true; 7002 } 7003 7004 // No exact match, look for prefixes 7005 final int N = perms.size(); 7006 for (int i = 0; i < N; i++) { 7007 final UriPermission perm = perms.valueAt(i); 7008 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7009 && perm.getStrength(modeFlags) >= minStrength) { 7010 return true; 7011 } 7012 } 7013 7014 return false; 7015 } 7016 7017 /** 7018 * @param uri This uri must NOT contain an embedded userId. 7019 * @param userId The userId in which the uri is to be resolved. 7020 */ 7021 @Override 7022 public int checkUriPermission(Uri uri, int pid, int uid, 7023 final int modeFlags, int userId, IBinder callerToken) { 7024 enforceNotIsolatedCaller("checkUriPermission"); 7025 7026 // Another redirected-binder-call permissions check as in 7027 // {@link checkPermissionWithToken}. 7028 Identity tlsIdentity = sCallerIdentity.get(); 7029 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7030 uid = tlsIdentity.uid; 7031 pid = tlsIdentity.pid; 7032 } 7033 7034 // Our own process gets to do everything. 7035 if (pid == MY_PID) { 7036 return PackageManager.PERMISSION_GRANTED; 7037 } 7038 synchronized (this) { 7039 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7040 ? PackageManager.PERMISSION_GRANTED 7041 : PackageManager.PERMISSION_DENIED; 7042 } 7043 } 7044 7045 /** 7046 * Check if the targetPkg can be granted permission to access uri by 7047 * the callingUid using the given modeFlags. Throws a security exception 7048 * if callingUid is not allowed to do this. Returns the uid of the target 7049 * if the URI permission grant should be performed; returns -1 if it is not 7050 * needed (for example targetPkg already has permission to access the URI). 7051 * If you already know the uid of the target, you can supply it in 7052 * lastTargetUid else set that to -1. 7053 */ 7054 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7055 final int modeFlags, int lastTargetUid) { 7056 if (!Intent.isAccessUriMode(modeFlags)) { 7057 return -1; 7058 } 7059 7060 if (targetPkg != null) { 7061 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7062 "Checking grant " + targetPkg + " permission to " + grantUri); 7063 } 7064 7065 final IPackageManager pm = AppGlobals.getPackageManager(); 7066 7067 // If this is not a content: uri, we can't do anything with it. 7068 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7069 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7070 "Can't grant URI permission for non-content URI: " + grantUri); 7071 return -1; 7072 } 7073 7074 final String authority = grantUri.uri.getAuthority(); 7075 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7076 if (pi == null) { 7077 Slog.w(TAG, "No content provider found for permission check: " + 7078 grantUri.uri.toSafeString()); 7079 return -1; 7080 } 7081 7082 int targetUid = lastTargetUid; 7083 if (targetUid < 0 && targetPkg != null) { 7084 try { 7085 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7086 if (targetUid < 0) { 7087 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7088 "Can't grant URI permission no uid for: " + targetPkg); 7089 return -1; 7090 } 7091 } catch (RemoteException ex) { 7092 return -1; 7093 } 7094 } 7095 7096 if (targetUid >= 0) { 7097 // First... does the target actually need this permission? 7098 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7099 // No need to grant the target this permission. 7100 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7101 "Target " + targetPkg + " already has full permission to " + grantUri); 7102 return -1; 7103 } 7104 } else { 7105 // First... there is no target package, so can anyone access it? 7106 boolean allowed = pi.exported; 7107 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7108 if (pi.readPermission != null) { 7109 allowed = false; 7110 } 7111 } 7112 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7113 if (pi.writePermission != null) { 7114 allowed = false; 7115 } 7116 } 7117 if (allowed) { 7118 return -1; 7119 } 7120 } 7121 7122 /* There is a special cross user grant if: 7123 * - The target is on another user. 7124 * - Apps on the current user can access the uri without any uid permissions. 7125 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7126 * grant uri permissions. 7127 */ 7128 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7129 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7130 modeFlags, false /*without considering the uid permissions*/); 7131 7132 // Second... is the provider allowing granting of URI permissions? 7133 if (!specialCrossUserGrant) { 7134 if (!pi.grantUriPermissions) { 7135 throw new SecurityException("Provider " + pi.packageName 7136 + "/" + pi.name 7137 + " does not allow granting of Uri permissions (uri " 7138 + grantUri + ")"); 7139 } 7140 if (pi.uriPermissionPatterns != null) { 7141 final int N = pi.uriPermissionPatterns.length; 7142 boolean allowed = false; 7143 for (int i=0; i<N; i++) { 7144 if (pi.uriPermissionPatterns[i] != null 7145 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7146 allowed = true; 7147 break; 7148 } 7149 } 7150 if (!allowed) { 7151 throw new SecurityException("Provider " + pi.packageName 7152 + "/" + pi.name 7153 + " does not allow granting of permission to path of Uri " 7154 + grantUri); 7155 } 7156 } 7157 } 7158 7159 // Third... does the caller itself have permission to access 7160 // this uri? 7161 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7162 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7163 // Require they hold a strong enough Uri permission 7164 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7165 throw new SecurityException("Uid " + callingUid 7166 + " does not have permission to uri " + grantUri); 7167 } 7168 } 7169 } 7170 return targetUid; 7171 } 7172 7173 /** 7174 * @param uri This uri must NOT contain an embedded userId. 7175 * @param userId The userId in which the uri is to be resolved. 7176 */ 7177 @Override 7178 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7179 final int modeFlags, int userId) { 7180 enforceNotIsolatedCaller("checkGrantUriPermission"); 7181 synchronized(this) { 7182 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7183 new GrantUri(userId, uri, false), modeFlags, -1); 7184 } 7185 } 7186 7187 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7188 final int modeFlags, UriPermissionOwner owner) { 7189 if (!Intent.isAccessUriMode(modeFlags)) { 7190 return; 7191 } 7192 7193 // So here we are: the caller has the assumed permission 7194 // to the uri, and the target doesn't. Let's now give this to 7195 // the target. 7196 7197 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7198 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7199 7200 final String authority = grantUri.uri.getAuthority(); 7201 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7202 if (pi == null) { 7203 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7204 return; 7205 } 7206 7207 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7208 grantUri.prefix = true; 7209 } 7210 final UriPermission perm = findOrCreateUriPermissionLocked( 7211 pi.packageName, targetPkg, targetUid, grantUri); 7212 perm.grantModes(modeFlags, owner); 7213 } 7214 7215 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7216 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7217 if (targetPkg == null) { 7218 throw new NullPointerException("targetPkg"); 7219 } 7220 int targetUid; 7221 final IPackageManager pm = AppGlobals.getPackageManager(); 7222 try { 7223 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7224 } catch (RemoteException ex) { 7225 return; 7226 } 7227 7228 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7229 targetUid); 7230 if (targetUid < 0) { 7231 return; 7232 } 7233 7234 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7235 owner); 7236 } 7237 7238 static class NeededUriGrants extends ArrayList<GrantUri> { 7239 final String targetPkg; 7240 final int targetUid; 7241 final int flags; 7242 7243 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7244 this.targetPkg = targetPkg; 7245 this.targetUid = targetUid; 7246 this.flags = flags; 7247 } 7248 } 7249 7250 /** 7251 * Like checkGrantUriPermissionLocked, but takes an Intent. 7252 */ 7253 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7254 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7255 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7256 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7257 + " clip=" + (intent != null ? intent.getClipData() : null) 7258 + " from " + intent + "; flags=0x" 7259 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7260 7261 if (targetPkg == null) { 7262 throw new NullPointerException("targetPkg"); 7263 } 7264 7265 if (intent == null) { 7266 return null; 7267 } 7268 Uri data = intent.getData(); 7269 ClipData clip = intent.getClipData(); 7270 if (data == null && clip == null) { 7271 return null; 7272 } 7273 // Default userId for uris in the intent (if they don't specify it themselves) 7274 int contentUserHint = intent.getContentUserHint(); 7275 if (contentUserHint == UserHandle.USER_CURRENT) { 7276 contentUserHint = UserHandle.getUserId(callingUid); 7277 } 7278 final IPackageManager pm = AppGlobals.getPackageManager(); 7279 int targetUid; 7280 if (needed != null) { 7281 targetUid = needed.targetUid; 7282 } else { 7283 try { 7284 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7285 } catch (RemoteException ex) { 7286 return null; 7287 } 7288 if (targetUid < 0) { 7289 if (DEBUG_URI_PERMISSION) { 7290 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7291 + " on user " + targetUserId); 7292 } 7293 return null; 7294 } 7295 } 7296 if (data != null) { 7297 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7298 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7299 targetUid); 7300 if (targetUid > 0) { 7301 if (needed == null) { 7302 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7303 } 7304 needed.add(grantUri); 7305 } 7306 } 7307 if (clip != null) { 7308 for (int i=0; i<clip.getItemCount(); i++) { 7309 Uri uri = clip.getItemAt(i).getUri(); 7310 if (uri != null) { 7311 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7312 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7313 targetUid); 7314 if (targetUid > 0) { 7315 if (needed == null) { 7316 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7317 } 7318 needed.add(grantUri); 7319 } 7320 } else { 7321 Intent clipIntent = clip.getItemAt(i).getIntent(); 7322 if (clipIntent != null) { 7323 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7324 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7325 if (newNeeded != null) { 7326 needed = newNeeded; 7327 } 7328 } 7329 } 7330 } 7331 } 7332 7333 return needed; 7334 } 7335 7336 /** 7337 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7338 */ 7339 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7340 UriPermissionOwner owner) { 7341 if (needed != null) { 7342 for (int i=0; i<needed.size(); i++) { 7343 GrantUri grantUri = needed.get(i); 7344 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7345 grantUri, needed.flags, owner); 7346 } 7347 } 7348 } 7349 7350 void grantUriPermissionFromIntentLocked(int callingUid, 7351 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7352 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7353 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7354 if (needed == null) { 7355 return; 7356 } 7357 7358 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7359 } 7360 7361 /** 7362 * @param uri This uri must NOT contain an embedded userId. 7363 * @param userId The userId in which the uri is to be resolved. 7364 */ 7365 @Override 7366 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7367 final int modeFlags, int userId) { 7368 enforceNotIsolatedCaller("grantUriPermission"); 7369 GrantUri grantUri = new GrantUri(userId, uri, false); 7370 synchronized(this) { 7371 final ProcessRecord r = getRecordForAppLocked(caller); 7372 if (r == null) { 7373 throw new SecurityException("Unable to find app for caller " 7374 + caller 7375 + " when granting permission to uri " + grantUri); 7376 } 7377 if (targetPkg == null) { 7378 throw new IllegalArgumentException("null target"); 7379 } 7380 if (grantUri == null) { 7381 throw new IllegalArgumentException("null uri"); 7382 } 7383 7384 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7385 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7386 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7387 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7388 7389 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7390 UserHandle.getUserId(r.uid)); 7391 } 7392 } 7393 7394 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7395 if (perm.modeFlags == 0) { 7396 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7397 perm.targetUid); 7398 if (perms != null) { 7399 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7400 "Removing " + perm.targetUid + " permission to " + perm.uri); 7401 7402 perms.remove(perm.uri); 7403 if (perms.isEmpty()) { 7404 mGrantedUriPermissions.remove(perm.targetUid); 7405 } 7406 } 7407 } 7408 } 7409 7410 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7411 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7412 7413 final IPackageManager pm = AppGlobals.getPackageManager(); 7414 final String authority = grantUri.uri.getAuthority(); 7415 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7416 if (pi == null) { 7417 Slog.w(TAG, "No content provider found for permission revoke: " 7418 + grantUri.toSafeString()); 7419 return; 7420 } 7421 7422 // Does the caller have this permission on the URI? 7423 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7424 // If they don't have direct access to the URI, then revoke any 7425 // ownerless URI permissions that have been granted to them. 7426 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7427 if (perms != null) { 7428 boolean persistChanged = false; 7429 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7430 final UriPermission perm = it.next(); 7431 if (perm.uri.sourceUserId == grantUri.sourceUserId 7432 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7433 if (DEBUG_URI_PERMISSION) 7434 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7435 " permission to " + perm.uri); 7436 persistChanged |= perm.revokeModes( 7437 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7438 if (perm.modeFlags == 0) { 7439 it.remove(); 7440 } 7441 } 7442 } 7443 if (perms.isEmpty()) { 7444 mGrantedUriPermissions.remove(callingUid); 7445 } 7446 if (persistChanged) { 7447 schedulePersistUriGrants(); 7448 } 7449 } 7450 return; 7451 } 7452 7453 boolean persistChanged = false; 7454 7455 // Go through all of the permissions and remove any that match. 7456 int N = mGrantedUriPermissions.size(); 7457 for (int i = 0; i < N; i++) { 7458 final int targetUid = mGrantedUriPermissions.keyAt(i); 7459 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7460 7461 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7462 final UriPermission perm = it.next(); 7463 if (perm.uri.sourceUserId == grantUri.sourceUserId 7464 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7465 if (DEBUG_URI_PERMISSION) 7466 Slog.v(TAG, 7467 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7468 persistChanged |= perm.revokeModes( 7469 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7470 if (perm.modeFlags == 0) { 7471 it.remove(); 7472 } 7473 } 7474 } 7475 7476 if (perms.isEmpty()) { 7477 mGrantedUriPermissions.remove(targetUid); 7478 N--; 7479 i--; 7480 } 7481 } 7482 7483 if (persistChanged) { 7484 schedulePersistUriGrants(); 7485 } 7486 } 7487 7488 /** 7489 * @param uri This uri must NOT contain an embedded userId. 7490 * @param userId The userId in which the uri is to be resolved. 7491 */ 7492 @Override 7493 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7494 int userId) { 7495 enforceNotIsolatedCaller("revokeUriPermission"); 7496 synchronized(this) { 7497 final ProcessRecord r = getRecordForAppLocked(caller); 7498 if (r == null) { 7499 throw new SecurityException("Unable to find app for caller " 7500 + caller 7501 + " when revoking permission to uri " + uri); 7502 } 7503 if (uri == null) { 7504 Slog.w(TAG, "revokeUriPermission: null uri"); 7505 return; 7506 } 7507 7508 if (!Intent.isAccessUriMode(modeFlags)) { 7509 return; 7510 } 7511 7512 final IPackageManager pm = AppGlobals.getPackageManager(); 7513 final String authority = uri.getAuthority(); 7514 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7515 if (pi == null) { 7516 Slog.w(TAG, "No content provider found for permission revoke: " 7517 + uri.toSafeString()); 7518 return; 7519 } 7520 7521 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7522 } 7523 } 7524 7525 /** 7526 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7527 * given package. 7528 * 7529 * @param packageName Package name to match, or {@code null} to apply to all 7530 * packages. 7531 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7532 * to all users. 7533 * @param persistable If persistable grants should be removed. 7534 */ 7535 private void removeUriPermissionsForPackageLocked( 7536 String packageName, int userHandle, boolean persistable) { 7537 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7538 throw new IllegalArgumentException("Must narrow by either package or user"); 7539 } 7540 7541 boolean persistChanged = false; 7542 7543 int N = mGrantedUriPermissions.size(); 7544 for (int i = 0; i < N; i++) { 7545 final int targetUid = mGrantedUriPermissions.keyAt(i); 7546 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7547 7548 // Only inspect grants matching user 7549 if (userHandle == UserHandle.USER_ALL 7550 || userHandle == UserHandle.getUserId(targetUid)) { 7551 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7552 final UriPermission perm = it.next(); 7553 7554 // Only inspect grants matching package 7555 if (packageName == null || perm.sourcePkg.equals(packageName) 7556 || perm.targetPkg.equals(packageName)) { 7557 persistChanged |= perm.revokeModes(persistable 7558 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7559 7560 // Only remove when no modes remain; any persisted grants 7561 // will keep this alive. 7562 if (perm.modeFlags == 0) { 7563 it.remove(); 7564 } 7565 } 7566 } 7567 7568 if (perms.isEmpty()) { 7569 mGrantedUriPermissions.remove(targetUid); 7570 N--; 7571 i--; 7572 } 7573 } 7574 } 7575 7576 if (persistChanged) { 7577 schedulePersistUriGrants(); 7578 } 7579 } 7580 7581 @Override 7582 public IBinder newUriPermissionOwner(String name) { 7583 enforceNotIsolatedCaller("newUriPermissionOwner"); 7584 synchronized(this) { 7585 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7586 return owner.getExternalTokenLocked(); 7587 } 7588 } 7589 7590 /** 7591 * @param uri This uri must NOT contain an embedded userId. 7592 * @param sourceUserId The userId in which the uri is to be resolved. 7593 * @param targetUserId The userId of the app that receives the grant. 7594 */ 7595 @Override 7596 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7597 final int modeFlags, int sourceUserId, int targetUserId) { 7598 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7599 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7600 synchronized(this) { 7601 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7602 if (owner == null) { 7603 throw new IllegalArgumentException("Unknown owner: " + token); 7604 } 7605 if (fromUid != Binder.getCallingUid()) { 7606 if (Binder.getCallingUid() != Process.myUid()) { 7607 // Only system code can grant URI permissions on behalf 7608 // of other users. 7609 throw new SecurityException("nice try"); 7610 } 7611 } 7612 if (targetPkg == null) { 7613 throw new IllegalArgumentException("null target"); 7614 } 7615 if (uri == null) { 7616 throw new IllegalArgumentException("null uri"); 7617 } 7618 7619 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7620 modeFlags, owner, targetUserId); 7621 } 7622 } 7623 7624 /** 7625 * @param uri This uri must NOT contain an embedded userId. 7626 * @param userId The userId in which the uri is to be resolved. 7627 */ 7628 @Override 7629 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7630 synchronized(this) { 7631 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7632 if (owner == null) { 7633 throw new IllegalArgumentException("Unknown owner: " + token); 7634 } 7635 7636 if (uri == null) { 7637 owner.removeUriPermissionsLocked(mode); 7638 } else { 7639 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7640 } 7641 } 7642 } 7643 7644 private void schedulePersistUriGrants() { 7645 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7646 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7647 10 * DateUtils.SECOND_IN_MILLIS); 7648 } 7649 } 7650 7651 private void writeGrantedUriPermissions() { 7652 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7653 7654 // Snapshot permissions so we can persist without lock 7655 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7656 synchronized (this) { 7657 final int size = mGrantedUriPermissions.size(); 7658 for (int i = 0; i < size; i++) { 7659 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7660 for (UriPermission perm : perms.values()) { 7661 if (perm.persistedModeFlags != 0) { 7662 persist.add(perm.snapshot()); 7663 } 7664 } 7665 } 7666 } 7667 7668 FileOutputStream fos = null; 7669 try { 7670 fos = mGrantFile.startWrite(); 7671 7672 XmlSerializer out = new FastXmlSerializer(); 7673 out.setOutput(fos, "utf-8"); 7674 out.startDocument(null, true); 7675 out.startTag(null, TAG_URI_GRANTS); 7676 for (UriPermission.Snapshot perm : persist) { 7677 out.startTag(null, TAG_URI_GRANT); 7678 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7679 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7680 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7681 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7682 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7683 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7684 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7685 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7686 out.endTag(null, TAG_URI_GRANT); 7687 } 7688 out.endTag(null, TAG_URI_GRANTS); 7689 out.endDocument(); 7690 7691 mGrantFile.finishWrite(fos); 7692 } catch (IOException e) { 7693 if (fos != null) { 7694 mGrantFile.failWrite(fos); 7695 } 7696 } 7697 } 7698 7699 private void readGrantedUriPermissionsLocked() { 7700 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7701 7702 final long now = System.currentTimeMillis(); 7703 7704 FileInputStream fis = null; 7705 try { 7706 fis = mGrantFile.openRead(); 7707 final XmlPullParser in = Xml.newPullParser(); 7708 in.setInput(fis, null); 7709 7710 int type; 7711 while ((type = in.next()) != END_DOCUMENT) { 7712 final String tag = in.getName(); 7713 if (type == START_TAG) { 7714 if (TAG_URI_GRANT.equals(tag)) { 7715 final int sourceUserId; 7716 final int targetUserId; 7717 final int userHandle = readIntAttribute(in, 7718 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7719 if (userHandle != UserHandle.USER_NULL) { 7720 // For backwards compatibility. 7721 sourceUserId = userHandle; 7722 targetUserId = userHandle; 7723 } else { 7724 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7725 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7726 } 7727 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7728 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7729 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7730 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7731 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7732 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7733 7734 // Sanity check that provider still belongs to source package 7735 final ProviderInfo pi = getProviderInfoLocked( 7736 uri.getAuthority(), sourceUserId); 7737 if (pi != null && sourcePkg.equals(pi.packageName)) { 7738 int targetUid = -1; 7739 try { 7740 targetUid = AppGlobals.getPackageManager() 7741 .getPackageUid(targetPkg, targetUserId); 7742 } catch (RemoteException e) { 7743 } 7744 if (targetUid != -1) { 7745 final UriPermission perm = findOrCreateUriPermissionLocked( 7746 sourcePkg, targetPkg, targetUid, 7747 new GrantUri(sourceUserId, uri, prefix)); 7748 perm.initPersistedModes(modeFlags, createdTime); 7749 } 7750 } else { 7751 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7752 + " but instead found " + pi); 7753 } 7754 } 7755 } 7756 } 7757 } catch (FileNotFoundException e) { 7758 // Missing grants is okay 7759 } catch (IOException e) { 7760 Slog.wtf(TAG, "Failed reading Uri grants", e); 7761 } catch (XmlPullParserException e) { 7762 Slog.wtf(TAG, "Failed reading Uri grants", e); 7763 } finally { 7764 IoUtils.closeQuietly(fis); 7765 } 7766 } 7767 7768 /** 7769 * @param uri This uri must NOT contain an embedded userId. 7770 * @param userId The userId in which the uri is to be resolved. 7771 */ 7772 @Override 7773 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7774 enforceNotIsolatedCaller("takePersistableUriPermission"); 7775 7776 Preconditions.checkFlagsArgument(modeFlags, 7777 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7778 7779 synchronized (this) { 7780 final int callingUid = Binder.getCallingUid(); 7781 boolean persistChanged = false; 7782 GrantUri grantUri = new GrantUri(userId, uri, false); 7783 7784 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7785 new GrantUri(userId, uri, false)); 7786 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7787 new GrantUri(userId, uri, true)); 7788 7789 final boolean exactValid = (exactPerm != null) 7790 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7791 final boolean prefixValid = (prefixPerm != null) 7792 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7793 7794 if (!(exactValid || prefixValid)) { 7795 throw new SecurityException("No persistable permission grants found for UID " 7796 + callingUid + " and Uri " + grantUri.toSafeString()); 7797 } 7798 7799 if (exactValid) { 7800 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7801 } 7802 if (prefixValid) { 7803 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7804 } 7805 7806 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7807 7808 if (persistChanged) { 7809 schedulePersistUriGrants(); 7810 } 7811 } 7812 } 7813 7814 /** 7815 * @param uri This uri must NOT contain an embedded userId. 7816 * @param userId The userId in which the uri is to be resolved. 7817 */ 7818 @Override 7819 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7820 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7821 7822 Preconditions.checkFlagsArgument(modeFlags, 7823 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7824 7825 synchronized (this) { 7826 final int callingUid = Binder.getCallingUid(); 7827 boolean persistChanged = false; 7828 7829 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7830 new GrantUri(userId, uri, false)); 7831 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7832 new GrantUri(userId, uri, true)); 7833 if (exactPerm == null && prefixPerm == null) { 7834 throw new SecurityException("No permission grants found for UID " + callingUid 7835 + " and Uri " + uri.toSafeString()); 7836 } 7837 7838 if (exactPerm != null) { 7839 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7840 removeUriPermissionIfNeededLocked(exactPerm); 7841 } 7842 if (prefixPerm != null) { 7843 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7844 removeUriPermissionIfNeededLocked(prefixPerm); 7845 } 7846 7847 if (persistChanged) { 7848 schedulePersistUriGrants(); 7849 } 7850 } 7851 } 7852 7853 /** 7854 * Prune any older {@link UriPermission} for the given UID until outstanding 7855 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7856 * 7857 * @return if any mutations occured that require persisting. 7858 */ 7859 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7860 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7861 if (perms == null) return false; 7862 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7863 7864 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7865 for (UriPermission perm : perms.values()) { 7866 if (perm.persistedModeFlags != 0) { 7867 persisted.add(perm); 7868 } 7869 } 7870 7871 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7872 if (trimCount <= 0) return false; 7873 7874 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7875 for (int i = 0; i < trimCount; i++) { 7876 final UriPermission perm = persisted.get(i); 7877 7878 if (DEBUG_URI_PERMISSION) { 7879 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7880 } 7881 7882 perm.releasePersistableModes(~0); 7883 removeUriPermissionIfNeededLocked(perm); 7884 } 7885 7886 return true; 7887 } 7888 7889 @Override 7890 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7891 String packageName, boolean incoming) { 7892 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7893 Preconditions.checkNotNull(packageName, "packageName"); 7894 7895 final int callingUid = Binder.getCallingUid(); 7896 final IPackageManager pm = AppGlobals.getPackageManager(); 7897 try { 7898 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7899 if (packageUid != callingUid) { 7900 throw new SecurityException( 7901 "Package " + packageName + " does not belong to calling UID " + callingUid); 7902 } 7903 } catch (RemoteException e) { 7904 throw new SecurityException("Failed to verify package name ownership"); 7905 } 7906 7907 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7908 synchronized (this) { 7909 if (incoming) { 7910 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7911 callingUid); 7912 if (perms == null) { 7913 Slog.w(TAG, "No permission grants found for " + packageName); 7914 } else { 7915 for (UriPermission perm : perms.values()) { 7916 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7917 result.add(perm.buildPersistedPublicApiObject()); 7918 } 7919 } 7920 } 7921 } else { 7922 final int size = mGrantedUriPermissions.size(); 7923 for (int i = 0; i < size; i++) { 7924 final ArrayMap<GrantUri, UriPermission> perms = 7925 mGrantedUriPermissions.valueAt(i); 7926 for (UriPermission perm : perms.values()) { 7927 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7928 result.add(perm.buildPersistedPublicApiObject()); 7929 } 7930 } 7931 } 7932 } 7933 } 7934 return new ParceledListSlice<android.content.UriPermission>(result); 7935 } 7936 7937 @Override 7938 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7939 synchronized (this) { 7940 ProcessRecord app = 7941 who != null ? getRecordForAppLocked(who) : null; 7942 if (app == null) return; 7943 7944 Message msg = Message.obtain(); 7945 msg.what = WAIT_FOR_DEBUGGER_MSG; 7946 msg.obj = app; 7947 msg.arg1 = waiting ? 1 : 0; 7948 mHandler.sendMessage(msg); 7949 } 7950 } 7951 7952 @Override 7953 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7954 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7955 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7956 outInfo.availMem = Process.getFreeMemory(); 7957 outInfo.totalMem = Process.getTotalMemory(); 7958 outInfo.threshold = homeAppMem; 7959 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7960 outInfo.hiddenAppThreshold = cachedAppMem; 7961 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7962 ProcessList.SERVICE_ADJ); 7963 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7964 ProcessList.VISIBLE_APP_ADJ); 7965 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7966 ProcessList.FOREGROUND_APP_ADJ); 7967 } 7968 7969 // ========================================================= 7970 // TASK MANAGEMENT 7971 // ========================================================= 7972 7973 @Override 7974 public List<IAppTask> getAppTasks(String callingPackage) { 7975 int callingUid = Binder.getCallingUid(); 7976 long ident = Binder.clearCallingIdentity(); 7977 7978 synchronized(this) { 7979 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7980 try { 7981 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7982 7983 final int N = mRecentTasks.size(); 7984 for (int i = 0; i < N; i++) { 7985 TaskRecord tr = mRecentTasks.get(i); 7986 // Skip tasks that do not match the caller. We don't need to verify 7987 // callingPackage, because we are also limiting to callingUid and know 7988 // that will limit to the correct security sandbox. 7989 if (tr.effectiveUid != callingUid) { 7990 continue; 7991 } 7992 Intent intent = tr.getBaseIntent(); 7993 if (intent == null || 7994 !callingPackage.equals(intent.getComponent().getPackageName())) { 7995 continue; 7996 } 7997 ActivityManager.RecentTaskInfo taskInfo = 7998 createRecentTaskInfoFromTaskRecord(tr); 7999 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8000 list.add(taskImpl); 8001 } 8002 } finally { 8003 Binder.restoreCallingIdentity(ident); 8004 } 8005 return list; 8006 } 8007 } 8008 8009 @Override 8010 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8011 final int callingUid = Binder.getCallingUid(); 8012 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8013 8014 synchronized(this) { 8015 if (localLOGV) Slog.v( 8016 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8017 8018 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8019 callingUid); 8020 8021 // TODO: Improve with MRU list from all ActivityStacks. 8022 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8023 } 8024 8025 return list; 8026 } 8027 8028 /** 8029 * Creates a new RecentTaskInfo from a TaskRecord. 8030 */ 8031 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8032 // Update the task description to reflect any changes in the task stack 8033 tr.updateTaskDescription(); 8034 8035 // Compose the recent task info 8036 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8037 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8038 rti.persistentId = tr.taskId; 8039 rti.baseIntent = new Intent(tr.getBaseIntent()); 8040 rti.origActivity = tr.origActivity; 8041 rti.description = tr.lastDescription; 8042 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8043 rti.userId = tr.userId; 8044 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8045 rti.firstActiveTime = tr.firstActiveTime; 8046 rti.lastActiveTime = tr.lastActiveTime; 8047 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8048 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8049 return rti; 8050 } 8051 8052 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8053 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8054 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8055 if (!allowed) { 8056 if (checkPermission(android.Manifest.permission.GET_TASKS, 8057 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8058 // Temporary compatibility: some existing apps on the system image may 8059 // still be requesting the old permission and not switched to the new 8060 // one; if so, we'll still allow them full access. This means we need 8061 // to see if they are holding the old permission and are a system app. 8062 try { 8063 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8064 allowed = true; 8065 Slog.w(TAG, caller + ": caller " + callingUid 8066 + " is using old GET_TASKS but privileged; allowing"); 8067 } 8068 } catch (RemoteException e) { 8069 } 8070 } 8071 } 8072 if (!allowed) { 8073 Slog.w(TAG, caller + ": caller " + callingUid 8074 + " does not hold GET_TASKS; limiting output"); 8075 } 8076 return allowed; 8077 } 8078 8079 @Override 8080 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8081 final int callingUid = Binder.getCallingUid(); 8082 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8083 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8084 8085 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8086 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8087 synchronized (this) { 8088 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8089 callingUid); 8090 final boolean detailed = checkCallingPermission( 8091 android.Manifest.permission.GET_DETAILED_TASKS) 8092 == PackageManager.PERMISSION_GRANTED; 8093 8094 final int N = mRecentTasks.size(); 8095 ArrayList<ActivityManager.RecentTaskInfo> res 8096 = new ArrayList<ActivityManager.RecentTaskInfo>( 8097 maxNum < N ? maxNum : N); 8098 8099 final Set<Integer> includedUsers; 8100 if (includeProfiles) { 8101 includedUsers = getProfileIdsLocked(userId); 8102 } else { 8103 includedUsers = new HashSet<Integer>(); 8104 } 8105 includedUsers.add(Integer.valueOf(userId)); 8106 8107 for (int i=0; i<N && maxNum > 0; i++) { 8108 TaskRecord tr = mRecentTasks.get(i); 8109 // Only add calling user or related users recent tasks 8110 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8111 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8112 continue; 8113 } 8114 8115 // Return the entry if desired by the caller. We always return 8116 // the first entry, because callers always expect this to be the 8117 // foreground app. We may filter others if the caller has 8118 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8119 // we should exclude the entry. 8120 8121 if (i == 0 8122 || withExcluded 8123 || (tr.intent == null) 8124 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8125 == 0)) { 8126 if (!allowed) { 8127 // If the caller doesn't have the GET_TASKS permission, then only 8128 // allow them to see a small subset of tasks -- their own and home. 8129 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8130 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8131 continue; 8132 } 8133 } 8134 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8135 if (tr.stack != null && tr.stack.isHomeStack()) { 8136 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8137 continue; 8138 } 8139 } 8140 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8141 // Don't include auto remove tasks that are finished or finishing. 8142 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8143 + tr); 8144 continue; 8145 } 8146 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8147 && !tr.isAvailable) { 8148 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8149 continue; 8150 } 8151 8152 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8153 if (!detailed) { 8154 rti.baseIntent.replaceExtras((Bundle)null); 8155 } 8156 8157 res.add(rti); 8158 maxNum--; 8159 } 8160 } 8161 return res; 8162 } 8163 } 8164 8165 private TaskRecord taskForIdLocked(int id) { 8166 final TaskRecord task = recentTaskForIdLocked(id); 8167 if (task != null) { 8168 return task; 8169 } 8170 8171 // Don't give up. Sometimes it just hasn't made it to recents yet. 8172 return mStackSupervisor.anyTaskForIdLocked(id); 8173 } 8174 8175 private TaskRecord recentTaskForIdLocked(int id) { 8176 final int N = mRecentTasks.size(); 8177 for (int i=0; i<N; i++) { 8178 TaskRecord tr = mRecentTasks.get(i); 8179 if (tr.taskId == id) { 8180 return tr; 8181 } 8182 } 8183 return null; 8184 } 8185 8186 @Override 8187 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8188 synchronized (this) { 8189 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8190 "getTaskThumbnail()"); 8191 TaskRecord tr = recentTaskForIdLocked(id); 8192 if (tr != null) { 8193 return tr.getTaskThumbnailLocked(); 8194 } 8195 } 8196 return null; 8197 } 8198 8199 @Override 8200 public int addAppTask(IBinder activityToken, Intent intent, 8201 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8202 final int callingUid = Binder.getCallingUid(); 8203 final long callingIdent = Binder.clearCallingIdentity(); 8204 8205 try { 8206 synchronized (this) { 8207 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8208 if (r == null) { 8209 throw new IllegalArgumentException("Activity does not exist; token=" 8210 + activityToken); 8211 } 8212 ComponentName comp = intent.getComponent(); 8213 if (comp == null) { 8214 throw new IllegalArgumentException("Intent " + intent 8215 + " must specify explicit component"); 8216 } 8217 if (thumbnail.getWidth() != mThumbnailWidth 8218 || thumbnail.getHeight() != mThumbnailHeight) { 8219 throw new IllegalArgumentException("Bad thumbnail size: got " 8220 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8221 + mThumbnailWidth + "x" + mThumbnailHeight); 8222 } 8223 if (intent.getSelector() != null) { 8224 intent.setSelector(null); 8225 } 8226 if (intent.getSourceBounds() != null) { 8227 intent.setSourceBounds(null); 8228 } 8229 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8230 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8231 // The caller has added this as an auto-remove task... that makes no 8232 // sense, so turn off auto-remove. 8233 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8234 } 8235 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8236 // Must be a new task. 8237 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8238 } 8239 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8240 mLastAddedTaskActivity = null; 8241 } 8242 ActivityInfo ainfo = mLastAddedTaskActivity; 8243 if (ainfo == null) { 8244 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8245 comp, 0, UserHandle.getUserId(callingUid)); 8246 if (ainfo.applicationInfo.uid != callingUid) { 8247 throw new SecurityException( 8248 "Can't add task for another application: target uid=" 8249 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8250 } 8251 } 8252 8253 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8254 intent, description); 8255 8256 int trimIdx = trimRecentsForTaskLocked(task, false); 8257 if (trimIdx >= 0) { 8258 // If this would have caused a trim, then we'll abort because that 8259 // means it would be added at the end of the list but then just removed. 8260 return -1; 8261 } 8262 8263 final int N = mRecentTasks.size(); 8264 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8265 final TaskRecord tr = mRecentTasks.remove(N - 1); 8266 tr.removedFromRecents(); 8267 } 8268 8269 task.inRecents = true; 8270 mRecentTasks.add(task); 8271 r.task.stack.addTask(task, false, false); 8272 8273 task.setLastThumbnail(thumbnail); 8274 task.freeLastThumbnail(); 8275 8276 return task.taskId; 8277 } 8278 } finally { 8279 Binder.restoreCallingIdentity(callingIdent); 8280 } 8281 } 8282 8283 @Override 8284 public Point getAppTaskThumbnailSize() { 8285 synchronized (this) { 8286 return new Point(mThumbnailWidth, mThumbnailHeight); 8287 } 8288 } 8289 8290 @Override 8291 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8292 synchronized (this) { 8293 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8294 if (r != null) { 8295 r.setTaskDescription(td); 8296 r.task.updateTaskDescription(); 8297 } 8298 } 8299 } 8300 8301 @Override 8302 public Bitmap getTaskDescriptionIcon(String filename) { 8303 if (!FileUtils.isValidExtFilename(filename) 8304 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8305 throw new IllegalArgumentException("Bad filename: " + filename); 8306 } 8307 return mTaskPersister.getTaskDescriptionIcon(filename); 8308 } 8309 8310 @Override 8311 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8312 throws RemoteException { 8313 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8314 opts.getCustomInPlaceResId() == 0) { 8315 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8316 "with valid animation"); 8317 } 8318 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8319 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8320 opts.getCustomInPlaceResId()); 8321 mWindowManager.executeAppTransition(); 8322 } 8323 8324 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8325 mRecentTasks.remove(tr); 8326 tr.removedFromRecents(); 8327 ComponentName component = tr.getBaseIntent().getComponent(); 8328 if (component == null) { 8329 Slog.w(TAG, "No component for base intent of task: " + tr); 8330 return; 8331 } 8332 8333 if (!killProcess) { 8334 return; 8335 } 8336 8337 // Determine if the process(es) for this task should be killed. 8338 final String pkg = component.getPackageName(); 8339 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8340 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8341 for (int i = 0; i < pmap.size(); i++) { 8342 8343 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8344 for (int j = 0; j < uids.size(); j++) { 8345 ProcessRecord proc = uids.valueAt(j); 8346 if (proc.userId != tr.userId) { 8347 // Don't kill process for a different user. 8348 continue; 8349 } 8350 if (proc == mHomeProcess) { 8351 // Don't kill the home process along with tasks from the same package. 8352 continue; 8353 } 8354 if (!proc.pkgList.containsKey(pkg)) { 8355 // Don't kill process that is not associated with this task. 8356 continue; 8357 } 8358 8359 for (int k = 0; k < proc.activities.size(); k++) { 8360 TaskRecord otherTask = proc.activities.get(k).task; 8361 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8362 // Don't kill process(es) that has an activity in a different task that is 8363 // also in recents. 8364 return; 8365 } 8366 } 8367 8368 // Add process to kill list. 8369 procsToKill.add(proc); 8370 } 8371 } 8372 8373 // Find any running services associated with this app and stop if needed. 8374 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8375 8376 // Kill the running processes. 8377 for (int i = 0; i < procsToKill.size(); i++) { 8378 ProcessRecord pr = procsToKill.get(i); 8379 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8380 pr.kill("remove task", true); 8381 } else { 8382 pr.waitingToKill = "remove task"; 8383 } 8384 } 8385 } 8386 8387 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8388 // Remove all tasks with activities in the specified package from the list of recent tasks 8389 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8390 TaskRecord tr = mRecentTasks.get(i); 8391 if (tr.userId != userId) continue; 8392 8393 ComponentName cn = tr.intent.getComponent(); 8394 if (cn != null && cn.getPackageName().equals(packageName)) { 8395 // If the package name matches, remove the task. 8396 removeTaskByIdLocked(tr.taskId, true); 8397 } 8398 } 8399 } 8400 8401 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8402 final IPackageManager pm = AppGlobals.getPackageManager(); 8403 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8404 8405 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8406 TaskRecord tr = mRecentTasks.get(i); 8407 if (tr.userId != userId) continue; 8408 8409 ComponentName cn = tr.intent.getComponent(); 8410 if (cn != null && cn.getPackageName().equals(packageName)) { 8411 // Skip if component still exists in the package. 8412 if (componentsKnownToExist.contains(cn)) continue; 8413 8414 try { 8415 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8416 if (info != null) { 8417 componentsKnownToExist.add(cn); 8418 } else { 8419 removeTaskByIdLocked(tr.taskId, false); 8420 } 8421 } catch (RemoteException e) { 8422 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8423 } 8424 } 8425 } 8426 } 8427 8428 /** 8429 * Removes the task with the specified task id. 8430 * 8431 * @param taskId Identifier of the task to be removed. 8432 * @param killProcess Kill any process associated with the task if possible. 8433 * @return Returns true if the given task was found and removed. 8434 */ 8435 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8436 TaskRecord tr = taskForIdLocked(taskId); 8437 if (tr != null) { 8438 tr.removeTaskActivitiesLocked(); 8439 cleanUpRemovedTaskLocked(tr, killProcess); 8440 if (tr.isPersistable) { 8441 notifyTaskPersisterLocked(null, true); 8442 } 8443 return true; 8444 } 8445 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8446 return false; 8447 } 8448 8449 @Override 8450 public boolean removeTask(int taskId) { 8451 synchronized (this) { 8452 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8453 "removeTask()"); 8454 long ident = Binder.clearCallingIdentity(); 8455 try { 8456 return removeTaskByIdLocked(taskId, true); 8457 } finally { 8458 Binder.restoreCallingIdentity(ident); 8459 } 8460 } 8461 } 8462 8463 /** 8464 * TODO: Add mController hook 8465 */ 8466 @Override 8467 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8468 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8469 "moveTaskToFront()"); 8470 8471 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8472 synchronized(this) { 8473 moveTaskToFrontLocked(taskId, flags, options); 8474 } 8475 } 8476 8477 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8478 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8479 Binder.getCallingUid(), -1, -1, "Task to front")) { 8480 ActivityOptions.abort(options); 8481 return; 8482 } 8483 final long origId = Binder.clearCallingIdentity(); 8484 try { 8485 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8486 if (task == null) { 8487 Slog.d(TAG, "Could not find task for id: "+ taskId); 8488 return; 8489 } 8490 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8491 mStackSupervisor.showLockTaskToast(); 8492 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8493 return; 8494 } 8495 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8496 if (prev != null && prev.isRecentsActivity()) { 8497 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8498 } 8499 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8500 } finally { 8501 Binder.restoreCallingIdentity(origId); 8502 } 8503 ActivityOptions.abort(options); 8504 } 8505 8506 @Override 8507 public void moveTaskToBack(int taskId) { 8508 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8509 "moveTaskToBack()"); 8510 8511 synchronized(this) { 8512 TaskRecord tr = taskForIdLocked(taskId); 8513 if (tr != null) { 8514 if (tr == mStackSupervisor.mLockTaskModeTask) { 8515 mStackSupervisor.showLockTaskToast(); 8516 return; 8517 } 8518 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8519 ActivityStack stack = tr.stack; 8520 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8521 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8522 Binder.getCallingUid(), -1, -1, "Task to back")) { 8523 return; 8524 } 8525 } 8526 final long origId = Binder.clearCallingIdentity(); 8527 try { 8528 stack.moveTaskToBackLocked(taskId, null); 8529 } finally { 8530 Binder.restoreCallingIdentity(origId); 8531 } 8532 } 8533 } 8534 } 8535 8536 /** 8537 * Moves an activity, and all of the other activities within the same task, to the bottom 8538 * of the history stack. The activity's order within the task is unchanged. 8539 * 8540 * @param token A reference to the activity we wish to move 8541 * @param nonRoot If false then this only works if the activity is the root 8542 * of a task; if true it will work for any activity in a task. 8543 * @return Returns true if the move completed, false if not. 8544 */ 8545 @Override 8546 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8547 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8548 synchronized(this) { 8549 final long origId = Binder.clearCallingIdentity(); 8550 try { 8551 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8552 if (taskId >= 0) { 8553 if ((mStackSupervisor.mLockTaskModeTask != null) 8554 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8555 mStackSupervisor.showLockTaskToast(); 8556 return false; 8557 } 8558 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8559 } 8560 } finally { 8561 Binder.restoreCallingIdentity(origId); 8562 } 8563 } 8564 return false; 8565 } 8566 8567 @Override 8568 public void moveTaskBackwards(int task) { 8569 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8570 "moveTaskBackwards()"); 8571 8572 synchronized(this) { 8573 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8574 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8575 return; 8576 } 8577 final long origId = Binder.clearCallingIdentity(); 8578 moveTaskBackwardsLocked(task); 8579 Binder.restoreCallingIdentity(origId); 8580 } 8581 } 8582 8583 private final void moveTaskBackwardsLocked(int task) { 8584 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8585 } 8586 8587 @Override 8588 public IBinder getHomeActivityToken() throws RemoteException { 8589 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8590 "getHomeActivityToken()"); 8591 synchronized (this) { 8592 return mStackSupervisor.getHomeActivityToken(); 8593 } 8594 } 8595 8596 @Override 8597 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8598 IActivityContainerCallback callback) throws RemoteException { 8599 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8600 "createActivityContainer()"); 8601 synchronized (this) { 8602 if (parentActivityToken == null) { 8603 throw new IllegalArgumentException("parent token must not be null"); 8604 } 8605 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8606 if (r == null) { 8607 return null; 8608 } 8609 if (callback == null) { 8610 throw new IllegalArgumentException("callback must not be null"); 8611 } 8612 return mStackSupervisor.createActivityContainer(r, callback); 8613 } 8614 } 8615 8616 @Override 8617 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8618 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8619 "deleteActivityContainer()"); 8620 synchronized (this) { 8621 mStackSupervisor.deleteActivityContainer(container); 8622 } 8623 } 8624 8625 @Override 8626 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8627 throws RemoteException { 8628 synchronized (this) { 8629 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8630 if (stack != null) { 8631 return stack.mActivityContainer; 8632 } 8633 return null; 8634 } 8635 } 8636 8637 @Override 8638 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8639 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8640 "moveTaskToStack()"); 8641 if (stackId == HOME_STACK_ID) { 8642 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8643 new RuntimeException("here").fillInStackTrace()); 8644 } 8645 synchronized (this) { 8646 long ident = Binder.clearCallingIdentity(); 8647 try { 8648 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8649 + stackId + " toTop=" + toTop); 8650 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8651 } finally { 8652 Binder.restoreCallingIdentity(ident); 8653 } 8654 } 8655 } 8656 8657 @Override 8658 public void resizeStack(int stackBoxId, Rect bounds) { 8659 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8660 "resizeStackBox()"); 8661 long ident = Binder.clearCallingIdentity(); 8662 try { 8663 mWindowManager.resizeStack(stackBoxId, bounds); 8664 } finally { 8665 Binder.restoreCallingIdentity(ident); 8666 } 8667 } 8668 8669 @Override 8670 public List<StackInfo> getAllStackInfos() { 8671 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8672 "getAllStackInfos()"); 8673 long ident = Binder.clearCallingIdentity(); 8674 try { 8675 synchronized (this) { 8676 return mStackSupervisor.getAllStackInfosLocked(); 8677 } 8678 } finally { 8679 Binder.restoreCallingIdentity(ident); 8680 } 8681 } 8682 8683 @Override 8684 public StackInfo getStackInfo(int stackId) { 8685 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8686 "getStackInfo()"); 8687 long ident = Binder.clearCallingIdentity(); 8688 try { 8689 synchronized (this) { 8690 return mStackSupervisor.getStackInfoLocked(stackId); 8691 } 8692 } finally { 8693 Binder.restoreCallingIdentity(ident); 8694 } 8695 } 8696 8697 @Override 8698 public boolean isInHomeStack(int taskId) { 8699 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8700 "getStackInfo()"); 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 synchronized (this) { 8704 TaskRecord tr = taskForIdLocked(taskId); 8705 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8706 } 8707 } finally { 8708 Binder.restoreCallingIdentity(ident); 8709 } 8710 } 8711 8712 @Override 8713 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8714 synchronized(this) { 8715 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8716 } 8717 } 8718 8719 private boolean isLockTaskAuthorized(String pkg) { 8720 final DevicePolicyManager dpm = (DevicePolicyManager) 8721 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8722 try { 8723 int uid = mContext.getPackageManager().getPackageUid(pkg, 8724 Binder.getCallingUserHandle().getIdentifier()); 8725 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8726 } catch (NameNotFoundException e) { 8727 return false; 8728 } 8729 } 8730 8731 void startLockTaskMode(TaskRecord task) { 8732 final String pkg; 8733 synchronized (this) { 8734 pkg = task.intent.getComponent().getPackageName(); 8735 } 8736 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8737 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8738 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8739 StatusBarManagerInternal.class); 8740 if (statusBarManager != null) { 8741 statusBarManager.showScreenPinningRequest(); 8742 } 8743 return; 8744 } 8745 long ident = Binder.clearCallingIdentity(); 8746 try { 8747 synchronized (this) { 8748 // Since we lost lock on task, make sure it is still there. 8749 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8750 if (task != null) { 8751 if (!isSystemInitiated 8752 && ((mStackSupervisor.getFocusedStack() == null) 8753 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8754 throw new IllegalArgumentException("Invalid task, not in foreground"); 8755 } 8756 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8757 } 8758 } 8759 } finally { 8760 Binder.restoreCallingIdentity(ident); 8761 } 8762 } 8763 8764 @Override 8765 public void startLockTaskMode(int taskId) { 8766 final TaskRecord task; 8767 long ident = Binder.clearCallingIdentity(); 8768 try { 8769 synchronized (this) { 8770 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8771 } 8772 } finally { 8773 Binder.restoreCallingIdentity(ident); 8774 } 8775 if (task != null) { 8776 startLockTaskMode(task); 8777 } 8778 } 8779 8780 @Override 8781 public void startLockTaskMode(IBinder token) { 8782 final TaskRecord task; 8783 long ident = Binder.clearCallingIdentity(); 8784 try { 8785 synchronized (this) { 8786 final ActivityRecord r = ActivityRecord.forToken(token); 8787 if (r == null) { 8788 return; 8789 } 8790 task = r.task; 8791 } 8792 } finally { 8793 Binder.restoreCallingIdentity(ident); 8794 } 8795 if (task != null) { 8796 startLockTaskMode(task); 8797 } 8798 } 8799 8800 @Override 8801 public void startLockTaskModeOnCurrent() throws RemoteException { 8802 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8803 "startLockTaskModeOnCurrent"); 8804 long ident = Binder.clearCallingIdentity(); 8805 try { 8806 ActivityRecord r = null; 8807 synchronized (this) { 8808 r = mStackSupervisor.topRunningActivityLocked(); 8809 } 8810 startLockTaskMode(r.task); 8811 } finally { 8812 Binder.restoreCallingIdentity(ident); 8813 } 8814 } 8815 8816 @Override 8817 public void stopLockTaskMode() { 8818 // Verify that the user matches the package of the intent for the TaskRecord 8819 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8820 // and stopLockTaskMode. 8821 final int callingUid = Binder.getCallingUid(); 8822 if (callingUid != Process.SYSTEM_UID) { 8823 try { 8824 String pkg = 8825 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8826 int uid = mContext.getPackageManager().getPackageUid(pkg, 8827 Binder.getCallingUserHandle().getIdentifier()); 8828 if (uid != callingUid) { 8829 throw new SecurityException("Invalid uid, expected " + uid); 8830 } 8831 } catch (NameNotFoundException e) { 8832 Log.d(TAG, "stopLockTaskMode " + e); 8833 return; 8834 } 8835 } 8836 long ident = Binder.clearCallingIdentity(); 8837 try { 8838 Log.d(TAG, "stopLockTaskMode"); 8839 // Stop lock task 8840 synchronized (this) { 8841 mStackSupervisor.setLockTaskModeLocked(null, false); 8842 } 8843 } finally { 8844 Binder.restoreCallingIdentity(ident); 8845 } 8846 } 8847 8848 @Override 8849 public void stopLockTaskModeOnCurrent() throws RemoteException { 8850 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8851 "stopLockTaskModeOnCurrent"); 8852 long ident = Binder.clearCallingIdentity(); 8853 try { 8854 stopLockTaskMode(); 8855 } finally { 8856 Binder.restoreCallingIdentity(ident); 8857 } 8858 } 8859 8860 @Override 8861 public boolean isInLockTaskMode() { 8862 synchronized (this) { 8863 return mStackSupervisor.isInLockTaskMode(); 8864 } 8865 } 8866 8867 // ========================================================= 8868 // CONTENT PROVIDERS 8869 // ========================================================= 8870 8871 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8872 List<ProviderInfo> providers = null; 8873 try { 8874 providers = AppGlobals.getPackageManager(). 8875 queryContentProviders(app.processName, app.uid, 8876 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8877 } catch (RemoteException ex) { 8878 } 8879 if (DEBUG_MU) 8880 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8881 int userId = app.userId; 8882 if (providers != null) { 8883 int N = providers.size(); 8884 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8885 for (int i=0; i<N; i++) { 8886 ProviderInfo cpi = 8887 (ProviderInfo)providers.get(i); 8888 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8889 cpi.name, cpi.flags); 8890 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8891 // This is a singleton provider, but a user besides the 8892 // default user is asking to initialize a process it runs 8893 // in... well, no, it doesn't actually run in this process, 8894 // it runs in the process of the default user. Get rid of it. 8895 providers.remove(i); 8896 N--; 8897 i--; 8898 continue; 8899 } 8900 8901 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8902 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8903 if (cpr == null) { 8904 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8905 mProviderMap.putProviderByClass(comp, cpr); 8906 } 8907 if (DEBUG_MU) 8908 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8909 app.pubProviders.put(cpi.name, cpr); 8910 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8911 // Don't add this if it is a platform component that is marked 8912 // to run in multiple processes, because this is actually 8913 // part of the framework so doesn't make sense to track as a 8914 // separate apk in the process. 8915 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8916 mProcessStats); 8917 } 8918 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8919 } 8920 } 8921 return providers; 8922 } 8923 8924 /** 8925 * Check if {@link ProcessRecord} has a possible chance at accessing the 8926 * given {@link ProviderInfo}. Final permission checking is always done 8927 * in {@link ContentProvider}. 8928 */ 8929 private final String checkContentProviderPermissionLocked( 8930 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8931 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8932 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8933 boolean checkedGrants = false; 8934 if (checkUser) { 8935 // Looking for cross-user grants before enforcing the typical cross-users permissions 8936 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8937 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8938 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8939 return null; 8940 } 8941 checkedGrants = true; 8942 } 8943 userId = handleIncomingUser(callingPid, callingUid, userId, 8944 false, ALLOW_NON_FULL, 8945 "checkContentProviderPermissionLocked " + cpi.authority, null); 8946 if (userId != tmpTargetUserId) { 8947 // When we actually went to determine the final targer user ID, this ended 8948 // up different than our initial check for the authority. This is because 8949 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8950 // SELF. So we need to re-check the grants again. 8951 checkedGrants = false; 8952 } 8953 } 8954 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8955 cpi.applicationInfo.uid, cpi.exported) 8956 == PackageManager.PERMISSION_GRANTED) { 8957 return null; 8958 } 8959 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8960 cpi.applicationInfo.uid, cpi.exported) 8961 == PackageManager.PERMISSION_GRANTED) { 8962 return null; 8963 } 8964 8965 PathPermission[] pps = cpi.pathPermissions; 8966 if (pps != null) { 8967 int i = pps.length; 8968 while (i > 0) { 8969 i--; 8970 PathPermission pp = pps[i]; 8971 String pprperm = pp.getReadPermission(); 8972 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8973 cpi.applicationInfo.uid, cpi.exported) 8974 == PackageManager.PERMISSION_GRANTED) { 8975 return null; 8976 } 8977 String ppwperm = pp.getWritePermission(); 8978 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8979 cpi.applicationInfo.uid, cpi.exported) 8980 == PackageManager.PERMISSION_GRANTED) { 8981 return null; 8982 } 8983 } 8984 } 8985 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8986 return null; 8987 } 8988 8989 String msg; 8990 if (!cpi.exported) { 8991 msg = "Permission Denial: opening provider " + cpi.name 8992 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8993 + ", uid=" + callingUid + ") that is not exported from uid " 8994 + cpi.applicationInfo.uid; 8995 } else { 8996 msg = "Permission Denial: opening provider " + cpi.name 8997 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8998 + ", uid=" + callingUid + ") requires " 8999 + cpi.readPermission + " or " + cpi.writePermission; 9000 } 9001 Slog.w(TAG, msg); 9002 return msg; 9003 } 9004 9005 /** 9006 * Returns if the ContentProvider has granted a uri to callingUid 9007 */ 9008 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9009 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9010 if (perms != null) { 9011 for (int i=perms.size()-1; i>=0; i--) { 9012 GrantUri grantUri = perms.keyAt(i); 9013 if (grantUri.sourceUserId == userId || !checkUser) { 9014 if (matchesProvider(grantUri.uri, cpi)) { 9015 return true; 9016 } 9017 } 9018 } 9019 } 9020 return false; 9021 } 9022 9023 /** 9024 * Returns true if the uri authority is one of the authorities specified in the provider. 9025 */ 9026 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9027 String uriAuth = uri.getAuthority(); 9028 String cpiAuth = cpi.authority; 9029 if (cpiAuth.indexOf(';') == -1) { 9030 return cpiAuth.equals(uriAuth); 9031 } 9032 String[] cpiAuths = cpiAuth.split(";"); 9033 int length = cpiAuths.length; 9034 for (int i = 0; i < length; i++) { 9035 if (cpiAuths[i].equals(uriAuth)) return true; 9036 } 9037 return false; 9038 } 9039 9040 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9041 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9042 if (r != null) { 9043 for (int i=0; i<r.conProviders.size(); i++) { 9044 ContentProviderConnection conn = r.conProviders.get(i); 9045 if (conn.provider == cpr) { 9046 if (DEBUG_PROVIDER) Slog.v(TAG, 9047 "Adding provider requested by " 9048 + r.processName + " from process " 9049 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9050 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9051 if (stable) { 9052 conn.stableCount++; 9053 conn.numStableIncs++; 9054 } else { 9055 conn.unstableCount++; 9056 conn.numUnstableIncs++; 9057 } 9058 return conn; 9059 } 9060 } 9061 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9062 if (stable) { 9063 conn.stableCount = 1; 9064 conn.numStableIncs = 1; 9065 } else { 9066 conn.unstableCount = 1; 9067 conn.numUnstableIncs = 1; 9068 } 9069 cpr.connections.add(conn); 9070 r.conProviders.add(conn); 9071 return conn; 9072 } 9073 cpr.addExternalProcessHandleLocked(externalProcessToken); 9074 return null; 9075 } 9076 9077 boolean decProviderCountLocked(ContentProviderConnection conn, 9078 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9079 if (conn != null) { 9080 cpr = conn.provider; 9081 if (DEBUG_PROVIDER) Slog.v(TAG, 9082 "Removing provider requested by " 9083 + conn.client.processName + " from process " 9084 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9085 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9086 if (stable) { 9087 conn.stableCount--; 9088 } else { 9089 conn.unstableCount--; 9090 } 9091 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9092 cpr.connections.remove(conn); 9093 conn.client.conProviders.remove(conn); 9094 return true; 9095 } 9096 return false; 9097 } 9098 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9099 return false; 9100 } 9101 9102 private void checkTime(long startTime, String where) { 9103 long now = SystemClock.elapsedRealtime(); 9104 if ((now-startTime) > 1000) { 9105 // If we are taking more than a second, log about it. 9106 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9107 } 9108 } 9109 9110 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9111 String name, IBinder token, boolean stable, int userId) { 9112 ContentProviderRecord cpr; 9113 ContentProviderConnection conn = null; 9114 ProviderInfo cpi = null; 9115 9116 synchronized(this) { 9117 long startTime = SystemClock.elapsedRealtime(); 9118 9119 ProcessRecord r = null; 9120 if (caller != null) { 9121 r = getRecordForAppLocked(caller); 9122 if (r == null) { 9123 throw new SecurityException( 9124 "Unable to find app for caller " + caller 9125 + " (pid=" + Binder.getCallingPid() 9126 + ") when getting content provider " + name); 9127 } 9128 } 9129 9130 boolean checkCrossUser = true; 9131 9132 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9133 9134 // First check if this content provider has been published... 9135 cpr = mProviderMap.getProviderByName(name, userId); 9136 // If that didn't work, check if it exists for user 0 and then 9137 // verify that it's a singleton provider before using it. 9138 if (cpr == null && userId != UserHandle.USER_OWNER) { 9139 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9140 if (cpr != null) { 9141 cpi = cpr.info; 9142 if (isSingleton(cpi.processName, cpi.applicationInfo, 9143 cpi.name, cpi.flags) 9144 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9145 userId = UserHandle.USER_OWNER; 9146 checkCrossUser = false; 9147 } else { 9148 cpr = null; 9149 cpi = null; 9150 } 9151 } 9152 } 9153 9154 boolean providerRunning = cpr != null; 9155 if (providerRunning) { 9156 cpi = cpr.info; 9157 String msg; 9158 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9159 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9160 != null) { 9161 throw new SecurityException(msg); 9162 } 9163 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9164 9165 if (r != null && cpr.canRunHere(r)) { 9166 // This provider has been published or is in the process 9167 // of being published... but it is also allowed to run 9168 // in the caller's process, so don't make a connection 9169 // and just let the caller instantiate its own instance. 9170 ContentProviderHolder holder = cpr.newHolder(null); 9171 // don't give caller the provider object, it needs 9172 // to make its own. 9173 holder.provider = null; 9174 return holder; 9175 } 9176 9177 final long origId = Binder.clearCallingIdentity(); 9178 9179 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9180 9181 // In this case the provider instance already exists, so we can 9182 // return it right away. 9183 conn = incProviderCountLocked(r, cpr, token, stable); 9184 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9185 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9186 // If this is a perceptible app accessing the provider, 9187 // make sure to count it as being accessed and thus 9188 // back up on the LRU list. This is good because 9189 // content providers are often expensive to start. 9190 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9191 updateLruProcessLocked(cpr.proc, false, null); 9192 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9193 } 9194 } 9195 9196 if (cpr.proc != null) { 9197 if (false) { 9198 if (cpr.name.flattenToShortString().equals( 9199 "com.android.providers.calendar/.CalendarProvider2")) { 9200 Slog.v(TAG, "****************** KILLING " 9201 + cpr.name.flattenToShortString()); 9202 Process.killProcess(cpr.proc.pid); 9203 } 9204 } 9205 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9206 boolean success = updateOomAdjLocked(cpr.proc); 9207 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9208 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9209 // NOTE: there is still a race here where a signal could be 9210 // pending on the process even though we managed to update its 9211 // adj level. Not sure what to do about this, but at least 9212 // the race is now smaller. 9213 if (!success) { 9214 // Uh oh... it looks like the provider's process 9215 // has been killed on us. We need to wait for a new 9216 // process to be started, and make sure its death 9217 // doesn't kill our process. 9218 Slog.i(TAG, 9219 "Existing provider " + cpr.name.flattenToShortString() 9220 + " is crashing; detaching " + r); 9221 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9222 checkTime(startTime, "getContentProviderImpl: before appDied"); 9223 appDiedLocked(cpr.proc); 9224 checkTime(startTime, "getContentProviderImpl: after appDied"); 9225 if (!lastRef) { 9226 // This wasn't the last ref our process had on 9227 // the provider... we have now been killed, bail. 9228 return null; 9229 } 9230 providerRunning = false; 9231 conn = null; 9232 } 9233 } 9234 9235 Binder.restoreCallingIdentity(origId); 9236 } 9237 9238 boolean singleton; 9239 if (!providerRunning) { 9240 try { 9241 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9242 cpi = AppGlobals.getPackageManager(). 9243 resolveContentProvider(name, 9244 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9245 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9246 } catch (RemoteException ex) { 9247 } 9248 if (cpi == null) { 9249 return null; 9250 } 9251 // If the provider is a singleton AND 9252 // (it's a call within the same user || the provider is a 9253 // privileged app) 9254 // Then allow connecting to the singleton provider 9255 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9256 cpi.name, cpi.flags) 9257 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9258 if (singleton) { 9259 userId = UserHandle.USER_OWNER; 9260 } 9261 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9262 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9263 9264 String msg; 9265 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9266 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9267 != null) { 9268 throw new SecurityException(msg); 9269 } 9270 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9271 9272 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9273 && !cpi.processName.equals("system")) { 9274 // If this content provider does not run in the system 9275 // process, and the system is not yet ready to run other 9276 // processes, then fail fast instead of hanging. 9277 throw new IllegalArgumentException( 9278 "Attempt to launch content provider before system ready"); 9279 } 9280 9281 // Make sure that the user who owns this provider is started. If not, 9282 // we don't want to allow it to run. 9283 if (mStartedUsers.get(userId) == null) { 9284 Slog.w(TAG, "Unable to launch app " 9285 + cpi.applicationInfo.packageName + "/" 9286 + cpi.applicationInfo.uid + " for provider " 9287 + name + ": user " + userId + " is stopped"); 9288 return null; 9289 } 9290 9291 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9292 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9293 cpr = mProviderMap.getProviderByClass(comp, userId); 9294 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9295 final boolean firstClass = cpr == null; 9296 if (firstClass) { 9297 final long ident = Binder.clearCallingIdentity(); 9298 try { 9299 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9300 ApplicationInfo ai = 9301 AppGlobals.getPackageManager(). 9302 getApplicationInfo( 9303 cpi.applicationInfo.packageName, 9304 STOCK_PM_FLAGS, userId); 9305 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9306 if (ai == null) { 9307 Slog.w(TAG, "No package info for content provider " 9308 + cpi.name); 9309 return null; 9310 } 9311 ai = getAppInfoForUser(ai, userId); 9312 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9313 } catch (RemoteException ex) { 9314 // pm is in same process, this will never happen. 9315 } finally { 9316 Binder.restoreCallingIdentity(ident); 9317 } 9318 } 9319 9320 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9321 9322 if (r != null && cpr.canRunHere(r)) { 9323 // If this is a multiprocess provider, then just return its 9324 // info and allow the caller to instantiate it. Only do 9325 // this if the provider is the same user as the caller's 9326 // process, or can run as root (so can be in any process). 9327 return cpr.newHolder(null); 9328 } 9329 9330 if (DEBUG_PROVIDER) { 9331 RuntimeException e = new RuntimeException("here"); 9332 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9333 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9334 } 9335 9336 // This is single process, and our app is now connecting to it. 9337 // See if we are already in the process of launching this 9338 // provider. 9339 final int N = mLaunchingProviders.size(); 9340 int i; 9341 for (i=0; i<N; i++) { 9342 if (mLaunchingProviders.get(i) == cpr) { 9343 break; 9344 } 9345 } 9346 9347 // If the provider is not already being launched, then get it 9348 // started. 9349 if (i >= N) { 9350 final long origId = Binder.clearCallingIdentity(); 9351 9352 try { 9353 // Content provider is now in use, its package can't be stopped. 9354 try { 9355 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9356 AppGlobals.getPackageManager().setPackageStoppedState( 9357 cpr.appInfo.packageName, false, userId); 9358 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9359 } catch (RemoteException e) { 9360 } catch (IllegalArgumentException e) { 9361 Slog.w(TAG, "Failed trying to unstop package " 9362 + cpr.appInfo.packageName + ": " + e); 9363 } 9364 9365 // Use existing process if already started 9366 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9367 ProcessRecord proc = getProcessRecordLocked( 9368 cpi.processName, cpr.appInfo.uid, false); 9369 if (proc != null && proc.thread != null) { 9370 if (DEBUG_PROVIDER) { 9371 Slog.d(TAG, "Installing in existing process " + proc); 9372 } 9373 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9374 proc.pubProviders.put(cpi.name, cpr); 9375 try { 9376 proc.thread.scheduleInstallProvider(cpi); 9377 } catch (RemoteException e) { 9378 } 9379 } else { 9380 checkTime(startTime, "getContentProviderImpl: before start process"); 9381 proc = startProcessLocked(cpi.processName, 9382 cpr.appInfo, false, 0, "content provider", 9383 new ComponentName(cpi.applicationInfo.packageName, 9384 cpi.name), false, false, false); 9385 checkTime(startTime, "getContentProviderImpl: after start process"); 9386 if (proc == null) { 9387 Slog.w(TAG, "Unable to launch app " 9388 + cpi.applicationInfo.packageName + "/" 9389 + cpi.applicationInfo.uid + " for provider " 9390 + name + ": process is bad"); 9391 return null; 9392 } 9393 } 9394 cpr.launchingApp = proc; 9395 mLaunchingProviders.add(cpr); 9396 } finally { 9397 Binder.restoreCallingIdentity(origId); 9398 } 9399 } 9400 9401 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9402 9403 // Make sure the provider is published (the same provider class 9404 // may be published under multiple names). 9405 if (firstClass) { 9406 mProviderMap.putProviderByClass(comp, cpr); 9407 } 9408 9409 mProviderMap.putProviderByName(name, cpr); 9410 conn = incProviderCountLocked(r, cpr, token, stable); 9411 if (conn != null) { 9412 conn.waiting = true; 9413 } 9414 } 9415 checkTime(startTime, "getContentProviderImpl: done!"); 9416 } 9417 9418 // Wait for the provider to be published... 9419 synchronized (cpr) { 9420 while (cpr.provider == null) { 9421 if (cpr.launchingApp == null) { 9422 Slog.w(TAG, "Unable to launch app " 9423 + cpi.applicationInfo.packageName + "/" 9424 + cpi.applicationInfo.uid + " for provider " 9425 + name + ": launching app became null"); 9426 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9427 UserHandle.getUserId(cpi.applicationInfo.uid), 9428 cpi.applicationInfo.packageName, 9429 cpi.applicationInfo.uid, name); 9430 return null; 9431 } 9432 try { 9433 if (DEBUG_MU) { 9434 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9435 + cpr.launchingApp); 9436 } 9437 if (conn != null) { 9438 conn.waiting = true; 9439 } 9440 cpr.wait(); 9441 } catch (InterruptedException ex) { 9442 } finally { 9443 if (conn != null) { 9444 conn.waiting = false; 9445 } 9446 } 9447 } 9448 } 9449 return cpr != null ? cpr.newHolder(conn) : null; 9450 } 9451 9452 @Override 9453 public final ContentProviderHolder getContentProvider( 9454 IApplicationThread caller, String name, int userId, boolean stable) { 9455 enforceNotIsolatedCaller("getContentProvider"); 9456 if (caller == null) { 9457 String msg = "null IApplicationThread when getting content provider " 9458 + name; 9459 Slog.w(TAG, msg); 9460 throw new SecurityException(msg); 9461 } 9462 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9463 // with cross-user grant. 9464 return getContentProviderImpl(caller, name, null, stable, userId); 9465 } 9466 9467 public ContentProviderHolder getContentProviderExternal( 9468 String name, int userId, IBinder token) { 9469 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9470 "Do not have permission in call getContentProviderExternal()"); 9471 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9472 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9473 return getContentProviderExternalUnchecked(name, token, userId); 9474 } 9475 9476 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9477 IBinder token, int userId) { 9478 return getContentProviderImpl(null, name, token, true, userId); 9479 } 9480 9481 /** 9482 * Drop a content provider from a ProcessRecord's bookkeeping 9483 */ 9484 public void removeContentProvider(IBinder connection, boolean stable) { 9485 enforceNotIsolatedCaller("removeContentProvider"); 9486 long ident = Binder.clearCallingIdentity(); 9487 try { 9488 synchronized (this) { 9489 ContentProviderConnection conn; 9490 try { 9491 conn = (ContentProviderConnection)connection; 9492 } catch (ClassCastException e) { 9493 String msg ="removeContentProvider: " + connection 9494 + " not a ContentProviderConnection"; 9495 Slog.w(TAG, msg); 9496 throw new IllegalArgumentException(msg); 9497 } 9498 if (conn == null) { 9499 throw new NullPointerException("connection is null"); 9500 } 9501 if (decProviderCountLocked(conn, null, null, stable)) { 9502 updateOomAdjLocked(); 9503 } 9504 } 9505 } finally { 9506 Binder.restoreCallingIdentity(ident); 9507 } 9508 } 9509 9510 public void removeContentProviderExternal(String name, IBinder token) { 9511 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9512 "Do not have permission in call removeContentProviderExternal()"); 9513 int userId = UserHandle.getCallingUserId(); 9514 long ident = Binder.clearCallingIdentity(); 9515 try { 9516 removeContentProviderExternalUnchecked(name, token, userId); 9517 } finally { 9518 Binder.restoreCallingIdentity(ident); 9519 } 9520 } 9521 9522 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9523 synchronized (this) { 9524 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9525 if(cpr == null) { 9526 //remove from mProvidersByClass 9527 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9528 return; 9529 } 9530 9531 //update content provider record entry info 9532 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9533 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9534 if (localCpr.hasExternalProcessHandles()) { 9535 if (localCpr.removeExternalProcessHandleLocked(token)) { 9536 updateOomAdjLocked(); 9537 } else { 9538 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9539 + " with no external reference for token: " 9540 + token + "."); 9541 } 9542 } else { 9543 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9544 + " with no external references."); 9545 } 9546 } 9547 } 9548 9549 public final void publishContentProviders(IApplicationThread caller, 9550 List<ContentProviderHolder> providers) { 9551 if (providers == null) { 9552 return; 9553 } 9554 9555 enforceNotIsolatedCaller("publishContentProviders"); 9556 synchronized (this) { 9557 final ProcessRecord r = getRecordForAppLocked(caller); 9558 if (DEBUG_MU) 9559 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9560 if (r == null) { 9561 throw new SecurityException( 9562 "Unable to find app for caller " + caller 9563 + " (pid=" + Binder.getCallingPid() 9564 + ") when publishing content providers"); 9565 } 9566 9567 final long origId = Binder.clearCallingIdentity(); 9568 9569 final int N = providers.size(); 9570 for (int i=0; i<N; i++) { 9571 ContentProviderHolder src = providers.get(i); 9572 if (src == null || src.info == null || src.provider == null) { 9573 continue; 9574 } 9575 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9576 if (DEBUG_MU) 9577 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9578 if (dst != null) { 9579 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9580 mProviderMap.putProviderByClass(comp, dst); 9581 String names[] = dst.info.authority.split(";"); 9582 for (int j = 0; j < names.length; j++) { 9583 mProviderMap.putProviderByName(names[j], dst); 9584 } 9585 9586 int NL = mLaunchingProviders.size(); 9587 int j; 9588 for (j=0; j<NL; j++) { 9589 if (mLaunchingProviders.get(j) == dst) { 9590 mLaunchingProviders.remove(j); 9591 j--; 9592 NL--; 9593 } 9594 } 9595 synchronized (dst) { 9596 dst.provider = src.provider; 9597 dst.proc = r; 9598 dst.notifyAll(); 9599 } 9600 updateOomAdjLocked(r); 9601 } 9602 } 9603 9604 Binder.restoreCallingIdentity(origId); 9605 } 9606 } 9607 9608 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9609 ContentProviderConnection conn; 9610 try { 9611 conn = (ContentProviderConnection)connection; 9612 } catch (ClassCastException e) { 9613 String msg ="refContentProvider: " + connection 9614 + " not a ContentProviderConnection"; 9615 Slog.w(TAG, msg); 9616 throw new IllegalArgumentException(msg); 9617 } 9618 if (conn == null) { 9619 throw new NullPointerException("connection is null"); 9620 } 9621 9622 synchronized (this) { 9623 if (stable > 0) { 9624 conn.numStableIncs += stable; 9625 } 9626 stable = conn.stableCount + stable; 9627 if (stable < 0) { 9628 throw new IllegalStateException("stableCount < 0: " + stable); 9629 } 9630 9631 if (unstable > 0) { 9632 conn.numUnstableIncs += unstable; 9633 } 9634 unstable = conn.unstableCount + unstable; 9635 if (unstable < 0) { 9636 throw new IllegalStateException("unstableCount < 0: " + unstable); 9637 } 9638 9639 if ((stable+unstable) <= 0) { 9640 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9641 + stable + " unstable=" + unstable); 9642 } 9643 conn.stableCount = stable; 9644 conn.unstableCount = unstable; 9645 return !conn.dead; 9646 } 9647 } 9648 9649 public void unstableProviderDied(IBinder connection) { 9650 ContentProviderConnection conn; 9651 try { 9652 conn = (ContentProviderConnection)connection; 9653 } catch (ClassCastException e) { 9654 String msg ="refContentProvider: " + connection 9655 + " not a ContentProviderConnection"; 9656 Slog.w(TAG, msg); 9657 throw new IllegalArgumentException(msg); 9658 } 9659 if (conn == null) { 9660 throw new NullPointerException("connection is null"); 9661 } 9662 9663 // Safely retrieve the content provider associated with the connection. 9664 IContentProvider provider; 9665 synchronized (this) { 9666 provider = conn.provider.provider; 9667 } 9668 9669 if (provider == null) { 9670 // Um, yeah, we're way ahead of you. 9671 return; 9672 } 9673 9674 // Make sure the caller is being honest with us. 9675 if (provider.asBinder().pingBinder()) { 9676 // Er, no, still looks good to us. 9677 synchronized (this) { 9678 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9679 + " says " + conn + " died, but we don't agree"); 9680 return; 9681 } 9682 } 9683 9684 // Well look at that! It's dead! 9685 synchronized (this) { 9686 if (conn.provider.provider != provider) { 9687 // But something changed... good enough. 9688 return; 9689 } 9690 9691 ProcessRecord proc = conn.provider.proc; 9692 if (proc == null || proc.thread == null) { 9693 // Seems like the process is already cleaned up. 9694 return; 9695 } 9696 9697 // As far as we're concerned, this is just like receiving a 9698 // death notification... just a bit prematurely. 9699 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9700 + ") early provider death"); 9701 final long ident = Binder.clearCallingIdentity(); 9702 try { 9703 appDiedLocked(proc); 9704 } finally { 9705 Binder.restoreCallingIdentity(ident); 9706 } 9707 } 9708 } 9709 9710 @Override 9711 public void appNotRespondingViaProvider(IBinder connection) { 9712 enforceCallingPermission( 9713 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9714 9715 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9716 if (conn == null) { 9717 Slog.w(TAG, "ContentProviderConnection is null"); 9718 return; 9719 } 9720 9721 final ProcessRecord host = conn.provider.proc; 9722 if (host == null) { 9723 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9724 return; 9725 } 9726 9727 final long token = Binder.clearCallingIdentity(); 9728 try { 9729 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9730 } finally { 9731 Binder.restoreCallingIdentity(token); 9732 } 9733 } 9734 9735 public final void installSystemProviders() { 9736 List<ProviderInfo> providers; 9737 synchronized (this) { 9738 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9739 providers = generateApplicationProvidersLocked(app); 9740 if (providers != null) { 9741 for (int i=providers.size()-1; i>=0; i--) { 9742 ProviderInfo pi = (ProviderInfo)providers.get(i); 9743 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9744 Slog.w(TAG, "Not installing system proc provider " + pi.name 9745 + ": not system .apk"); 9746 providers.remove(i); 9747 } 9748 } 9749 } 9750 } 9751 if (providers != null) { 9752 mSystemThread.installSystemProviders(providers); 9753 } 9754 9755 mCoreSettingsObserver = new CoreSettingsObserver(this); 9756 9757 //mUsageStatsService.monitorPackages(); 9758 } 9759 9760 /** 9761 * Allows apps to retrieve the MIME type of a URI. 9762 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9763 * users, then it does not need permission to access the ContentProvider. 9764 * Either, it needs cross-user uri grants. 9765 * 9766 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9767 * 9768 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9769 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9770 */ 9771 public String getProviderMimeType(Uri uri, int userId) { 9772 enforceNotIsolatedCaller("getProviderMimeType"); 9773 final String name = uri.getAuthority(); 9774 int callingUid = Binder.getCallingUid(); 9775 int callingPid = Binder.getCallingPid(); 9776 long ident = 0; 9777 boolean clearedIdentity = false; 9778 userId = unsafeConvertIncomingUser(userId); 9779 if (canClearIdentity(callingPid, callingUid, userId)) { 9780 clearedIdentity = true; 9781 ident = Binder.clearCallingIdentity(); 9782 } 9783 ContentProviderHolder holder = null; 9784 try { 9785 holder = getContentProviderExternalUnchecked(name, null, userId); 9786 if (holder != null) { 9787 return holder.provider.getType(uri); 9788 } 9789 } catch (RemoteException e) { 9790 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9791 return null; 9792 } finally { 9793 // We need to clear the identity to call removeContentProviderExternalUnchecked 9794 if (!clearedIdentity) { 9795 ident = Binder.clearCallingIdentity(); 9796 } 9797 try { 9798 if (holder != null) { 9799 removeContentProviderExternalUnchecked(name, null, userId); 9800 } 9801 } finally { 9802 Binder.restoreCallingIdentity(ident); 9803 } 9804 } 9805 9806 return null; 9807 } 9808 9809 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9810 if (UserHandle.getUserId(callingUid) == userId) { 9811 return true; 9812 } 9813 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9814 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9815 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9816 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9817 return true; 9818 } 9819 return false; 9820 } 9821 9822 // ========================================================= 9823 // GLOBAL MANAGEMENT 9824 // ========================================================= 9825 9826 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9827 boolean isolated, int isolatedUid) { 9828 String proc = customProcess != null ? customProcess : info.processName; 9829 BatteryStatsImpl.Uid.Proc ps = null; 9830 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9831 int uid = info.uid; 9832 if (isolated) { 9833 if (isolatedUid == 0) { 9834 int userId = UserHandle.getUserId(uid); 9835 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9836 while (true) { 9837 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9838 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9839 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9840 } 9841 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9842 mNextIsolatedProcessUid++; 9843 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9844 // No process for this uid, use it. 9845 break; 9846 } 9847 stepsLeft--; 9848 if (stepsLeft <= 0) { 9849 return null; 9850 } 9851 } 9852 } else { 9853 // Special case for startIsolatedProcess (internal only), where 9854 // the uid of the isolated process is specified by the caller. 9855 uid = isolatedUid; 9856 } 9857 } 9858 return new ProcessRecord(stats, info, proc, uid); 9859 } 9860 9861 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9862 String abiOverride) { 9863 ProcessRecord app; 9864 if (!isolated) { 9865 app = getProcessRecordLocked(info.processName, info.uid, true); 9866 } else { 9867 app = null; 9868 } 9869 9870 if (app == null) { 9871 app = newProcessRecordLocked(info, null, isolated, 0); 9872 mProcessNames.put(info.processName, app.uid, app); 9873 if (isolated) { 9874 mIsolatedProcesses.put(app.uid, app); 9875 } 9876 updateLruProcessLocked(app, false, null); 9877 updateOomAdjLocked(); 9878 } 9879 9880 // This package really, really can not be stopped. 9881 try { 9882 AppGlobals.getPackageManager().setPackageStoppedState( 9883 info.packageName, false, UserHandle.getUserId(app.uid)); 9884 } catch (RemoteException e) { 9885 } catch (IllegalArgumentException e) { 9886 Slog.w(TAG, "Failed trying to unstop package " 9887 + info.packageName + ": " + e); 9888 } 9889 9890 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9891 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9892 app.persistent = true; 9893 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9894 } 9895 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9896 mPersistentStartingProcesses.add(app); 9897 startProcessLocked(app, "added application", app.processName, abiOverride, 9898 null /* entryPoint */, null /* entryPointArgs */); 9899 } 9900 9901 return app; 9902 } 9903 9904 public void unhandledBack() { 9905 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9906 "unhandledBack()"); 9907 9908 synchronized(this) { 9909 final long origId = Binder.clearCallingIdentity(); 9910 try { 9911 getFocusedStack().unhandledBackLocked(); 9912 } finally { 9913 Binder.restoreCallingIdentity(origId); 9914 } 9915 } 9916 } 9917 9918 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9919 enforceNotIsolatedCaller("openContentUri"); 9920 final int userId = UserHandle.getCallingUserId(); 9921 String name = uri.getAuthority(); 9922 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9923 ParcelFileDescriptor pfd = null; 9924 if (cph != null) { 9925 // We record the binder invoker's uid in thread-local storage before 9926 // going to the content provider to open the file. Later, in the code 9927 // that handles all permissions checks, we look for this uid and use 9928 // that rather than the Activity Manager's own uid. The effect is that 9929 // we do the check against the caller's permissions even though it looks 9930 // to the content provider like the Activity Manager itself is making 9931 // the request. 9932 Binder token = new Binder(); 9933 sCallerIdentity.set(new Identity( 9934 token, Binder.getCallingPid(), Binder.getCallingUid())); 9935 try { 9936 pfd = cph.provider.openFile(null, uri, "r", null, token); 9937 } catch (FileNotFoundException e) { 9938 // do nothing; pfd will be returned null 9939 } finally { 9940 // Ensure that whatever happens, we clean up the identity state 9941 sCallerIdentity.remove(); 9942 } 9943 9944 // We've got the fd now, so we're done with the provider. 9945 removeContentProviderExternalUnchecked(name, null, userId); 9946 } else { 9947 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9948 } 9949 return pfd; 9950 } 9951 9952 // Actually is sleeping or shutting down or whatever else in the future 9953 // is an inactive state. 9954 public boolean isSleepingOrShuttingDown() { 9955 return isSleeping() || mShuttingDown; 9956 } 9957 9958 public boolean isSleeping() { 9959 return mSleeping; 9960 } 9961 9962 void onWakefulnessChanged(int wakefulness) { 9963 synchronized(this) { 9964 mWakefulness = wakefulness; 9965 updateSleepIfNeededLocked(); 9966 } 9967 } 9968 9969 void finishRunningVoiceLocked() { 9970 if (mRunningVoice) { 9971 mRunningVoice = false; 9972 updateSleepIfNeededLocked(); 9973 } 9974 } 9975 9976 void updateSleepIfNeededLocked() { 9977 if (mSleeping && !shouldSleepLocked()) { 9978 mSleeping = false; 9979 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9980 } else if (!mSleeping && shouldSleepLocked()) { 9981 mSleeping = true; 9982 mStackSupervisor.goingToSleepLocked(); 9983 9984 // Initialize the wake times of all processes. 9985 checkExcessivePowerUsageLocked(false); 9986 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9987 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9988 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9989 } 9990 } 9991 9992 private boolean shouldSleepLocked() { 9993 // Resume applications while running a voice interactor. 9994 if (mRunningVoice) { 9995 return false; 9996 } 9997 9998 switch (mWakefulness) { 9999 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10000 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10001 // If we're interactive but applications are already paused then defer 10002 // resuming them until the lock screen is hidden. 10003 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10004 case PowerManagerInternal.WAKEFULNESS_DOZING: 10005 // If we're dozing then pause applications whenever the lock screen is shown. 10006 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10007 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10008 default: 10009 // If we're asleep then pause applications unconditionally. 10010 return true; 10011 } 10012 } 10013 10014 /** Pokes the task persister. */ 10015 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10016 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10017 // Never persist the home stack. 10018 return; 10019 } 10020 mTaskPersister.wakeup(task, flush); 10021 } 10022 10023 /** Notifies all listeners when the task stack has changed. */ 10024 void notifyTaskStackChangedLocked() { 10025 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10026 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10027 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10028 } 10029 10030 @Override 10031 public boolean shutdown(int timeout) { 10032 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10033 != PackageManager.PERMISSION_GRANTED) { 10034 throw new SecurityException("Requires permission " 10035 + android.Manifest.permission.SHUTDOWN); 10036 } 10037 10038 boolean timedout = false; 10039 10040 synchronized(this) { 10041 mShuttingDown = true; 10042 updateEventDispatchingLocked(); 10043 timedout = mStackSupervisor.shutdownLocked(timeout); 10044 } 10045 10046 mAppOpsService.shutdown(); 10047 if (mUsageStatsService != null) { 10048 mUsageStatsService.prepareShutdown(); 10049 } 10050 mBatteryStatsService.shutdown(); 10051 synchronized (this) { 10052 mProcessStats.shutdownLocked(); 10053 notifyTaskPersisterLocked(null, true); 10054 } 10055 10056 return timedout; 10057 } 10058 10059 public final void activitySlept(IBinder token) { 10060 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10061 10062 final long origId = Binder.clearCallingIdentity(); 10063 10064 synchronized (this) { 10065 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10066 if (r != null) { 10067 mStackSupervisor.activitySleptLocked(r); 10068 } 10069 } 10070 10071 Binder.restoreCallingIdentity(origId); 10072 } 10073 10074 private String lockScreenShownToString() { 10075 switch (mLockScreenShown) { 10076 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10077 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10078 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10079 default: return "Unknown=" + mLockScreenShown; 10080 } 10081 } 10082 10083 void logLockScreen(String msg) { 10084 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10085 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10086 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10087 + " mSleeping=" + mSleeping); 10088 } 10089 10090 void startRunningVoiceLocked() { 10091 if (!mRunningVoice) { 10092 mRunningVoice = true; 10093 updateSleepIfNeededLocked(); 10094 } 10095 } 10096 10097 private void updateEventDispatchingLocked() { 10098 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10099 } 10100 10101 public void setLockScreenShown(boolean shown) { 10102 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10103 != PackageManager.PERMISSION_GRANTED) { 10104 throw new SecurityException("Requires permission " 10105 + android.Manifest.permission.DEVICE_POWER); 10106 } 10107 10108 synchronized(this) { 10109 long ident = Binder.clearCallingIdentity(); 10110 try { 10111 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10112 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10113 updateSleepIfNeededLocked(); 10114 } finally { 10115 Binder.restoreCallingIdentity(ident); 10116 } 10117 } 10118 } 10119 10120 @Override 10121 public void stopAppSwitches() { 10122 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10123 != PackageManager.PERMISSION_GRANTED) { 10124 throw new SecurityException("Requires permission " 10125 + android.Manifest.permission.STOP_APP_SWITCHES); 10126 } 10127 10128 synchronized(this) { 10129 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10130 + APP_SWITCH_DELAY_TIME; 10131 mDidAppSwitch = false; 10132 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10133 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10134 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10135 } 10136 } 10137 10138 public void resumeAppSwitches() { 10139 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10140 != PackageManager.PERMISSION_GRANTED) { 10141 throw new SecurityException("Requires permission " 10142 + android.Manifest.permission.STOP_APP_SWITCHES); 10143 } 10144 10145 synchronized(this) { 10146 // Note that we don't execute any pending app switches... we will 10147 // let those wait until either the timeout, or the next start 10148 // activity request. 10149 mAppSwitchesAllowedTime = 0; 10150 } 10151 } 10152 10153 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10154 int callingPid, int callingUid, String name) { 10155 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10156 return true; 10157 } 10158 10159 int perm = checkComponentPermission( 10160 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10161 sourceUid, -1, true); 10162 if (perm == PackageManager.PERMISSION_GRANTED) { 10163 return true; 10164 } 10165 10166 // If the actual IPC caller is different from the logical source, then 10167 // also see if they are allowed to control app switches. 10168 if (callingUid != -1 && callingUid != sourceUid) { 10169 perm = checkComponentPermission( 10170 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10171 callingUid, -1, true); 10172 if (perm == PackageManager.PERMISSION_GRANTED) { 10173 return true; 10174 } 10175 } 10176 10177 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10178 return false; 10179 } 10180 10181 public void setDebugApp(String packageName, boolean waitForDebugger, 10182 boolean persistent) { 10183 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10184 "setDebugApp()"); 10185 10186 long ident = Binder.clearCallingIdentity(); 10187 try { 10188 // Note that this is not really thread safe if there are multiple 10189 // callers into it at the same time, but that's not a situation we 10190 // care about. 10191 if (persistent) { 10192 final ContentResolver resolver = mContext.getContentResolver(); 10193 Settings.Global.putString( 10194 resolver, Settings.Global.DEBUG_APP, 10195 packageName); 10196 Settings.Global.putInt( 10197 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10198 waitForDebugger ? 1 : 0); 10199 } 10200 10201 synchronized (this) { 10202 if (!persistent) { 10203 mOrigDebugApp = mDebugApp; 10204 mOrigWaitForDebugger = mWaitForDebugger; 10205 } 10206 mDebugApp = packageName; 10207 mWaitForDebugger = waitForDebugger; 10208 mDebugTransient = !persistent; 10209 if (packageName != null) { 10210 forceStopPackageLocked(packageName, -1, false, false, true, true, 10211 false, UserHandle.USER_ALL, "set debug app"); 10212 } 10213 } 10214 } finally { 10215 Binder.restoreCallingIdentity(ident); 10216 } 10217 } 10218 10219 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10220 synchronized (this) { 10221 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10222 if (!isDebuggable) { 10223 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10224 throw new SecurityException("Process not debuggable: " + app.packageName); 10225 } 10226 } 10227 10228 mOpenGlTraceApp = processName; 10229 } 10230 } 10231 10232 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10233 synchronized (this) { 10234 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10235 if (!isDebuggable) { 10236 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10237 throw new SecurityException("Process not debuggable: " + app.packageName); 10238 } 10239 } 10240 mProfileApp = processName; 10241 mProfileFile = profilerInfo.profileFile; 10242 if (mProfileFd != null) { 10243 try { 10244 mProfileFd.close(); 10245 } catch (IOException e) { 10246 } 10247 mProfileFd = null; 10248 } 10249 mProfileFd = profilerInfo.profileFd; 10250 mSamplingInterval = profilerInfo.samplingInterval; 10251 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10252 mProfileType = 0; 10253 } 10254 } 10255 10256 @Override 10257 public void setAlwaysFinish(boolean enabled) { 10258 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10259 "setAlwaysFinish()"); 10260 10261 Settings.Global.putInt( 10262 mContext.getContentResolver(), 10263 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10264 10265 synchronized (this) { 10266 mAlwaysFinishActivities = enabled; 10267 } 10268 } 10269 10270 @Override 10271 public void setActivityController(IActivityController controller) { 10272 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10273 "setActivityController()"); 10274 synchronized (this) { 10275 mController = controller; 10276 Watchdog.getInstance().setActivityController(controller); 10277 } 10278 } 10279 10280 @Override 10281 public void setUserIsMonkey(boolean userIsMonkey) { 10282 synchronized (this) { 10283 synchronized (mPidsSelfLocked) { 10284 final int callingPid = Binder.getCallingPid(); 10285 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10286 if (precessRecord == null) { 10287 throw new SecurityException("Unknown process: " + callingPid); 10288 } 10289 if (precessRecord.instrumentationUiAutomationConnection == null) { 10290 throw new SecurityException("Only an instrumentation process " 10291 + "with a UiAutomation can call setUserIsMonkey"); 10292 } 10293 } 10294 mUserIsMonkey = userIsMonkey; 10295 } 10296 } 10297 10298 @Override 10299 public boolean isUserAMonkey() { 10300 synchronized (this) { 10301 // If there is a controller also implies the user is a monkey. 10302 return (mUserIsMonkey || mController != null); 10303 } 10304 } 10305 10306 public void requestBugReport() { 10307 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10308 SystemProperties.set("ctl.start", "bugreport"); 10309 } 10310 10311 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10312 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10313 } 10314 10315 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10316 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10317 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10318 } 10319 return KEY_DISPATCHING_TIMEOUT; 10320 } 10321 10322 @Override 10323 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10324 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10325 != PackageManager.PERMISSION_GRANTED) { 10326 throw new SecurityException("Requires permission " 10327 + android.Manifest.permission.FILTER_EVENTS); 10328 } 10329 ProcessRecord proc; 10330 long timeout; 10331 synchronized (this) { 10332 synchronized (mPidsSelfLocked) { 10333 proc = mPidsSelfLocked.get(pid); 10334 } 10335 timeout = getInputDispatchingTimeoutLocked(proc); 10336 } 10337 10338 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10339 return -1; 10340 } 10341 10342 return timeout; 10343 } 10344 10345 /** 10346 * Handle input dispatching timeouts. 10347 * Returns whether input dispatching should be aborted or not. 10348 */ 10349 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10350 final ActivityRecord activity, final ActivityRecord parent, 10351 final boolean aboveSystem, String reason) { 10352 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10353 != PackageManager.PERMISSION_GRANTED) { 10354 throw new SecurityException("Requires permission " 10355 + android.Manifest.permission.FILTER_EVENTS); 10356 } 10357 10358 final String annotation; 10359 if (reason == null) { 10360 annotation = "Input dispatching timed out"; 10361 } else { 10362 annotation = "Input dispatching timed out (" + reason + ")"; 10363 } 10364 10365 if (proc != null) { 10366 synchronized (this) { 10367 if (proc.debugging) { 10368 return false; 10369 } 10370 10371 if (mDidDexOpt) { 10372 // Give more time since we were dexopting. 10373 mDidDexOpt = false; 10374 return false; 10375 } 10376 10377 if (proc.instrumentationClass != null) { 10378 Bundle info = new Bundle(); 10379 info.putString("shortMsg", "keyDispatchingTimedOut"); 10380 info.putString("longMsg", annotation); 10381 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10382 return true; 10383 } 10384 } 10385 mHandler.post(new Runnable() { 10386 @Override 10387 public void run() { 10388 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10389 } 10390 }); 10391 } 10392 10393 return true; 10394 } 10395 10396 public Bundle getAssistContextExtras(int requestType) { 10397 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10398 UserHandle.getCallingUserId()); 10399 if (pae == null) { 10400 return null; 10401 } 10402 synchronized (pae) { 10403 while (!pae.haveResult) { 10404 try { 10405 pae.wait(); 10406 } catch (InterruptedException e) { 10407 } 10408 } 10409 if (pae.result != null) { 10410 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10411 } 10412 } 10413 synchronized (this) { 10414 mPendingAssistExtras.remove(pae); 10415 mHandler.removeCallbacks(pae); 10416 } 10417 return pae.extras; 10418 } 10419 10420 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10421 int userHandle) { 10422 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10423 "getAssistContextExtras()"); 10424 PendingAssistExtras pae; 10425 Bundle extras = new Bundle(); 10426 synchronized (this) { 10427 ActivityRecord activity = getFocusedStack().mResumedActivity; 10428 if (activity == null) { 10429 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10430 return null; 10431 } 10432 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10433 if (activity.app == null || activity.app.thread == null) { 10434 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10435 return null; 10436 } 10437 if (activity.app.pid == Binder.getCallingPid()) { 10438 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10439 return null; 10440 } 10441 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10442 try { 10443 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10444 requestType); 10445 mPendingAssistExtras.add(pae); 10446 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10447 } catch (RemoteException e) { 10448 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10449 return null; 10450 } 10451 return pae; 10452 } 10453 } 10454 10455 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10456 PendingAssistExtras pae = (PendingAssistExtras)token; 10457 synchronized (pae) { 10458 pae.result = extras; 10459 pae.haveResult = true; 10460 pae.notifyAll(); 10461 if (pae.intent == null) { 10462 // Caller is just waiting for the result. 10463 return; 10464 } 10465 } 10466 10467 // We are now ready to launch the assist activity. 10468 synchronized (this) { 10469 boolean exists = mPendingAssistExtras.remove(pae); 10470 mHandler.removeCallbacks(pae); 10471 if (!exists) { 10472 // Timed out. 10473 return; 10474 } 10475 } 10476 pae.intent.replaceExtras(extras); 10477 if (pae.hint != null) { 10478 pae.intent.putExtra(pae.hint, true); 10479 } 10480 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10481 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10482 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10483 closeSystemDialogs("assist"); 10484 try { 10485 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10486 } catch (ActivityNotFoundException e) { 10487 Slog.w(TAG, "No activity to handle assist action.", e); 10488 } 10489 } 10490 10491 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10492 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10493 } 10494 10495 public void registerProcessObserver(IProcessObserver observer) { 10496 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10497 "registerProcessObserver()"); 10498 synchronized (this) { 10499 mProcessObservers.register(observer); 10500 } 10501 } 10502 10503 @Override 10504 public void unregisterProcessObserver(IProcessObserver observer) { 10505 synchronized (this) { 10506 mProcessObservers.unregister(observer); 10507 } 10508 } 10509 10510 @Override 10511 public boolean convertFromTranslucent(IBinder token) { 10512 final long origId = Binder.clearCallingIdentity(); 10513 try { 10514 synchronized (this) { 10515 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10516 if (r == null) { 10517 return false; 10518 } 10519 final boolean translucentChanged = r.changeWindowTranslucency(true); 10520 if (translucentChanged) { 10521 r.task.stack.releaseBackgroundResources(); 10522 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10523 } 10524 mWindowManager.setAppFullscreen(token, true); 10525 return translucentChanged; 10526 } 10527 } finally { 10528 Binder.restoreCallingIdentity(origId); 10529 } 10530 } 10531 10532 @Override 10533 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10534 final long origId = Binder.clearCallingIdentity(); 10535 try { 10536 synchronized (this) { 10537 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10538 if (r == null) { 10539 return false; 10540 } 10541 int index = r.task.mActivities.lastIndexOf(r); 10542 if (index > 0) { 10543 ActivityRecord under = r.task.mActivities.get(index - 1); 10544 under.returningOptions = options; 10545 } 10546 final boolean translucentChanged = r.changeWindowTranslucency(false); 10547 if (translucentChanged) { 10548 r.task.stack.convertToTranslucent(r); 10549 } 10550 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10551 mWindowManager.setAppFullscreen(token, false); 10552 return translucentChanged; 10553 } 10554 } finally { 10555 Binder.restoreCallingIdentity(origId); 10556 } 10557 } 10558 10559 @Override 10560 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10561 final long origId = Binder.clearCallingIdentity(); 10562 try { 10563 synchronized (this) { 10564 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10565 if (r != null) { 10566 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10567 } 10568 } 10569 return false; 10570 } finally { 10571 Binder.restoreCallingIdentity(origId); 10572 } 10573 } 10574 10575 @Override 10576 public boolean isBackgroundVisibleBehind(IBinder token) { 10577 final long origId = Binder.clearCallingIdentity(); 10578 try { 10579 synchronized (this) { 10580 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10581 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10582 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10583 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10584 return visible; 10585 } 10586 } finally { 10587 Binder.restoreCallingIdentity(origId); 10588 } 10589 } 10590 10591 @Override 10592 public ActivityOptions getActivityOptions(IBinder token) { 10593 final long origId = Binder.clearCallingIdentity(); 10594 try { 10595 synchronized (this) { 10596 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10597 if (r != null) { 10598 final ActivityOptions activityOptions = r.pendingOptions; 10599 r.pendingOptions = null; 10600 return activityOptions; 10601 } 10602 return null; 10603 } 10604 } finally { 10605 Binder.restoreCallingIdentity(origId); 10606 } 10607 } 10608 10609 @Override 10610 public void setImmersive(IBinder token, boolean immersive) { 10611 synchronized(this) { 10612 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10613 if (r == null) { 10614 throw new IllegalArgumentException(); 10615 } 10616 r.immersive = immersive; 10617 10618 // update associated state if we're frontmost 10619 if (r == mFocusedActivity) { 10620 if (DEBUG_IMMERSIVE) { 10621 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10622 } 10623 applyUpdateLockStateLocked(r); 10624 } 10625 } 10626 } 10627 10628 @Override 10629 public boolean isImmersive(IBinder token) { 10630 synchronized (this) { 10631 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10632 if (r == null) { 10633 throw new IllegalArgumentException(); 10634 } 10635 return r.immersive; 10636 } 10637 } 10638 10639 public boolean isTopActivityImmersive() { 10640 enforceNotIsolatedCaller("startActivity"); 10641 synchronized (this) { 10642 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10643 return (r != null) ? r.immersive : false; 10644 } 10645 } 10646 10647 @Override 10648 public boolean isTopOfTask(IBinder token) { 10649 synchronized (this) { 10650 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10651 if (r == null) { 10652 throw new IllegalArgumentException(); 10653 } 10654 return r.task.getTopActivity() == r; 10655 } 10656 } 10657 10658 public final void enterSafeMode() { 10659 synchronized(this) { 10660 // It only makes sense to do this before the system is ready 10661 // and started launching other packages. 10662 if (!mSystemReady) { 10663 try { 10664 AppGlobals.getPackageManager().enterSafeMode(); 10665 } catch (RemoteException e) { 10666 } 10667 } 10668 10669 mSafeMode = true; 10670 } 10671 } 10672 10673 public final void showSafeModeOverlay() { 10674 View v = LayoutInflater.from(mContext).inflate( 10675 com.android.internal.R.layout.safe_mode, null); 10676 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10677 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10678 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10679 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10680 lp.gravity = Gravity.BOTTOM | Gravity.START; 10681 lp.format = v.getBackground().getOpacity(); 10682 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10683 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10684 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10685 ((WindowManager)mContext.getSystemService( 10686 Context.WINDOW_SERVICE)).addView(v, lp); 10687 } 10688 10689 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10690 if (!(sender instanceof PendingIntentRecord)) { 10691 return; 10692 } 10693 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10694 synchronized (stats) { 10695 if (mBatteryStatsService.isOnBattery()) { 10696 mBatteryStatsService.enforceCallingPermission(); 10697 PendingIntentRecord rec = (PendingIntentRecord)sender; 10698 int MY_UID = Binder.getCallingUid(); 10699 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10700 BatteryStatsImpl.Uid.Pkg pkg = 10701 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10702 sourcePkg != null ? sourcePkg : rec.key.packageName); 10703 pkg.incWakeupsLocked(); 10704 } 10705 } 10706 } 10707 10708 public boolean killPids(int[] pids, String pReason, boolean secure) { 10709 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10710 throw new SecurityException("killPids only available to the system"); 10711 } 10712 String reason = (pReason == null) ? "Unknown" : pReason; 10713 // XXX Note: don't acquire main activity lock here, because the window 10714 // manager calls in with its locks held. 10715 10716 boolean killed = false; 10717 synchronized (mPidsSelfLocked) { 10718 int[] types = new int[pids.length]; 10719 int worstType = 0; 10720 for (int i=0; i<pids.length; i++) { 10721 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10722 if (proc != null) { 10723 int type = proc.setAdj; 10724 types[i] = type; 10725 if (type > worstType) { 10726 worstType = type; 10727 } 10728 } 10729 } 10730 10731 // If the worst oom_adj is somewhere in the cached proc LRU range, 10732 // then constrain it so we will kill all cached procs. 10733 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10734 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10735 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10736 } 10737 10738 // If this is not a secure call, don't let it kill processes that 10739 // are important. 10740 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10741 worstType = ProcessList.SERVICE_ADJ; 10742 } 10743 10744 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10745 for (int i=0; i<pids.length; i++) { 10746 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10747 if (proc == null) { 10748 continue; 10749 } 10750 int adj = proc.setAdj; 10751 if (adj >= worstType && !proc.killedByAm) { 10752 proc.kill(reason, true); 10753 killed = true; 10754 } 10755 } 10756 } 10757 return killed; 10758 } 10759 10760 @Override 10761 public void killUid(int uid, String reason) { 10762 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10763 throw new SecurityException("killUid only available to the system"); 10764 } 10765 synchronized (this) { 10766 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10767 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10768 reason != null ? reason : "kill uid"); 10769 } 10770 } 10771 10772 @Override 10773 public boolean killProcessesBelowForeground(String reason) { 10774 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10775 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10776 } 10777 10778 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10779 } 10780 10781 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10782 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10783 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10784 } 10785 10786 boolean killed = false; 10787 synchronized (mPidsSelfLocked) { 10788 final int size = mPidsSelfLocked.size(); 10789 for (int i = 0; i < size; i++) { 10790 final int pid = mPidsSelfLocked.keyAt(i); 10791 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10792 if (proc == null) continue; 10793 10794 final int adj = proc.setAdj; 10795 if (adj > belowAdj && !proc.killedByAm) { 10796 proc.kill(reason, true); 10797 killed = true; 10798 } 10799 } 10800 } 10801 return killed; 10802 } 10803 10804 @Override 10805 public void hang(final IBinder who, boolean allowRestart) { 10806 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10807 != PackageManager.PERMISSION_GRANTED) { 10808 throw new SecurityException("Requires permission " 10809 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10810 } 10811 10812 final IBinder.DeathRecipient death = new DeathRecipient() { 10813 @Override 10814 public void binderDied() { 10815 synchronized (this) { 10816 notifyAll(); 10817 } 10818 } 10819 }; 10820 10821 try { 10822 who.linkToDeath(death, 0); 10823 } catch (RemoteException e) { 10824 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10825 return; 10826 } 10827 10828 synchronized (this) { 10829 Watchdog.getInstance().setAllowRestart(allowRestart); 10830 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10831 synchronized (death) { 10832 while (who.isBinderAlive()) { 10833 try { 10834 death.wait(); 10835 } catch (InterruptedException e) { 10836 } 10837 } 10838 } 10839 Watchdog.getInstance().setAllowRestart(true); 10840 } 10841 } 10842 10843 @Override 10844 public void restart() { 10845 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10846 != PackageManager.PERMISSION_GRANTED) { 10847 throw new SecurityException("Requires permission " 10848 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10849 } 10850 10851 Log.i(TAG, "Sending shutdown broadcast..."); 10852 10853 BroadcastReceiver br = new BroadcastReceiver() { 10854 @Override public void onReceive(Context context, Intent intent) { 10855 // Now the broadcast is done, finish up the low-level shutdown. 10856 Log.i(TAG, "Shutting down activity manager..."); 10857 shutdown(10000); 10858 Log.i(TAG, "Shutdown complete, restarting!"); 10859 Process.killProcess(Process.myPid()); 10860 System.exit(10); 10861 } 10862 }; 10863 10864 // First send the high-level shut down broadcast. 10865 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10866 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10867 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10868 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10869 mContext.sendOrderedBroadcastAsUser(intent, 10870 UserHandle.ALL, null, br, mHandler, 0, null, null); 10871 */ 10872 br.onReceive(mContext, intent); 10873 } 10874 10875 private long getLowRamTimeSinceIdle(long now) { 10876 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10877 } 10878 10879 @Override 10880 public void performIdleMaintenance() { 10881 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10882 != PackageManager.PERMISSION_GRANTED) { 10883 throw new SecurityException("Requires permission " 10884 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10885 } 10886 10887 synchronized (this) { 10888 final long now = SystemClock.uptimeMillis(); 10889 final long timeSinceLastIdle = now - mLastIdleTime; 10890 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10891 mLastIdleTime = now; 10892 mLowRamTimeSinceLastIdle = 0; 10893 if (mLowRamStartTime != 0) { 10894 mLowRamStartTime = now; 10895 } 10896 10897 StringBuilder sb = new StringBuilder(128); 10898 sb.append("Idle maintenance over "); 10899 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10900 sb.append(" low RAM for "); 10901 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10902 Slog.i(TAG, sb.toString()); 10903 10904 // If at least 1/3 of our time since the last idle period has been spent 10905 // with RAM low, then we want to kill processes. 10906 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10907 10908 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10909 ProcessRecord proc = mLruProcesses.get(i); 10910 if (proc.notCachedSinceIdle) { 10911 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10912 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10913 if (doKilling && proc.initialIdlePss != 0 10914 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10915 proc.kill("idle maint (pss " + proc.lastPss 10916 + " from " + proc.initialIdlePss + ")", true); 10917 } 10918 } 10919 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10920 proc.notCachedSinceIdle = true; 10921 proc.initialIdlePss = 0; 10922 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10923 isSleeping(), now); 10924 } 10925 } 10926 10927 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10928 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10929 } 10930 } 10931 10932 private void retrieveSettings() { 10933 final ContentResolver resolver = mContext.getContentResolver(); 10934 String debugApp = Settings.Global.getString( 10935 resolver, Settings.Global.DEBUG_APP); 10936 boolean waitForDebugger = Settings.Global.getInt( 10937 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10938 boolean alwaysFinishActivities = Settings.Global.getInt( 10939 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10940 boolean forceRtl = Settings.Global.getInt( 10941 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10942 // Transfer any global setting for forcing RTL layout, into a System Property 10943 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10944 10945 Configuration configuration = new Configuration(); 10946 Settings.System.getConfiguration(resolver, configuration); 10947 if (forceRtl) { 10948 // This will take care of setting the correct layout direction flags 10949 configuration.setLayoutDirection(configuration.locale); 10950 } 10951 10952 synchronized (this) { 10953 mDebugApp = mOrigDebugApp = debugApp; 10954 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10955 mAlwaysFinishActivities = alwaysFinishActivities; 10956 // This happens before any activities are started, so we can 10957 // change mConfiguration in-place. 10958 updateConfigurationLocked(configuration, null, false, true); 10959 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10960 } 10961 } 10962 10963 /** Loads resources after the current configuration has been set. */ 10964 private void loadResourcesOnSystemReady() { 10965 final Resources res = mContext.getResources(); 10966 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10967 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10968 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10969 } 10970 10971 public boolean testIsSystemReady() { 10972 // no need to synchronize(this) just to read & return the value 10973 return mSystemReady; 10974 } 10975 10976 private static File getCalledPreBootReceiversFile() { 10977 File dataDir = Environment.getDataDirectory(); 10978 File systemDir = new File(dataDir, "system"); 10979 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10980 return fname; 10981 } 10982 10983 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10984 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10985 File file = getCalledPreBootReceiversFile(); 10986 FileInputStream fis = null; 10987 try { 10988 fis = new FileInputStream(file); 10989 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10990 int fvers = dis.readInt(); 10991 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10992 String vers = dis.readUTF(); 10993 String codename = dis.readUTF(); 10994 String build = dis.readUTF(); 10995 if (android.os.Build.VERSION.RELEASE.equals(vers) 10996 && android.os.Build.VERSION.CODENAME.equals(codename) 10997 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10998 int num = dis.readInt(); 10999 while (num > 0) { 11000 num--; 11001 String pkg = dis.readUTF(); 11002 String cls = dis.readUTF(); 11003 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11004 } 11005 } 11006 } 11007 } catch (FileNotFoundException e) { 11008 } catch (IOException e) { 11009 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11010 } finally { 11011 if (fis != null) { 11012 try { 11013 fis.close(); 11014 } catch (IOException e) { 11015 } 11016 } 11017 } 11018 return lastDoneReceivers; 11019 } 11020 11021 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11022 File file = getCalledPreBootReceiversFile(); 11023 FileOutputStream fos = null; 11024 DataOutputStream dos = null; 11025 try { 11026 fos = new FileOutputStream(file); 11027 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11028 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11029 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11030 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11031 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11032 dos.writeInt(list.size()); 11033 for (int i=0; i<list.size(); i++) { 11034 dos.writeUTF(list.get(i).getPackageName()); 11035 dos.writeUTF(list.get(i).getClassName()); 11036 } 11037 } catch (IOException e) { 11038 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11039 file.delete(); 11040 } finally { 11041 FileUtils.sync(fos); 11042 if (dos != null) { 11043 try { 11044 dos.close(); 11045 } catch (IOException e) { 11046 // TODO Auto-generated catch block 11047 e.printStackTrace(); 11048 } 11049 } 11050 } 11051 } 11052 11053 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11054 ArrayList<ComponentName> doneReceivers, int userId) { 11055 boolean waitingUpdate = false; 11056 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11057 List<ResolveInfo> ris = null; 11058 try { 11059 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11060 intent, null, 0, userId); 11061 } catch (RemoteException e) { 11062 } 11063 if (ris != null) { 11064 for (int i=ris.size()-1; i>=0; i--) { 11065 if ((ris.get(i).activityInfo.applicationInfo.flags 11066 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11067 ris.remove(i); 11068 } 11069 } 11070 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11071 11072 // For User 0, load the version number. When delivering to a new user, deliver 11073 // to all receivers. 11074 if (userId == UserHandle.USER_OWNER) { 11075 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11076 for (int i=0; i<ris.size(); i++) { 11077 ActivityInfo ai = ris.get(i).activityInfo; 11078 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11079 if (lastDoneReceivers.contains(comp)) { 11080 // We already did the pre boot receiver for this app with the current 11081 // platform version, so don't do it again... 11082 ris.remove(i); 11083 i--; 11084 // ...however, do keep it as one that has been done, so we don't 11085 // forget about it when rewriting the file of last done receivers. 11086 doneReceivers.add(comp); 11087 } 11088 } 11089 } 11090 11091 // If primary user, send broadcast to all available users, else just to userId 11092 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11093 : new int[] { userId }; 11094 for (int i = 0; i < ris.size(); i++) { 11095 ActivityInfo ai = ris.get(i).activityInfo; 11096 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11097 doneReceivers.add(comp); 11098 intent.setComponent(comp); 11099 for (int j=0; j<users.length; j++) { 11100 IIntentReceiver finisher = null; 11101 // On last receiver and user, set up a completion callback 11102 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11103 finisher = new IIntentReceiver.Stub() { 11104 public void performReceive(Intent intent, int resultCode, 11105 String data, Bundle extras, boolean ordered, 11106 boolean sticky, int sendingUser) { 11107 // The raw IIntentReceiver interface is called 11108 // with the AM lock held, so redispatch to 11109 // execute our code without the lock. 11110 mHandler.post(onFinishCallback); 11111 } 11112 }; 11113 } 11114 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11115 + " for user " + users[j]); 11116 broadcastIntentLocked(null, null, intent, null, finisher, 11117 0, null, null, null, AppOpsManager.OP_NONE, 11118 true, false, MY_PID, Process.SYSTEM_UID, 11119 users[j]); 11120 if (finisher != null) { 11121 waitingUpdate = true; 11122 } 11123 } 11124 } 11125 } 11126 11127 return waitingUpdate; 11128 } 11129 11130 public void systemReady(final Runnable goingCallback) { 11131 synchronized(this) { 11132 if (mSystemReady) { 11133 // If we're done calling all the receivers, run the next "boot phase" passed in 11134 // by the SystemServer 11135 if (goingCallback != null) { 11136 goingCallback.run(); 11137 } 11138 return; 11139 } 11140 11141 // Make sure we have the current profile info, since it is needed for 11142 // security checks. 11143 updateCurrentProfileIdsLocked(); 11144 11145 if (mRecentTasks == null) { 11146 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11147 if (!mRecentTasks.isEmpty()) { 11148 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11149 } 11150 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11151 mTaskPersister.startPersisting(); 11152 } 11153 11154 // Check to see if there are any update receivers to run. 11155 if (!mDidUpdate) { 11156 if (mWaitingUpdate) { 11157 return; 11158 } 11159 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11160 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11161 public void run() { 11162 synchronized (ActivityManagerService.this) { 11163 mDidUpdate = true; 11164 } 11165 writeLastDonePreBootReceivers(doneReceivers); 11166 showBootMessage(mContext.getText( 11167 R.string.android_upgrading_complete), 11168 false); 11169 systemReady(goingCallback); 11170 } 11171 }, doneReceivers, UserHandle.USER_OWNER); 11172 11173 if (mWaitingUpdate) { 11174 return; 11175 } 11176 mDidUpdate = true; 11177 } 11178 11179 mAppOpsService.systemReady(); 11180 mSystemReady = true; 11181 } 11182 11183 ArrayList<ProcessRecord> procsToKill = null; 11184 synchronized(mPidsSelfLocked) { 11185 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11186 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11187 if (!isAllowedWhileBooting(proc.info)){ 11188 if (procsToKill == null) { 11189 procsToKill = new ArrayList<ProcessRecord>(); 11190 } 11191 procsToKill.add(proc); 11192 } 11193 } 11194 } 11195 11196 synchronized(this) { 11197 if (procsToKill != null) { 11198 for (int i=procsToKill.size()-1; i>=0; i--) { 11199 ProcessRecord proc = procsToKill.get(i); 11200 Slog.i(TAG, "Removing system update proc: " + proc); 11201 removeProcessLocked(proc, true, false, "system update done"); 11202 } 11203 } 11204 11205 // Now that we have cleaned up any update processes, we 11206 // are ready to start launching real processes and know that 11207 // we won't trample on them any more. 11208 mProcessesReady = true; 11209 } 11210 11211 Slog.i(TAG, "System now ready"); 11212 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11213 SystemClock.uptimeMillis()); 11214 11215 synchronized(this) { 11216 // Make sure we have no pre-ready processes sitting around. 11217 11218 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11219 ResolveInfo ri = mContext.getPackageManager() 11220 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11221 STOCK_PM_FLAGS); 11222 CharSequence errorMsg = null; 11223 if (ri != null) { 11224 ActivityInfo ai = ri.activityInfo; 11225 ApplicationInfo app = ai.applicationInfo; 11226 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11227 mTopAction = Intent.ACTION_FACTORY_TEST; 11228 mTopData = null; 11229 mTopComponent = new ComponentName(app.packageName, 11230 ai.name); 11231 } else { 11232 errorMsg = mContext.getResources().getText( 11233 com.android.internal.R.string.factorytest_not_system); 11234 } 11235 } else { 11236 errorMsg = mContext.getResources().getText( 11237 com.android.internal.R.string.factorytest_no_action); 11238 } 11239 if (errorMsg != null) { 11240 mTopAction = null; 11241 mTopData = null; 11242 mTopComponent = null; 11243 Message msg = Message.obtain(); 11244 msg.what = SHOW_FACTORY_ERROR_MSG; 11245 msg.getData().putCharSequence("msg", errorMsg); 11246 mHandler.sendMessage(msg); 11247 } 11248 } 11249 } 11250 11251 retrieveSettings(); 11252 loadResourcesOnSystemReady(); 11253 11254 synchronized (this) { 11255 readGrantedUriPermissionsLocked(); 11256 } 11257 11258 if (goingCallback != null) goingCallback.run(); 11259 11260 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11261 Integer.toString(mCurrentUserId), mCurrentUserId); 11262 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11263 Integer.toString(mCurrentUserId), mCurrentUserId); 11264 mSystemServiceManager.startUser(mCurrentUserId); 11265 11266 synchronized (this) { 11267 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11268 try { 11269 List apps = AppGlobals.getPackageManager(). 11270 getPersistentApplications(STOCK_PM_FLAGS); 11271 if (apps != null) { 11272 int N = apps.size(); 11273 int i; 11274 for (i=0; i<N; i++) { 11275 ApplicationInfo info 11276 = (ApplicationInfo)apps.get(i); 11277 if (info != null && 11278 !info.packageName.equals("android")) { 11279 addAppLocked(info, false, null /* ABI override */); 11280 } 11281 } 11282 } 11283 } catch (RemoteException ex) { 11284 // pm is in same process, this will never happen. 11285 } 11286 } 11287 11288 // Start up initial activity. 11289 mBooting = true; 11290 startHomeActivityLocked(mCurrentUserId); 11291 11292 try { 11293 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11294 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11295 + " data partition or your device will be unstable."); 11296 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11297 } 11298 } catch (RemoteException e) { 11299 } 11300 11301 if (!Build.isFingerprintConsistent()) { 11302 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11303 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11304 } 11305 11306 long ident = Binder.clearCallingIdentity(); 11307 try { 11308 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11309 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11310 | Intent.FLAG_RECEIVER_FOREGROUND); 11311 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11312 broadcastIntentLocked(null, null, intent, 11313 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11314 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11315 intent = new Intent(Intent.ACTION_USER_STARTING); 11316 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11317 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11318 broadcastIntentLocked(null, null, intent, 11319 null, new IIntentReceiver.Stub() { 11320 @Override 11321 public void performReceive(Intent intent, int resultCode, String data, 11322 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11323 throws RemoteException { 11324 } 11325 }, 0, null, null, 11326 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11327 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11328 } catch (Throwable t) { 11329 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11330 } finally { 11331 Binder.restoreCallingIdentity(ident); 11332 } 11333 mStackSupervisor.resumeTopActivitiesLocked(); 11334 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11335 } 11336 } 11337 11338 private boolean makeAppCrashingLocked(ProcessRecord app, 11339 String shortMsg, String longMsg, String stackTrace) { 11340 app.crashing = true; 11341 app.crashingReport = generateProcessError(app, 11342 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11343 startAppProblemLocked(app); 11344 app.stopFreezingAllLocked(); 11345 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11346 } 11347 11348 private void makeAppNotRespondingLocked(ProcessRecord app, 11349 String activity, String shortMsg, String longMsg) { 11350 app.notResponding = true; 11351 app.notRespondingReport = generateProcessError(app, 11352 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11353 activity, shortMsg, longMsg, null); 11354 startAppProblemLocked(app); 11355 app.stopFreezingAllLocked(); 11356 } 11357 11358 /** 11359 * Generate a process error record, suitable for attachment to a ProcessRecord. 11360 * 11361 * @param app The ProcessRecord in which the error occurred. 11362 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11363 * ActivityManager.AppErrorStateInfo 11364 * @param activity The activity associated with the crash, if known. 11365 * @param shortMsg Short message describing the crash. 11366 * @param longMsg Long message describing the crash. 11367 * @param stackTrace Full crash stack trace, may be null. 11368 * 11369 * @return Returns a fully-formed AppErrorStateInfo record. 11370 */ 11371 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11372 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11373 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11374 11375 report.condition = condition; 11376 report.processName = app.processName; 11377 report.pid = app.pid; 11378 report.uid = app.info.uid; 11379 report.tag = activity; 11380 report.shortMsg = shortMsg; 11381 report.longMsg = longMsg; 11382 report.stackTrace = stackTrace; 11383 11384 return report; 11385 } 11386 11387 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11388 synchronized (this) { 11389 app.crashing = false; 11390 app.crashingReport = null; 11391 app.notResponding = false; 11392 app.notRespondingReport = null; 11393 if (app.anrDialog == fromDialog) { 11394 app.anrDialog = null; 11395 } 11396 if (app.waitDialog == fromDialog) { 11397 app.waitDialog = null; 11398 } 11399 if (app.pid > 0 && app.pid != MY_PID) { 11400 handleAppCrashLocked(app, null, null, null); 11401 app.kill("user request after error", true); 11402 } 11403 } 11404 } 11405 11406 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11407 String stackTrace) { 11408 long now = SystemClock.uptimeMillis(); 11409 11410 Long crashTime; 11411 if (!app.isolated) { 11412 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11413 } else { 11414 crashTime = null; 11415 } 11416 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11417 // This process loses! 11418 Slog.w(TAG, "Process " + app.info.processName 11419 + " has crashed too many times: killing!"); 11420 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11421 app.userId, app.info.processName, app.uid); 11422 mStackSupervisor.handleAppCrashLocked(app); 11423 if (!app.persistent) { 11424 // We don't want to start this process again until the user 11425 // explicitly does so... but for persistent process, we really 11426 // need to keep it running. If a persistent process is actually 11427 // repeatedly crashing, then badness for everyone. 11428 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11429 app.info.processName); 11430 if (!app.isolated) { 11431 // XXX We don't have a way to mark isolated processes 11432 // as bad, since they don't have a peristent identity. 11433 mBadProcesses.put(app.info.processName, app.uid, 11434 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11435 mProcessCrashTimes.remove(app.info.processName, app.uid); 11436 } 11437 app.bad = true; 11438 app.removed = true; 11439 // Don't let services in this process be restarted and potentially 11440 // annoy the user repeatedly. Unless it is persistent, since those 11441 // processes run critical code. 11442 removeProcessLocked(app, false, false, "crash"); 11443 mStackSupervisor.resumeTopActivitiesLocked(); 11444 return false; 11445 } 11446 mStackSupervisor.resumeTopActivitiesLocked(); 11447 } else { 11448 mStackSupervisor.finishTopRunningActivityLocked(app); 11449 } 11450 11451 // Bump up the crash count of any services currently running in the proc. 11452 for (int i=app.services.size()-1; i>=0; i--) { 11453 // Any services running in the application need to be placed 11454 // back in the pending list. 11455 ServiceRecord sr = app.services.valueAt(i); 11456 sr.crashCount++; 11457 } 11458 11459 // If the crashing process is what we consider to be the "home process" and it has been 11460 // replaced by a third-party app, clear the package preferred activities from packages 11461 // with a home activity running in the process to prevent a repeatedly crashing app 11462 // from blocking the user to manually clear the list. 11463 final ArrayList<ActivityRecord> activities = app.activities; 11464 if (app == mHomeProcess && activities.size() > 0 11465 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11466 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11467 final ActivityRecord r = activities.get(activityNdx); 11468 if (r.isHomeActivity()) { 11469 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11470 try { 11471 ActivityThread.getPackageManager() 11472 .clearPackagePreferredActivities(r.packageName); 11473 } catch (RemoteException c) { 11474 // pm is in same process, this will never happen. 11475 } 11476 } 11477 } 11478 } 11479 11480 if (!app.isolated) { 11481 // XXX Can't keep track of crash times for isolated processes, 11482 // because they don't have a perisistent identity. 11483 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11484 } 11485 11486 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11487 return true; 11488 } 11489 11490 void startAppProblemLocked(ProcessRecord app) { 11491 // If this app is not running under the current user, then we 11492 // can't give it a report button because that would require 11493 // launching the report UI under a different user. 11494 app.errorReportReceiver = null; 11495 11496 for (int userId : mCurrentProfileIds) { 11497 if (app.userId == userId) { 11498 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11499 mContext, app.info.packageName, app.info.flags); 11500 } 11501 } 11502 skipCurrentReceiverLocked(app); 11503 } 11504 11505 void skipCurrentReceiverLocked(ProcessRecord app) { 11506 for (BroadcastQueue queue : mBroadcastQueues) { 11507 queue.skipCurrentReceiverLocked(app); 11508 } 11509 } 11510 11511 /** 11512 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11513 * The application process will exit immediately after this call returns. 11514 * @param app object of the crashing app, null for the system server 11515 * @param crashInfo describing the exception 11516 */ 11517 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11518 ProcessRecord r = findAppProcess(app, "Crash"); 11519 final String processName = app == null ? "system_server" 11520 : (r == null ? "unknown" : r.processName); 11521 11522 handleApplicationCrashInner("crash", r, processName, crashInfo); 11523 } 11524 11525 /* Native crash reporting uses this inner version because it needs to be somewhat 11526 * decoupled from the AM-managed cleanup lifecycle 11527 */ 11528 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11529 ApplicationErrorReport.CrashInfo crashInfo) { 11530 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11531 UserHandle.getUserId(Binder.getCallingUid()), processName, 11532 r == null ? -1 : r.info.flags, 11533 crashInfo.exceptionClassName, 11534 crashInfo.exceptionMessage, 11535 crashInfo.throwFileName, 11536 crashInfo.throwLineNumber); 11537 11538 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11539 11540 crashApplication(r, crashInfo); 11541 } 11542 11543 public void handleApplicationStrictModeViolation( 11544 IBinder app, 11545 int violationMask, 11546 StrictMode.ViolationInfo info) { 11547 ProcessRecord r = findAppProcess(app, "StrictMode"); 11548 if (r == null) { 11549 return; 11550 } 11551 11552 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11553 Integer stackFingerprint = info.hashCode(); 11554 boolean logIt = true; 11555 synchronized (mAlreadyLoggedViolatedStacks) { 11556 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11557 logIt = false; 11558 // TODO: sub-sample into EventLog for these, with 11559 // the info.durationMillis? Then we'd get 11560 // the relative pain numbers, without logging all 11561 // the stack traces repeatedly. We'd want to do 11562 // likewise in the client code, which also does 11563 // dup suppression, before the Binder call. 11564 } else { 11565 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11566 mAlreadyLoggedViolatedStacks.clear(); 11567 } 11568 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11569 } 11570 } 11571 if (logIt) { 11572 logStrictModeViolationToDropBox(r, info); 11573 } 11574 } 11575 11576 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11577 AppErrorResult result = new AppErrorResult(); 11578 synchronized (this) { 11579 final long origId = Binder.clearCallingIdentity(); 11580 11581 Message msg = Message.obtain(); 11582 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11583 HashMap<String, Object> data = new HashMap<String, Object>(); 11584 data.put("result", result); 11585 data.put("app", r); 11586 data.put("violationMask", violationMask); 11587 data.put("info", info); 11588 msg.obj = data; 11589 mHandler.sendMessage(msg); 11590 11591 Binder.restoreCallingIdentity(origId); 11592 } 11593 int res = result.get(); 11594 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11595 } 11596 } 11597 11598 // Depending on the policy in effect, there could be a bunch of 11599 // these in quick succession so we try to batch these together to 11600 // minimize disk writes, number of dropbox entries, and maximize 11601 // compression, by having more fewer, larger records. 11602 private void logStrictModeViolationToDropBox( 11603 ProcessRecord process, 11604 StrictMode.ViolationInfo info) { 11605 if (info == null) { 11606 return; 11607 } 11608 final boolean isSystemApp = process == null || 11609 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11610 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11611 final String processName = process == null ? "unknown" : process.processName; 11612 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11613 final DropBoxManager dbox = (DropBoxManager) 11614 mContext.getSystemService(Context.DROPBOX_SERVICE); 11615 11616 // Exit early if the dropbox isn't configured to accept this report type. 11617 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11618 11619 boolean bufferWasEmpty; 11620 boolean needsFlush; 11621 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11622 synchronized (sb) { 11623 bufferWasEmpty = sb.length() == 0; 11624 appendDropBoxProcessHeaders(process, processName, sb); 11625 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11626 sb.append("System-App: ").append(isSystemApp).append("\n"); 11627 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11628 if (info.violationNumThisLoop != 0) { 11629 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11630 } 11631 if (info.numAnimationsRunning != 0) { 11632 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11633 } 11634 if (info.broadcastIntentAction != null) { 11635 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11636 } 11637 if (info.durationMillis != -1) { 11638 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11639 } 11640 if (info.numInstances != -1) { 11641 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11642 } 11643 if (info.tags != null) { 11644 for (String tag : info.tags) { 11645 sb.append("Span-Tag: ").append(tag).append("\n"); 11646 } 11647 } 11648 sb.append("\n"); 11649 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11650 sb.append(info.crashInfo.stackTrace); 11651 } 11652 sb.append("\n"); 11653 11654 // Only buffer up to ~64k. Various logging bits truncate 11655 // things at 128k. 11656 needsFlush = (sb.length() > 64 * 1024); 11657 } 11658 11659 // Flush immediately if the buffer's grown too large, or this 11660 // is a non-system app. Non-system apps are isolated with a 11661 // different tag & policy and not batched. 11662 // 11663 // Batching is useful during internal testing with 11664 // StrictMode settings turned up high. Without batching, 11665 // thousands of separate files could be created on boot. 11666 if (!isSystemApp || needsFlush) { 11667 new Thread("Error dump: " + dropboxTag) { 11668 @Override 11669 public void run() { 11670 String report; 11671 synchronized (sb) { 11672 report = sb.toString(); 11673 sb.delete(0, sb.length()); 11674 sb.trimToSize(); 11675 } 11676 if (report.length() != 0) { 11677 dbox.addText(dropboxTag, report); 11678 } 11679 } 11680 }.start(); 11681 return; 11682 } 11683 11684 // System app batching: 11685 if (!bufferWasEmpty) { 11686 // An existing dropbox-writing thread is outstanding, so 11687 // we don't need to start it up. The existing thread will 11688 // catch the buffer appends we just did. 11689 return; 11690 } 11691 11692 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11693 // (After this point, we shouldn't access AMS internal data structures.) 11694 new Thread("Error dump: " + dropboxTag) { 11695 @Override 11696 public void run() { 11697 // 5 second sleep to let stacks arrive and be batched together 11698 try { 11699 Thread.sleep(5000); // 5 seconds 11700 } catch (InterruptedException e) {} 11701 11702 String errorReport; 11703 synchronized (mStrictModeBuffer) { 11704 errorReport = mStrictModeBuffer.toString(); 11705 if (errorReport.length() == 0) { 11706 return; 11707 } 11708 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11709 mStrictModeBuffer.trimToSize(); 11710 } 11711 dbox.addText(dropboxTag, errorReport); 11712 } 11713 }.start(); 11714 } 11715 11716 /** 11717 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11718 * @param app object of the crashing app, null for the system server 11719 * @param tag reported by the caller 11720 * @param system whether this wtf is coming from the system 11721 * @param crashInfo describing the context of the error 11722 * @return true if the process should exit immediately (WTF is fatal) 11723 */ 11724 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11725 final ApplicationErrorReport.CrashInfo crashInfo) { 11726 final int callingUid = Binder.getCallingUid(); 11727 final int callingPid = Binder.getCallingPid(); 11728 11729 if (system) { 11730 // If this is coming from the system, we could very well have low-level 11731 // system locks held, so we want to do this all asynchronously. And we 11732 // never want this to become fatal, so there is that too. 11733 mHandler.post(new Runnable() { 11734 @Override public void run() { 11735 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11736 } 11737 }); 11738 return false; 11739 } 11740 11741 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11742 crashInfo); 11743 11744 if (r != null && r.pid != Process.myPid() && 11745 Settings.Global.getInt(mContext.getContentResolver(), 11746 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11747 crashApplication(r, crashInfo); 11748 return true; 11749 } else { 11750 return false; 11751 } 11752 } 11753 11754 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11755 final ApplicationErrorReport.CrashInfo crashInfo) { 11756 final ProcessRecord r = findAppProcess(app, "WTF"); 11757 final String processName = app == null ? "system_server" 11758 : (r == null ? "unknown" : r.processName); 11759 11760 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11761 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11762 11763 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11764 11765 return r; 11766 } 11767 11768 /** 11769 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11770 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11771 */ 11772 private ProcessRecord findAppProcess(IBinder app, String reason) { 11773 if (app == null) { 11774 return null; 11775 } 11776 11777 synchronized (this) { 11778 final int NP = mProcessNames.getMap().size(); 11779 for (int ip=0; ip<NP; ip++) { 11780 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11781 final int NA = apps.size(); 11782 for (int ia=0; ia<NA; ia++) { 11783 ProcessRecord p = apps.valueAt(ia); 11784 if (p.thread != null && p.thread.asBinder() == app) { 11785 return p; 11786 } 11787 } 11788 } 11789 11790 Slog.w(TAG, "Can't find mystery application for " + reason 11791 + " from pid=" + Binder.getCallingPid() 11792 + " uid=" + Binder.getCallingUid() + ": " + app); 11793 return null; 11794 } 11795 } 11796 11797 /** 11798 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11799 * to append various headers to the dropbox log text. 11800 */ 11801 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11802 StringBuilder sb) { 11803 // Watchdog thread ends up invoking this function (with 11804 // a null ProcessRecord) to add the stack file to dropbox. 11805 // Do not acquire a lock on this (am) in such cases, as it 11806 // could cause a potential deadlock, if and when watchdog 11807 // is invoked due to unavailability of lock on am and it 11808 // would prevent watchdog from killing system_server. 11809 if (process == null) { 11810 sb.append("Process: ").append(processName).append("\n"); 11811 return; 11812 } 11813 // Note: ProcessRecord 'process' is guarded by the service 11814 // instance. (notably process.pkgList, which could otherwise change 11815 // concurrently during execution of this method) 11816 synchronized (this) { 11817 sb.append("Process: ").append(processName).append("\n"); 11818 int flags = process.info.flags; 11819 IPackageManager pm = AppGlobals.getPackageManager(); 11820 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11821 for (int ip=0; ip<process.pkgList.size(); ip++) { 11822 String pkg = process.pkgList.keyAt(ip); 11823 sb.append("Package: ").append(pkg); 11824 try { 11825 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11826 if (pi != null) { 11827 sb.append(" v").append(pi.versionCode); 11828 if (pi.versionName != null) { 11829 sb.append(" (").append(pi.versionName).append(")"); 11830 } 11831 } 11832 } catch (RemoteException e) { 11833 Slog.e(TAG, "Error getting package info: " + pkg, e); 11834 } 11835 sb.append("\n"); 11836 } 11837 } 11838 } 11839 11840 private static String processClass(ProcessRecord process) { 11841 if (process == null || process.pid == MY_PID) { 11842 return "system_server"; 11843 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11844 return "system_app"; 11845 } else { 11846 return "data_app"; 11847 } 11848 } 11849 11850 /** 11851 * Write a description of an error (crash, WTF, ANR) to the drop box. 11852 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11853 * @param process which caused the error, null means the system server 11854 * @param activity which triggered the error, null if unknown 11855 * @param parent activity related to the error, null if unknown 11856 * @param subject line related to the error, null if absent 11857 * @param report in long form describing the error, null if absent 11858 * @param logFile to include in the report, null if none 11859 * @param crashInfo giving an application stack trace, null if absent 11860 */ 11861 public void addErrorToDropBox(String eventType, 11862 ProcessRecord process, String processName, ActivityRecord activity, 11863 ActivityRecord parent, String subject, 11864 final String report, final File logFile, 11865 final ApplicationErrorReport.CrashInfo crashInfo) { 11866 // NOTE -- this must never acquire the ActivityManagerService lock, 11867 // otherwise the watchdog may be prevented from resetting the system. 11868 11869 final String dropboxTag = processClass(process) + "_" + eventType; 11870 final DropBoxManager dbox = (DropBoxManager) 11871 mContext.getSystemService(Context.DROPBOX_SERVICE); 11872 11873 // Exit early if the dropbox isn't configured to accept this report type. 11874 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11875 11876 final StringBuilder sb = new StringBuilder(1024); 11877 appendDropBoxProcessHeaders(process, processName, sb); 11878 if (activity != null) { 11879 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11880 } 11881 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11882 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11883 } 11884 if (parent != null && parent != activity) { 11885 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11886 } 11887 if (subject != null) { 11888 sb.append("Subject: ").append(subject).append("\n"); 11889 } 11890 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11891 if (Debug.isDebuggerConnected()) { 11892 sb.append("Debugger: Connected\n"); 11893 } 11894 sb.append("\n"); 11895 11896 // Do the rest in a worker thread to avoid blocking the caller on I/O 11897 // (After this point, we shouldn't access AMS internal data structures.) 11898 Thread worker = new Thread("Error dump: " + dropboxTag) { 11899 @Override 11900 public void run() { 11901 if (report != null) { 11902 sb.append(report); 11903 } 11904 if (logFile != null) { 11905 try { 11906 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11907 "\n\n[[TRUNCATED]]")); 11908 } catch (IOException e) { 11909 Slog.e(TAG, "Error reading " + logFile, e); 11910 } 11911 } 11912 if (crashInfo != null && crashInfo.stackTrace != null) { 11913 sb.append(crashInfo.stackTrace); 11914 } 11915 11916 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11917 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11918 if (lines > 0) { 11919 sb.append("\n"); 11920 11921 // Merge several logcat streams, and take the last N lines 11922 InputStreamReader input = null; 11923 try { 11924 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11925 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11926 "-b", "crash", 11927 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11928 11929 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11930 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11931 input = new InputStreamReader(logcat.getInputStream()); 11932 11933 int num; 11934 char[] buf = new char[8192]; 11935 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11936 } catch (IOException e) { 11937 Slog.e(TAG, "Error running logcat", e); 11938 } finally { 11939 if (input != null) try { input.close(); } catch (IOException e) {} 11940 } 11941 } 11942 11943 dbox.addText(dropboxTag, sb.toString()); 11944 } 11945 }; 11946 11947 if (process == null) { 11948 // If process is null, we are being called from some internal code 11949 // and may be about to die -- run this synchronously. 11950 worker.run(); 11951 } else { 11952 worker.start(); 11953 } 11954 } 11955 11956 /** 11957 * Bring up the "unexpected error" dialog box for a crashing app. 11958 * Deal with edge cases (intercepts from instrumented applications, 11959 * ActivityController, error intent receivers, that sort of thing). 11960 * @param r the application crashing 11961 * @param crashInfo describing the failure 11962 */ 11963 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11964 long timeMillis = System.currentTimeMillis(); 11965 String shortMsg = crashInfo.exceptionClassName; 11966 String longMsg = crashInfo.exceptionMessage; 11967 String stackTrace = crashInfo.stackTrace; 11968 if (shortMsg != null && longMsg != null) { 11969 longMsg = shortMsg + ": " + longMsg; 11970 } else if (shortMsg != null) { 11971 longMsg = shortMsg; 11972 } 11973 11974 AppErrorResult result = new AppErrorResult(); 11975 synchronized (this) { 11976 if (mController != null) { 11977 try { 11978 String name = r != null ? r.processName : null; 11979 int pid = r != null ? r.pid : Binder.getCallingPid(); 11980 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11981 if (!mController.appCrashed(name, pid, 11982 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11983 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11984 && "Native crash".equals(crashInfo.exceptionClassName)) { 11985 Slog.w(TAG, "Skip killing native crashed app " + name 11986 + "(" + pid + ") during testing"); 11987 } else { 11988 Slog.w(TAG, "Force-killing crashed app " + name 11989 + " at watcher's request"); 11990 if (r != null) { 11991 r.kill("crash", true); 11992 } else { 11993 // Huh. 11994 Process.killProcess(pid); 11995 Process.killProcessGroup(uid, pid); 11996 } 11997 } 11998 return; 11999 } 12000 } catch (RemoteException e) { 12001 mController = null; 12002 Watchdog.getInstance().setActivityController(null); 12003 } 12004 } 12005 12006 final long origId = Binder.clearCallingIdentity(); 12007 12008 // If this process is running instrumentation, finish it. 12009 if (r != null && r.instrumentationClass != null) { 12010 Slog.w(TAG, "Error in app " + r.processName 12011 + " running instrumentation " + r.instrumentationClass + ":"); 12012 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12013 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12014 Bundle info = new Bundle(); 12015 info.putString("shortMsg", shortMsg); 12016 info.putString("longMsg", longMsg); 12017 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12018 Binder.restoreCallingIdentity(origId); 12019 return; 12020 } 12021 12022 // If we can't identify the process or it's already exceeded its crash quota, 12023 // quit right away without showing a crash dialog. 12024 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12025 Binder.restoreCallingIdentity(origId); 12026 return; 12027 } 12028 12029 Message msg = Message.obtain(); 12030 msg.what = SHOW_ERROR_MSG; 12031 HashMap data = new HashMap(); 12032 data.put("result", result); 12033 data.put("app", r); 12034 msg.obj = data; 12035 mHandler.sendMessage(msg); 12036 12037 Binder.restoreCallingIdentity(origId); 12038 } 12039 12040 int res = result.get(); 12041 12042 Intent appErrorIntent = null; 12043 synchronized (this) { 12044 if (r != null && !r.isolated) { 12045 // XXX Can't keep track of crash time for isolated processes, 12046 // since they don't have a persistent identity. 12047 mProcessCrashTimes.put(r.info.processName, r.uid, 12048 SystemClock.uptimeMillis()); 12049 } 12050 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12051 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12052 } 12053 } 12054 12055 if (appErrorIntent != null) { 12056 try { 12057 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12058 } catch (ActivityNotFoundException e) { 12059 Slog.w(TAG, "bug report receiver dissappeared", e); 12060 } 12061 } 12062 } 12063 12064 Intent createAppErrorIntentLocked(ProcessRecord r, 12065 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12066 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12067 if (report == null) { 12068 return null; 12069 } 12070 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12071 result.setComponent(r.errorReportReceiver); 12072 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12073 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12074 return result; 12075 } 12076 12077 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12078 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12079 if (r.errorReportReceiver == null) { 12080 return null; 12081 } 12082 12083 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12084 return null; 12085 } 12086 12087 ApplicationErrorReport report = new ApplicationErrorReport(); 12088 report.packageName = r.info.packageName; 12089 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12090 report.processName = r.processName; 12091 report.time = timeMillis; 12092 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12093 12094 if (r.crashing || r.forceCrashReport) { 12095 report.type = ApplicationErrorReport.TYPE_CRASH; 12096 report.crashInfo = crashInfo; 12097 } else if (r.notResponding) { 12098 report.type = ApplicationErrorReport.TYPE_ANR; 12099 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12100 12101 report.anrInfo.activity = r.notRespondingReport.tag; 12102 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12103 report.anrInfo.info = r.notRespondingReport.longMsg; 12104 } 12105 12106 return report; 12107 } 12108 12109 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12110 enforceNotIsolatedCaller("getProcessesInErrorState"); 12111 // assume our apps are happy - lazy create the list 12112 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12113 12114 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12115 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12116 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12117 12118 synchronized (this) { 12119 12120 // iterate across all processes 12121 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12122 ProcessRecord app = mLruProcesses.get(i); 12123 if (!allUsers && app.userId != userId) { 12124 continue; 12125 } 12126 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12127 // This one's in trouble, so we'll generate a report for it 12128 // crashes are higher priority (in case there's a crash *and* an anr) 12129 ActivityManager.ProcessErrorStateInfo report = null; 12130 if (app.crashing) { 12131 report = app.crashingReport; 12132 } else if (app.notResponding) { 12133 report = app.notRespondingReport; 12134 } 12135 12136 if (report != null) { 12137 if (errList == null) { 12138 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12139 } 12140 errList.add(report); 12141 } else { 12142 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12143 " crashing = " + app.crashing + 12144 " notResponding = " + app.notResponding); 12145 } 12146 } 12147 } 12148 } 12149 12150 return errList; 12151 } 12152 12153 static int procStateToImportance(int procState, int memAdj, 12154 ActivityManager.RunningAppProcessInfo currApp) { 12155 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12156 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12157 currApp.lru = memAdj; 12158 } else { 12159 currApp.lru = 0; 12160 } 12161 return imp; 12162 } 12163 12164 private void fillInProcMemInfo(ProcessRecord app, 12165 ActivityManager.RunningAppProcessInfo outInfo) { 12166 outInfo.pid = app.pid; 12167 outInfo.uid = app.info.uid; 12168 if (mHeavyWeightProcess == app) { 12169 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12170 } 12171 if (app.persistent) { 12172 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12173 } 12174 if (app.activities.size() > 0) { 12175 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12176 } 12177 outInfo.lastTrimLevel = app.trimMemoryLevel; 12178 int adj = app.curAdj; 12179 int procState = app.curProcState; 12180 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12181 outInfo.importanceReasonCode = app.adjTypeCode; 12182 outInfo.processState = app.curProcState; 12183 } 12184 12185 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12186 enforceNotIsolatedCaller("getRunningAppProcesses"); 12187 // Lazy instantiation of list 12188 List<ActivityManager.RunningAppProcessInfo> runList = null; 12189 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12190 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12191 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12192 synchronized (this) { 12193 // Iterate across all processes 12194 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12195 ProcessRecord app = mLruProcesses.get(i); 12196 if (!allUsers && app.userId != userId) { 12197 continue; 12198 } 12199 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12200 // Generate process state info for running application 12201 ActivityManager.RunningAppProcessInfo currApp = 12202 new ActivityManager.RunningAppProcessInfo(app.processName, 12203 app.pid, app.getPackageList()); 12204 fillInProcMemInfo(app, currApp); 12205 if (app.adjSource instanceof ProcessRecord) { 12206 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12207 currApp.importanceReasonImportance = 12208 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12209 app.adjSourceProcState); 12210 } else if (app.adjSource instanceof ActivityRecord) { 12211 ActivityRecord r = (ActivityRecord)app.adjSource; 12212 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12213 } 12214 if (app.adjTarget instanceof ComponentName) { 12215 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12216 } 12217 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12218 // + " lru=" + currApp.lru); 12219 if (runList == null) { 12220 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12221 } 12222 runList.add(currApp); 12223 } 12224 } 12225 } 12226 return runList; 12227 } 12228 12229 public List<ApplicationInfo> getRunningExternalApplications() { 12230 enforceNotIsolatedCaller("getRunningExternalApplications"); 12231 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12232 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12233 if (runningApps != null && runningApps.size() > 0) { 12234 Set<String> extList = new HashSet<String>(); 12235 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12236 if (app.pkgList != null) { 12237 for (String pkg : app.pkgList) { 12238 extList.add(pkg); 12239 } 12240 } 12241 } 12242 IPackageManager pm = AppGlobals.getPackageManager(); 12243 for (String pkg : extList) { 12244 try { 12245 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12246 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12247 retList.add(info); 12248 } 12249 } catch (RemoteException e) { 12250 } 12251 } 12252 } 12253 return retList; 12254 } 12255 12256 @Override 12257 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12258 enforceNotIsolatedCaller("getMyMemoryState"); 12259 synchronized (this) { 12260 ProcessRecord proc; 12261 synchronized (mPidsSelfLocked) { 12262 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12263 } 12264 fillInProcMemInfo(proc, outInfo); 12265 } 12266 } 12267 12268 @Override 12269 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12270 if (checkCallingPermission(android.Manifest.permission.DUMP) 12271 != PackageManager.PERMISSION_GRANTED) { 12272 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12273 + Binder.getCallingPid() 12274 + ", uid=" + Binder.getCallingUid() 12275 + " without permission " 12276 + android.Manifest.permission.DUMP); 12277 return; 12278 } 12279 12280 boolean dumpAll = false; 12281 boolean dumpClient = false; 12282 String dumpPackage = null; 12283 12284 int opti = 0; 12285 while (opti < args.length) { 12286 String opt = args[opti]; 12287 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12288 break; 12289 } 12290 opti++; 12291 if ("-a".equals(opt)) { 12292 dumpAll = true; 12293 } else if ("-c".equals(opt)) { 12294 dumpClient = true; 12295 } else if ("-h".equals(opt)) { 12296 pw.println("Activity manager dump options:"); 12297 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12298 pw.println(" cmd may be one of:"); 12299 pw.println(" a[ctivities]: activity stack state"); 12300 pw.println(" r[recents]: recent activities state"); 12301 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12302 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12303 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12304 pw.println(" o[om]: out of memory management"); 12305 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12306 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12307 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12308 pw.println(" service [COMP_SPEC]: service client-side state"); 12309 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12310 pw.println(" all: dump all activities"); 12311 pw.println(" top: dump the top activity"); 12312 pw.println(" write: write all pending state to storage"); 12313 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12314 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12315 pw.println(" a partial substring in a component name, a"); 12316 pw.println(" hex object identifier."); 12317 pw.println(" -a: include all available server state."); 12318 pw.println(" -c: include client state."); 12319 return; 12320 } else { 12321 pw.println("Unknown argument: " + opt + "; use -h for help"); 12322 } 12323 } 12324 12325 long origId = Binder.clearCallingIdentity(); 12326 boolean more = false; 12327 // Is the caller requesting to dump a particular piece of data? 12328 if (opti < args.length) { 12329 String cmd = args[opti]; 12330 opti++; 12331 if ("activities".equals(cmd) || "a".equals(cmd)) { 12332 synchronized (this) { 12333 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12334 } 12335 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12336 synchronized (this) { 12337 dumpRecentsLocked(fd, pw, args, opti, true, null); 12338 } 12339 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12340 String[] newArgs; 12341 String name; 12342 if (opti >= args.length) { 12343 name = null; 12344 newArgs = EMPTY_STRING_ARRAY; 12345 } else { 12346 name = args[opti]; 12347 opti++; 12348 newArgs = new String[args.length - opti]; 12349 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12350 args.length - opti); 12351 } 12352 synchronized (this) { 12353 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12354 } 12355 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12356 String[] newArgs; 12357 String name; 12358 if (opti >= args.length) { 12359 name = null; 12360 newArgs = EMPTY_STRING_ARRAY; 12361 } else { 12362 name = args[opti]; 12363 opti++; 12364 newArgs = new String[args.length - opti]; 12365 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12366 args.length - opti); 12367 } 12368 synchronized (this) { 12369 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12370 } 12371 } else if ("processes".equals(cmd) || "p".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 synchronized (this) { 12385 dumpProcessesLocked(fd, pw, args, opti, true, name); 12386 } 12387 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12388 synchronized (this) { 12389 dumpOomLocked(fd, pw, args, opti, true); 12390 } 12391 } else if ("provider".equals(cmd)) { 12392 String[] newArgs; 12393 String name; 12394 if (opti >= args.length) { 12395 name = null; 12396 newArgs = EMPTY_STRING_ARRAY; 12397 } else { 12398 name = args[opti]; 12399 opti++; 12400 newArgs = new String[args.length - opti]; 12401 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12402 } 12403 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12404 pw.println("No providers match: " + name); 12405 pw.println("Use -h for help."); 12406 } 12407 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12408 synchronized (this) { 12409 dumpProvidersLocked(fd, pw, args, opti, true, null); 12410 } 12411 } else if ("service".equals(cmd)) { 12412 String[] newArgs; 12413 String name; 12414 if (opti >= args.length) { 12415 name = null; 12416 newArgs = EMPTY_STRING_ARRAY; 12417 } else { 12418 name = args[opti]; 12419 opti++; 12420 newArgs = new String[args.length - opti]; 12421 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12422 args.length - opti); 12423 } 12424 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12425 pw.println("No services match: " + name); 12426 pw.println("Use -h for help."); 12427 } 12428 } else if ("package".equals(cmd)) { 12429 String[] newArgs; 12430 if (opti >= args.length) { 12431 pw.println("package: no package name specified"); 12432 pw.println("Use -h for help."); 12433 } else { 12434 dumpPackage = args[opti]; 12435 opti++; 12436 newArgs = new String[args.length - opti]; 12437 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12438 args.length - opti); 12439 args = newArgs; 12440 opti = 0; 12441 more = true; 12442 } 12443 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12444 synchronized (this) { 12445 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12446 } 12447 } else if ("write".equals(cmd)) { 12448 mTaskPersister.flush(); 12449 pw.println("All tasks persisted."); 12450 return; 12451 } else { 12452 // Dumping a single activity? 12453 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12454 pw.println("Bad activity command, or no activities match: " + cmd); 12455 pw.println("Use -h for help."); 12456 } 12457 } 12458 if (!more) { 12459 Binder.restoreCallingIdentity(origId); 12460 return; 12461 } 12462 } 12463 12464 // No piece of data specified, dump everything. 12465 synchronized (this) { 12466 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12467 pw.println(); 12468 if (dumpAll) { 12469 pw.println("-------------------------------------------------------------------------------"); 12470 } 12471 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12472 pw.println(); 12473 if (dumpAll) { 12474 pw.println("-------------------------------------------------------------------------------"); 12475 } 12476 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12477 pw.println(); 12478 if (dumpAll) { 12479 pw.println("-------------------------------------------------------------------------------"); 12480 } 12481 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12482 pw.println(); 12483 if (dumpAll) { 12484 pw.println("-------------------------------------------------------------------------------"); 12485 } 12486 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12487 pw.println(); 12488 if (dumpAll) { 12489 pw.println("-------------------------------------------------------------------------------"); 12490 } 12491 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12492 pw.println(); 12493 if (dumpAll) { 12494 pw.println("-------------------------------------------------------------------------------"); 12495 } 12496 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12497 } 12498 Binder.restoreCallingIdentity(origId); 12499 } 12500 12501 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12502 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12503 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12504 12505 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12506 dumpPackage); 12507 boolean needSep = printedAnything; 12508 12509 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12510 dumpPackage, needSep, " mFocusedActivity: "); 12511 if (printed) { 12512 printedAnything = true; 12513 needSep = false; 12514 } 12515 12516 if (dumpPackage == null) { 12517 if (needSep) { 12518 pw.println(); 12519 } 12520 needSep = true; 12521 printedAnything = true; 12522 mStackSupervisor.dump(pw, " "); 12523 } 12524 12525 if (!printedAnything) { 12526 pw.println(" (nothing)"); 12527 } 12528 } 12529 12530 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12531 int opti, boolean dumpAll, String dumpPackage) { 12532 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12533 12534 boolean printedAnything = false; 12535 12536 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12537 boolean printedHeader = false; 12538 12539 final int N = mRecentTasks.size(); 12540 for (int i=0; i<N; i++) { 12541 TaskRecord tr = mRecentTasks.get(i); 12542 if (dumpPackage != null) { 12543 if (tr.realActivity == null || 12544 !dumpPackage.equals(tr.realActivity)) { 12545 continue; 12546 } 12547 } 12548 if (!printedHeader) { 12549 pw.println(" Recent tasks:"); 12550 printedHeader = true; 12551 printedAnything = true; 12552 } 12553 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12554 pw.println(tr); 12555 if (dumpAll) { 12556 mRecentTasks.get(i).dump(pw, " "); 12557 } 12558 } 12559 } 12560 12561 if (!printedAnything) { 12562 pw.println(" (nothing)"); 12563 } 12564 } 12565 12566 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12567 int opti, boolean dumpAll, String dumpPackage) { 12568 boolean needSep = false; 12569 boolean printedAnything = false; 12570 int numPers = 0; 12571 12572 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12573 12574 if (dumpAll) { 12575 final int NP = mProcessNames.getMap().size(); 12576 for (int ip=0; ip<NP; ip++) { 12577 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12578 final int NA = procs.size(); 12579 for (int ia=0; ia<NA; ia++) { 12580 ProcessRecord r = procs.valueAt(ia); 12581 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12582 continue; 12583 } 12584 if (!needSep) { 12585 pw.println(" All known processes:"); 12586 needSep = true; 12587 printedAnything = true; 12588 } 12589 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12590 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12591 pw.print(" "); pw.println(r); 12592 r.dump(pw, " "); 12593 if (r.persistent) { 12594 numPers++; 12595 } 12596 } 12597 } 12598 } 12599 12600 if (mIsolatedProcesses.size() > 0) { 12601 boolean printed = false; 12602 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12603 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12604 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12605 continue; 12606 } 12607 if (!printed) { 12608 if (needSep) { 12609 pw.println(); 12610 } 12611 pw.println(" Isolated process list (sorted by uid):"); 12612 printedAnything = true; 12613 printed = true; 12614 needSep = true; 12615 } 12616 pw.println(String.format("%sIsolated #%2d: %s", 12617 " ", i, r.toString())); 12618 } 12619 } 12620 12621 if (mLruProcesses.size() > 0) { 12622 if (needSep) { 12623 pw.println(); 12624 } 12625 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12626 pw.print(" total, non-act at "); 12627 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12628 pw.print(", non-svc at "); 12629 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12630 pw.println("):"); 12631 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12632 needSep = true; 12633 printedAnything = true; 12634 } 12635 12636 if (dumpAll || dumpPackage != null) { 12637 synchronized (mPidsSelfLocked) { 12638 boolean printed = false; 12639 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12640 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12641 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12642 continue; 12643 } 12644 if (!printed) { 12645 if (needSep) pw.println(); 12646 needSep = true; 12647 pw.println(" PID mappings:"); 12648 printed = true; 12649 printedAnything = true; 12650 } 12651 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12652 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12653 } 12654 } 12655 } 12656 12657 if (mForegroundProcesses.size() > 0) { 12658 synchronized (mPidsSelfLocked) { 12659 boolean printed = false; 12660 for (int i=0; i<mForegroundProcesses.size(); i++) { 12661 ProcessRecord r = mPidsSelfLocked.get( 12662 mForegroundProcesses.valueAt(i).pid); 12663 if (dumpPackage != null && (r == null 12664 || !r.pkgList.containsKey(dumpPackage))) { 12665 continue; 12666 } 12667 if (!printed) { 12668 if (needSep) pw.println(); 12669 needSep = true; 12670 pw.println(" Foreground Processes:"); 12671 printed = true; 12672 printedAnything = true; 12673 } 12674 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12675 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12676 } 12677 } 12678 } 12679 12680 if (mPersistentStartingProcesses.size() > 0) { 12681 if (needSep) pw.println(); 12682 needSep = true; 12683 printedAnything = true; 12684 pw.println(" Persisent processes that are starting:"); 12685 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12686 "Starting Norm", "Restarting PERS", dumpPackage); 12687 } 12688 12689 if (mRemovedProcesses.size() > 0) { 12690 if (needSep) pw.println(); 12691 needSep = true; 12692 printedAnything = true; 12693 pw.println(" Processes that are being removed:"); 12694 dumpProcessList(pw, this, mRemovedProcesses, " ", 12695 "Removed Norm", "Removed PERS", dumpPackage); 12696 } 12697 12698 if (mProcessesOnHold.size() > 0) { 12699 if (needSep) pw.println(); 12700 needSep = true; 12701 printedAnything = true; 12702 pw.println(" Processes that are on old until the system is ready:"); 12703 dumpProcessList(pw, this, mProcessesOnHold, " ", 12704 "OnHold Norm", "OnHold PERS", dumpPackage); 12705 } 12706 12707 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12708 12709 if (mProcessCrashTimes.getMap().size() > 0) { 12710 boolean printed = false; 12711 long now = SystemClock.uptimeMillis(); 12712 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12713 final int NP = pmap.size(); 12714 for (int ip=0; ip<NP; ip++) { 12715 String pname = pmap.keyAt(ip); 12716 SparseArray<Long> uids = pmap.valueAt(ip); 12717 final int N = uids.size(); 12718 for (int i=0; i<N; i++) { 12719 int puid = uids.keyAt(i); 12720 ProcessRecord r = mProcessNames.get(pname, puid); 12721 if (dumpPackage != null && (r == null 12722 || !r.pkgList.containsKey(dumpPackage))) { 12723 continue; 12724 } 12725 if (!printed) { 12726 if (needSep) pw.println(); 12727 needSep = true; 12728 pw.println(" Time since processes crashed:"); 12729 printed = true; 12730 printedAnything = true; 12731 } 12732 pw.print(" Process "); pw.print(pname); 12733 pw.print(" uid "); pw.print(puid); 12734 pw.print(": last crashed "); 12735 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12736 pw.println(" ago"); 12737 } 12738 } 12739 } 12740 12741 if (mBadProcesses.getMap().size() > 0) { 12742 boolean printed = false; 12743 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12744 final int NP = pmap.size(); 12745 for (int ip=0; ip<NP; ip++) { 12746 String pname = pmap.keyAt(ip); 12747 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12748 final int N = uids.size(); 12749 for (int i=0; i<N; i++) { 12750 int puid = uids.keyAt(i); 12751 ProcessRecord r = mProcessNames.get(pname, puid); 12752 if (dumpPackage != null && (r == null 12753 || !r.pkgList.containsKey(dumpPackage))) { 12754 continue; 12755 } 12756 if (!printed) { 12757 if (needSep) pw.println(); 12758 needSep = true; 12759 pw.println(" Bad processes:"); 12760 printedAnything = true; 12761 } 12762 BadProcessInfo info = uids.valueAt(i); 12763 pw.print(" Bad process "); pw.print(pname); 12764 pw.print(" uid "); pw.print(puid); 12765 pw.print(": crashed at time "); pw.println(info.time); 12766 if (info.shortMsg != null) { 12767 pw.print(" Short msg: "); pw.println(info.shortMsg); 12768 } 12769 if (info.longMsg != null) { 12770 pw.print(" Long msg: "); pw.println(info.longMsg); 12771 } 12772 if (info.stack != null) { 12773 pw.println(" Stack:"); 12774 int lastPos = 0; 12775 for (int pos=0; pos<info.stack.length(); pos++) { 12776 if (info.stack.charAt(pos) == '\n') { 12777 pw.print(" "); 12778 pw.write(info.stack, lastPos, pos-lastPos); 12779 pw.println(); 12780 lastPos = pos+1; 12781 } 12782 } 12783 if (lastPos < info.stack.length()) { 12784 pw.print(" "); 12785 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12786 pw.println(); 12787 } 12788 } 12789 } 12790 } 12791 } 12792 12793 if (dumpPackage == null) { 12794 pw.println(); 12795 needSep = false; 12796 pw.println(" mStartedUsers:"); 12797 for (int i=0; i<mStartedUsers.size(); i++) { 12798 UserStartedState uss = mStartedUsers.valueAt(i); 12799 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12800 pw.print(": "); uss.dump("", pw); 12801 } 12802 pw.print(" mStartedUserArray: ["); 12803 for (int i=0; i<mStartedUserArray.length; i++) { 12804 if (i > 0) pw.print(", "); 12805 pw.print(mStartedUserArray[i]); 12806 } 12807 pw.println("]"); 12808 pw.print(" mUserLru: ["); 12809 for (int i=0; i<mUserLru.size(); i++) { 12810 if (i > 0) pw.print(", "); 12811 pw.print(mUserLru.get(i)); 12812 } 12813 pw.println("]"); 12814 if (dumpAll) { 12815 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12816 } 12817 synchronized (mUserProfileGroupIdsSelfLocked) { 12818 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12819 pw.println(" mUserProfileGroupIds:"); 12820 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12821 pw.print(" User #"); 12822 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12823 pw.print(" -> profile #"); 12824 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12825 } 12826 } 12827 } 12828 } 12829 if (mHomeProcess != null && (dumpPackage == null 12830 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12831 if (needSep) { 12832 pw.println(); 12833 needSep = false; 12834 } 12835 pw.println(" mHomeProcess: " + mHomeProcess); 12836 } 12837 if (mPreviousProcess != null && (dumpPackage == null 12838 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12839 if (needSep) { 12840 pw.println(); 12841 needSep = false; 12842 } 12843 pw.println(" mPreviousProcess: " + mPreviousProcess); 12844 } 12845 if (dumpAll) { 12846 StringBuilder sb = new StringBuilder(128); 12847 sb.append(" mPreviousProcessVisibleTime: "); 12848 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12849 pw.println(sb); 12850 } 12851 if (mHeavyWeightProcess != null && (dumpPackage == null 12852 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12853 if (needSep) { 12854 pw.println(); 12855 needSep = false; 12856 } 12857 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12858 } 12859 if (dumpPackage == null) { 12860 pw.println(" mConfiguration: " + mConfiguration); 12861 } 12862 if (dumpAll) { 12863 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12864 if (mCompatModePackages.getPackages().size() > 0) { 12865 boolean printed = false; 12866 for (Map.Entry<String, Integer> entry 12867 : mCompatModePackages.getPackages().entrySet()) { 12868 String pkg = entry.getKey(); 12869 int mode = entry.getValue(); 12870 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12871 continue; 12872 } 12873 if (!printed) { 12874 pw.println(" mScreenCompatPackages:"); 12875 printed = true; 12876 } 12877 pw.print(" "); pw.print(pkg); pw.print(": "); 12878 pw.print(mode); pw.println(); 12879 } 12880 } 12881 } 12882 if (dumpPackage == null) { 12883 pw.println(" mWakefulness=" 12884 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12885 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12886 + lockScreenShownToString()); 12887 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12888 } 12889 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12890 || mOrigWaitForDebugger) { 12891 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12892 || dumpPackage.equals(mOrigDebugApp)) { 12893 if (needSep) { 12894 pw.println(); 12895 needSep = false; 12896 } 12897 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12898 + " mDebugTransient=" + mDebugTransient 12899 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12900 } 12901 } 12902 if (mOpenGlTraceApp != null) { 12903 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12904 if (needSep) { 12905 pw.println(); 12906 needSep = false; 12907 } 12908 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12909 } 12910 } 12911 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12912 || mProfileFd != null) { 12913 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12914 if (needSep) { 12915 pw.println(); 12916 needSep = false; 12917 } 12918 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12919 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12920 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12921 + mAutoStopProfiler); 12922 pw.println(" mProfileType=" + mProfileType); 12923 } 12924 } 12925 if (dumpPackage == null) { 12926 if (mAlwaysFinishActivities || mController != null) { 12927 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12928 + " mController=" + mController); 12929 } 12930 if (dumpAll) { 12931 pw.println(" Total persistent processes: " + numPers); 12932 pw.println(" mProcessesReady=" + mProcessesReady 12933 + " mSystemReady=" + mSystemReady 12934 + " mBooted=" + mBooted 12935 + " mFactoryTest=" + mFactoryTest); 12936 pw.println(" mBooting=" + mBooting 12937 + " mCallFinishBooting=" + mCallFinishBooting 12938 + " mBootAnimationComplete=" + mBootAnimationComplete); 12939 pw.print(" mLastPowerCheckRealtime="); 12940 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12941 pw.println(""); 12942 pw.print(" mLastPowerCheckUptime="); 12943 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12944 pw.println(""); 12945 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12946 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12947 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12948 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12949 + " (" + mLruProcesses.size() + " total)" 12950 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12951 + " mNumServiceProcs=" + mNumServiceProcs 12952 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12953 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12954 + " mLastMemoryLevel" + mLastMemoryLevel 12955 + " mLastNumProcesses" + mLastNumProcesses); 12956 long now = SystemClock.uptimeMillis(); 12957 pw.print(" mLastIdleTime="); 12958 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12959 pw.print(" mLowRamSinceLastIdle="); 12960 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12961 pw.println(); 12962 } 12963 } 12964 12965 if (!printedAnything) { 12966 pw.println(" (nothing)"); 12967 } 12968 } 12969 12970 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12971 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12972 if (mProcessesToGc.size() > 0) { 12973 boolean printed = false; 12974 long now = SystemClock.uptimeMillis(); 12975 for (int i=0; i<mProcessesToGc.size(); i++) { 12976 ProcessRecord proc = mProcessesToGc.get(i); 12977 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12978 continue; 12979 } 12980 if (!printed) { 12981 if (needSep) pw.println(); 12982 needSep = true; 12983 pw.println(" Processes that are waiting to GC:"); 12984 printed = true; 12985 } 12986 pw.print(" Process "); pw.println(proc); 12987 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12988 pw.print(", last gced="); 12989 pw.print(now-proc.lastRequestedGc); 12990 pw.print(" ms ago, last lowMem="); 12991 pw.print(now-proc.lastLowMemory); 12992 pw.println(" ms ago"); 12993 12994 } 12995 } 12996 return needSep; 12997 } 12998 12999 void printOomLevel(PrintWriter pw, String name, int adj) { 13000 pw.print(" "); 13001 if (adj >= 0) { 13002 pw.print(' '); 13003 if (adj < 10) pw.print(' '); 13004 } else { 13005 if (adj > -10) pw.print(' '); 13006 } 13007 pw.print(adj); 13008 pw.print(": "); 13009 pw.print(name); 13010 pw.print(" ("); 13011 pw.print(mProcessList.getMemLevel(adj)/1024); 13012 pw.println(" kB)"); 13013 } 13014 13015 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13016 int opti, boolean dumpAll) { 13017 boolean needSep = false; 13018 13019 if (mLruProcesses.size() > 0) { 13020 if (needSep) pw.println(); 13021 needSep = true; 13022 pw.println(" OOM levels:"); 13023 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13024 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13025 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13026 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13027 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13028 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13029 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13030 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13031 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13032 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13033 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13034 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13035 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13036 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13037 13038 if (needSep) pw.println(); 13039 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13040 pw.print(" total, non-act at "); 13041 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13042 pw.print(", non-svc at "); 13043 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13044 pw.println("):"); 13045 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13046 needSep = true; 13047 } 13048 13049 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13050 13051 pw.println(); 13052 pw.println(" mHomeProcess: " + mHomeProcess); 13053 pw.println(" mPreviousProcess: " + mPreviousProcess); 13054 if (mHeavyWeightProcess != null) { 13055 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13056 } 13057 13058 return true; 13059 } 13060 13061 /** 13062 * There are three ways to call this: 13063 * - no provider specified: dump all the providers 13064 * - a flattened component name that matched an existing provider was specified as the 13065 * first arg: dump that one provider 13066 * - the first arg isn't the flattened component name of an existing provider: 13067 * dump all providers whose component contains the first arg as a substring 13068 */ 13069 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13070 int opti, boolean dumpAll) { 13071 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13072 } 13073 13074 static class ItemMatcher { 13075 ArrayList<ComponentName> components; 13076 ArrayList<String> strings; 13077 ArrayList<Integer> objects; 13078 boolean all; 13079 13080 ItemMatcher() { 13081 all = true; 13082 } 13083 13084 void build(String name) { 13085 ComponentName componentName = ComponentName.unflattenFromString(name); 13086 if (componentName != null) { 13087 if (components == null) { 13088 components = new ArrayList<ComponentName>(); 13089 } 13090 components.add(componentName); 13091 all = false; 13092 } else { 13093 int objectId = 0; 13094 // Not a '/' separated full component name; maybe an object ID? 13095 try { 13096 objectId = Integer.parseInt(name, 16); 13097 if (objects == null) { 13098 objects = new ArrayList<Integer>(); 13099 } 13100 objects.add(objectId); 13101 all = false; 13102 } catch (RuntimeException e) { 13103 // Not an integer; just do string match. 13104 if (strings == null) { 13105 strings = new ArrayList<String>(); 13106 } 13107 strings.add(name); 13108 all = false; 13109 } 13110 } 13111 } 13112 13113 int build(String[] args, int opti) { 13114 for (; opti<args.length; opti++) { 13115 String name = args[opti]; 13116 if ("--".equals(name)) { 13117 return opti+1; 13118 } 13119 build(name); 13120 } 13121 return opti; 13122 } 13123 13124 boolean match(Object object, ComponentName comp) { 13125 if (all) { 13126 return true; 13127 } 13128 if (components != null) { 13129 for (int i=0; i<components.size(); i++) { 13130 if (components.get(i).equals(comp)) { 13131 return true; 13132 } 13133 } 13134 } 13135 if (objects != null) { 13136 for (int i=0; i<objects.size(); i++) { 13137 if (System.identityHashCode(object) == objects.get(i)) { 13138 return true; 13139 } 13140 } 13141 } 13142 if (strings != null) { 13143 String flat = comp.flattenToString(); 13144 for (int i=0; i<strings.size(); i++) { 13145 if (flat.contains(strings.get(i))) { 13146 return true; 13147 } 13148 } 13149 } 13150 return false; 13151 } 13152 } 13153 13154 /** 13155 * There are three things that cmd can be: 13156 * - a flattened component name that matches an existing activity 13157 * - the cmd arg isn't the flattened component name of an existing activity: 13158 * dump all activity whose component contains the cmd as a substring 13159 * - A hex number of the ActivityRecord object instance. 13160 */ 13161 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13162 int opti, boolean dumpAll) { 13163 ArrayList<ActivityRecord> activities; 13164 13165 synchronized (this) { 13166 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13167 } 13168 13169 if (activities.size() <= 0) { 13170 return false; 13171 } 13172 13173 String[] newArgs = new String[args.length - opti]; 13174 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13175 13176 TaskRecord lastTask = null; 13177 boolean needSep = false; 13178 for (int i=activities.size()-1; i>=0; i--) { 13179 ActivityRecord r = activities.get(i); 13180 if (needSep) { 13181 pw.println(); 13182 } 13183 needSep = true; 13184 synchronized (this) { 13185 if (lastTask != r.task) { 13186 lastTask = r.task; 13187 pw.print("TASK "); pw.print(lastTask.affinity); 13188 pw.print(" id="); pw.println(lastTask.taskId); 13189 if (dumpAll) { 13190 lastTask.dump(pw, " "); 13191 } 13192 } 13193 } 13194 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13195 } 13196 return true; 13197 } 13198 13199 /** 13200 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13201 * there is a thread associated with the activity. 13202 */ 13203 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13204 final ActivityRecord r, String[] args, boolean dumpAll) { 13205 String innerPrefix = prefix + " "; 13206 synchronized (this) { 13207 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13208 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13209 pw.print(" pid="); 13210 if (r.app != null) pw.println(r.app.pid); 13211 else pw.println("(not running)"); 13212 if (dumpAll) { 13213 r.dump(pw, innerPrefix); 13214 } 13215 } 13216 if (r.app != null && r.app.thread != null) { 13217 // flush anything that is already in the PrintWriter since the thread is going 13218 // to write to the file descriptor directly 13219 pw.flush(); 13220 try { 13221 TransferPipe tp = new TransferPipe(); 13222 try { 13223 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13224 r.appToken, innerPrefix, args); 13225 tp.go(fd); 13226 } finally { 13227 tp.kill(); 13228 } 13229 } catch (IOException e) { 13230 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13231 } catch (RemoteException e) { 13232 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13233 } 13234 } 13235 } 13236 13237 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13238 int opti, boolean dumpAll, String dumpPackage) { 13239 boolean needSep = false; 13240 boolean onlyHistory = false; 13241 boolean printedAnything = false; 13242 13243 if ("history".equals(dumpPackage)) { 13244 if (opti < args.length && "-s".equals(args[opti])) { 13245 dumpAll = false; 13246 } 13247 onlyHistory = true; 13248 dumpPackage = null; 13249 } 13250 13251 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13252 if (!onlyHistory && dumpAll) { 13253 if (mRegisteredReceivers.size() > 0) { 13254 boolean printed = false; 13255 Iterator it = mRegisteredReceivers.values().iterator(); 13256 while (it.hasNext()) { 13257 ReceiverList r = (ReceiverList)it.next(); 13258 if (dumpPackage != null && (r.app == null || 13259 !dumpPackage.equals(r.app.info.packageName))) { 13260 continue; 13261 } 13262 if (!printed) { 13263 pw.println(" Registered Receivers:"); 13264 needSep = true; 13265 printed = true; 13266 printedAnything = true; 13267 } 13268 pw.print(" * "); pw.println(r); 13269 r.dump(pw, " "); 13270 } 13271 } 13272 13273 if (mReceiverResolver.dump(pw, needSep ? 13274 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13275 " ", dumpPackage, false, false)) { 13276 needSep = true; 13277 printedAnything = true; 13278 } 13279 } 13280 13281 for (BroadcastQueue q : mBroadcastQueues) { 13282 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13283 printedAnything |= needSep; 13284 } 13285 13286 needSep = true; 13287 13288 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13289 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13290 if (needSep) { 13291 pw.println(); 13292 } 13293 needSep = true; 13294 printedAnything = true; 13295 pw.print(" Sticky broadcasts for user "); 13296 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13297 StringBuilder sb = new StringBuilder(128); 13298 for (Map.Entry<String, ArrayList<Intent>> ent 13299 : mStickyBroadcasts.valueAt(user).entrySet()) { 13300 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13301 if (dumpAll) { 13302 pw.println(":"); 13303 ArrayList<Intent> intents = ent.getValue(); 13304 final int N = intents.size(); 13305 for (int i=0; i<N; i++) { 13306 sb.setLength(0); 13307 sb.append(" Intent: "); 13308 intents.get(i).toShortString(sb, false, true, false, false); 13309 pw.println(sb.toString()); 13310 Bundle bundle = intents.get(i).getExtras(); 13311 if (bundle != null) { 13312 pw.print(" "); 13313 pw.println(bundle.toString()); 13314 } 13315 } 13316 } else { 13317 pw.println(""); 13318 } 13319 } 13320 } 13321 } 13322 13323 if (!onlyHistory && dumpAll) { 13324 pw.println(); 13325 for (BroadcastQueue queue : mBroadcastQueues) { 13326 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13327 + queue.mBroadcastsScheduled); 13328 } 13329 pw.println(" mHandler:"); 13330 mHandler.dump(new PrintWriterPrinter(pw), " "); 13331 needSep = true; 13332 printedAnything = true; 13333 } 13334 13335 if (!printedAnything) { 13336 pw.println(" (nothing)"); 13337 } 13338 } 13339 13340 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13341 int opti, boolean dumpAll, String dumpPackage) { 13342 boolean needSep; 13343 boolean printedAnything = false; 13344 13345 ItemMatcher matcher = new ItemMatcher(); 13346 matcher.build(args, opti); 13347 13348 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13349 13350 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13351 printedAnything |= needSep; 13352 13353 if (mLaunchingProviders.size() > 0) { 13354 boolean printed = false; 13355 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13356 ContentProviderRecord r = mLaunchingProviders.get(i); 13357 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13358 continue; 13359 } 13360 if (!printed) { 13361 if (needSep) pw.println(); 13362 needSep = true; 13363 pw.println(" Launching content providers:"); 13364 printed = true; 13365 printedAnything = true; 13366 } 13367 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13368 pw.println(r); 13369 } 13370 } 13371 13372 if (mGrantedUriPermissions.size() > 0) { 13373 boolean printed = false; 13374 int dumpUid = -2; 13375 if (dumpPackage != null) { 13376 try { 13377 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13378 } catch (NameNotFoundException e) { 13379 dumpUid = -1; 13380 } 13381 } 13382 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13383 int uid = mGrantedUriPermissions.keyAt(i); 13384 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13385 continue; 13386 } 13387 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13388 if (!printed) { 13389 if (needSep) pw.println(); 13390 needSep = true; 13391 pw.println(" Granted Uri Permissions:"); 13392 printed = true; 13393 printedAnything = true; 13394 } 13395 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13396 for (UriPermission perm : perms.values()) { 13397 pw.print(" "); pw.println(perm); 13398 if (dumpAll) { 13399 perm.dump(pw, " "); 13400 } 13401 } 13402 } 13403 } 13404 13405 if (!printedAnything) { 13406 pw.println(" (nothing)"); 13407 } 13408 } 13409 13410 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13411 int opti, boolean dumpAll, String dumpPackage) { 13412 boolean printed = false; 13413 13414 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13415 13416 if (mIntentSenderRecords.size() > 0) { 13417 Iterator<WeakReference<PendingIntentRecord>> it 13418 = mIntentSenderRecords.values().iterator(); 13419 while (it.hasNext()) { 13420 WeakReference<PendingIntentRecord> ref = it.next(); 13421 PendingIntentRecord rec = ref != null ? ref.get(): null; 13422 if (dumpPackage != null && (rec == null 13423 || !dumpPackage.equals(rec.key.packageName))) { 13424 continue; 13425 } 13426 printed = true; 13427 if (rec != null) { 13428 pw.print(" * "); pw.println(rec); 13429 if (dumpAll) { 13430 rec.dump(pw, " "); 13431 } 13432 } else { 13433 pw.print(" * "); pw.println(ref); 13434 } 13435 } 13436 } 13437 13438 if (!printed) { 13439 pw.println(" (nothing)"); 13440 } 13441 } 13442 13443 private static final int dumpProcessList(PrintWriter pw, 13444 ActivityManagerService service, List list, 13445 String prefix, String normalLabel, String persistentLabel, 13446 String dumpPackage) { 13447 int numPers = 0; 13448 final int N = list.size()-1; 13449 for (int i=N; i>=0; i--) { 13450 ProcessRecord r = (ProcessRecord)list.get(i); 13451 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13452 continue; 13453 } 13454 pw.println(String.format("%s%s #%2d: %s", 13455 prefix, (r.persistent ? persistentLabel : normalLabel), 13456 i, r.toString())); 13457 if (r.persistent) { 13458 numPers++; 13459 } 13460 } 13461 return numPers; 13462 } 13463 13464 private static final boolean dumpProcessOomList(PrintWriter pw, 13465 ActivityManagerService service, List<ProcessRecord> origList, 13466 String prefix, String normalLabel, String persistentLabel, 13467 boolean inclDetails, String dumpPackage) { 13468 13469 ArrayList<Pair<ProcessRecord, Integer>> list 13470 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13471 for (int i=0; i<origList.size(); i++) { 13472 ProcessRecord r = origList.get(i); 13473 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13474 continue; 13475 } 13476 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13477 } 13478 13479 if (list.size() <= 0) { 13480 return false; 13481 } 13482 13483 Comparator<Pair<ProcessRecord, Integer>> comparator 13484 = new Comparator<Pair<ProcessRecord, Integer>>() { 13485 @Override 13486 public int compare(Pair<ProcessRecord, Integer> object1, 13487 Pair<ProcessRecord, Integer> object2) { 13488 if (object1.first.setAdj != object2.first.setAdj) { 13489 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13490 } 13491 if (object1.second.intValue() != object2.second.intValue()) { 13492 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13493 } 13494 return 0; 13495 } 13496 }; 13497 13498 Collections.sort(list, comparator); 13499 13500 final long curRealtime = SystemClock.elapsedRealtime(); 13501 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13502 final long curUptime = SystemClock.uptimeMillis(); 13503 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13504 13505 for (int i=list.size()-1; i>=0; i--) { 13506 ProcessRecord r = list.get(i).first; 13507 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13508 char schedGroup; 13509 switch (r.setSchedGroup) { 13510 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13511 schedGroup = 'B'; 13512 break; 13513 case Process.THREAD_GROUP_DEFAULT: 13514 schedGroup = 'F'; 13515 break; 13516 default: 13517 schedGroup = '?'; 13518 break; 13519 } 13520 char foreground; 13521 if (r.foregroundActivities) { 13522 foreground = 'A'; 13523 } else if (r.foregroundServices) { 13524 foreground = 'S'; 13525 } else { 13526 foreground = ' '; 13527 } 13528 String procState = ProcessList.makeProcStateString(r.curProcState); 13529 pw.print(prefix); 13530 pw.print(r.persistent ? persistentLabel : normalLabel); 13531 pw.print(" #"); 13532 int num = (origList.size()-1)-list.get(i).second; 13533 if (num < 10) pw.print(' '); 13534 pw.print(num); 13535 pw.print(": "); 13536 pw.print(oomAdj); 13537 pw.print(' '); 13538 pw.print(schedGroup); 13539 pw.print('/'); 13540 pw.print(foreground); 13541 pw.print('/'); 13542 pw.print(procState); 13543 pw.print(" trm:"); 13544 if (r.trimMemoryLevel < 10) pw.print(' '); 13545 pw.print(r.trimMemoryLevel); 13546 pw.print(' '); 13547 pw.print(r.toShortString()); 13548 pw.print(" ("); 13549 pw.print(r.adjType); 13550 pw.println(')'); 13551 if (r.adjSource != null || r.adjTarget != null) { 13552 pw.print(prefix); 13553 pw.print(" "); 13554 if (r.adjTarget instanceof ComponentName) { 13555 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13556 } else if (r.adjTarget != null) { 13557 pw.print(r.adjTarget.toString()); 13558 } else { 13559 pw.print("{null}"); 13560 } 13561 pw.print("<="); 13562 if (r.adjSource instanceof ProcessRecord) { 13563 pw.print("Proc{"); 13564 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13565 pw.println("}"); 13566 } else if (r.adjSource != null) { 13567 pw.println(r.adjSource.toString()); 13568 } else { 13569 pw.println("{null}"); 13570 } 13571 } 13572 if (inclDetails) { 13573 pw.print(prefix); 13574 pw.print(" "); 13575 pw.print("oom: max="); pw.print(r.maxAdj); 13576 pw.print(" curRaw="); pw.print(r.curRawAdj); 13577 pw.print(" setRaw="); pw.print(r.setRawAdj); 13578 pw.print(" cur="); pw.print(r.curAdj); 13579 pw.print(" set="); pw.println(r.setAdj); 13580 pw.print(prefix); 13581 pw.print(" "); 13582 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13583 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13584 pw.print(" lastPss="); pw.print(r.lastPss); 13585 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13586 pw.print(prefix); 13587 pw.print(" "); 13588 pw.print("cached="); pw.print(r.cached); 13589 pw.print(" empty="); pw.print(r.empty); 13590 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13591 13592 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13593 if (r.lastWakeTime != 0) { 13594 long wtime; 13595 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13596 synchronized (stats) { 13597 wtime = stats.getProcessWakeTime(r.info.uid, 13598 r.pid, curRealtime); 13599 } 13600 long timeUsed = wtime - r.lastWakeTime; 13601 pw.print(prefix); 13602 pw.print(" "); 13603 pw.print("keep awake over "); 13604 TimeUtils.formatDuration(realtimeSince, pw); 13605 pw.print(" used "); 13606 TimeUtils.formatDuration(timeUsed, pw); 13607 pw.print(" ("); 13608 pw.print((timeUsed*100)/realtimeSince); 13609 pw.println("%)"); 13610 } 13611 if (r.lastCpuTime != 0) { 13612 long timeUsed = r.curCpuTime - r.lastCpuTime; 13613 pw.print(prefix); 13614 pw.print(" "); 13615 pw.print("run cpu over "); 13616 TimeUtils.formatDuration(uptimeSince, pw); 13617 pw.print(" used "); 13618 TimeUtils.formatDuration(timeUsed, pw); 13619 pw.print(" ("); 13620 pw.print((timeUsed*100)/uptimeSince); 13621 pw.println("%)"); 13622 } 13623 } 13624 } 13625 } 13626 return true; 13627 } 13628 13629 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13630 String[] args) { 13631 ArrayList<ProcessRecord> procs; 13632 synchronized (this) { 13633 if (args != null && args.length > start 13634 && args[start].charAt(0) != '-') { 13635 procs = new ArrayList<ProcessRecord>(); 13636 int pid = -1; 13637 try { 13638 pid = Integer.parseInt(args[start]); 13639 } catch (NumberFormatException e) { 13640 } 13641 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13642 ProcessRecord proc = mLruProcesses.get(i); 13643 if (proc.pid == pid) { 13644 procs.add(proc); 13645 } else if (allPkgs && proc.pkgList != null 13646 && proc.pkgList.containsKey(args[start])) { 13647 procs.add(proc); 13648 } else if (proc.processName.equals(args[start])) { 13649 procs.add(proc); 13650 } 13651 } 13652 if (procs.size() <= 0) { 13653 return null; 13654 } 13655 } else { 13656 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13657 } 13658 } 13659 return procs; 13660 } 13661 13662 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13663 PrintWriter pw, String[] args) { 13664 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13665 if (procs == null) { 13666 pw.println("No process found for: " + args[0]); 13667 return; 13668 } 13669 13670 long uptime = SystemClock.uptimeMillis(); 13671 long realtime = SystemClock.elapsedRealtime(); 13672 pw.println("Applications Graphics Acceleration Info:"); 13673 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13674 13675 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13676 ProcessRecord r = procs.get(i); 13677 if (r.thread != null) { 13678 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13679 pw.flush(); 13680 try { 13681 TransferPipe tp = new TransferPipe(); 13682 try { 13683 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13684 tp.go(fd); 13685 } finally { 13686 tp.kill(); 13687 } 13688 } catch (IOException e) { 13689 pw.println("Failure while dumping the app: " + r); 13690 pw.flush(); 13691 } catch (RemoteException e) { 13692 pw.println("Got a RemoteException while dumping the app " + r); 13693 pw.flush(); 13694 } 13695 } 13696 } 13697 } 13698 13699 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13700 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13701 if (procs == null) { 13702 pw.println("No process found for: " + args[0]); 13703 return; 13704 } 13705 13706 pw.println("Applications Database Info:"); 13707 13708 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13709 ProcessRecord r = procs.get(i); 13710 if (r.thread != null) { 13711 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13712 pw.flush(); 13713 try { 13714 TransferPipe tp = new TransferPipe(); 13715 try { 13716 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13717 tp.go(fd); 13718 } finally { 13719 tp.kill(); 13720 } 13721 } catch (IOException e) { 13722 pw.println("Failure while dumping the app: " + r); 13723 pw.flush(); 13724 } catch (RemoteException e) { 13725 pw.println("Got a RemoteException while dumping the app " + r); 13726 pw.flush(); 13727 } 13728 } 13729 } 13730 } 13731 13732 final static class MemItem { 13733 final boolean isProc; 13734 final String label; 13735 final String shortLabel; 13736 final long pss; 13737 final int id; 13738 final boolean hasActivities; 13739 ArrayList<MemItem> subitems; 13740 13741 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13742 boolean _hasActivities) { 13743 isProc = true; 13744 label = _label; 13745 shortLabel = _shortLabel; 13746 pss = _pss; 13747 id = _id; 13748 hasActivities = _hasActivities; 13749 } 13750 13751 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13752 isProc = false; 13753 label = _label; 13754 shortLabel = _shortLabel; 13755 pss = _pss; 13756 id = _id; 13757 hasActivities = false; 13758 } 13759 } 13760 13761 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13762 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13763 if (sort && !isCompact) { 13764 Collections.sort(items, new Comparator<MemItem>() { 13765 @Override 13766 public int compare(MemItem lhs, MemItem rhs) { 13767 if (lhs.pss < rhs.pss) { 13768 return 1; 13769 } else if (lhs.pss > rhs.pss) { 13770 return -1; 13771 } 13772 return 0; 13773 } 13774 }); 13775 } 13776 13777 for (int i=0; i<items.size(); i++) { 13778 MemItem mi = items.get(i); 13779 if (!isCompact) { 13780 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13781 } else if (mi.isProc) { 13782 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13783 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13784 pw.println(mi.hasActivities ? ",a" : ",e"); 13785 } else { 13786 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13787 pw.println(mi.pss); 13788 } 13789 if (mi.subitems != null) { 13790 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13791 true, isCompact); 13792 } 13793 } 13794 } 13795 13796 // These are in KB. 13797 static final long[] DUMP_MEM_BUCKETS = new long[] { 13798 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13799 120*1024, 160*1024, 200*1024, 13800 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13801 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13802 }; 13803 13804 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13805 boolean stackLike) { 13806 int start = label.lastIndexOf('.'); 13807 if (start >= 0) start++; 13808 else start = 0; 13809 int end = label.length(); 13810 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13811 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13812 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13813 out.append(bucket); 13814 out.append(stackLike ? "MB." : "MB "); 13815 out.append(label, start, end); 13816 return; 13817 } 13818 } 13819 out.append(memKB/1024); 13820 out.append(stackLike ? "MB." : "MB "); 13821 out.append(label, start, end); 13822 } 13823 13824 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13825 ProcessList.NATIVE_ADJ, 13826 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13827 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13828 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13829 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13830 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13831 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13832 }; 13833 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13834 "Native", 13835 "System", "Persistent", "Persistent Service", "Foreground", 13836 "Visible", "Perceptible", 13837 "Heavy Weight", "Backup", 13838 "A Services", "Home", 13839 "Previous", "B Services", "Cached" 13840 }; 13841 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13842 "native", 13843 "sys", "pers", "persvc", "fore", 13844 "vis", "percept", 13845 "heavy", "backup", 13846 "servicea", "home", 13847 "prev", "serviceb", "cached" 13848 }; 13849 13850 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13851 long realtime, boolean isCheckinRequest, boolean isCompact) { 13852 if (isCheckinRequest || isCompact) { 13853 // short checkin version 13854 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13855 } else { 13856 pw.println("Applications Memory Usage (kB):"); 13857 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13858 } 13859 } 13860 13861 private static final int KSM_SHARED = 0; 13862 private static final int KSM_SHARING = 1; 13863 private static final int KSM_UNSHARED = 2; 13864 private static final int KSM_VOLATILE = 3; 13865 13866 private final long[] getKsmInfo() { 13867 long[] longOut = new long[4]; 13868 final int[] SINGLE_LONG_FORMAT = new int[] { 13869 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13870 }; 13871 long[] longTmp = new long[1]; 13872 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13873 SINGLE_LONG_FORMAT, null, longTmp, null); 13874 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13875 longTmp[0] = 0; 13876 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13877 SINGLE_LONG_FORMAT, null, longTmp, null); 13878 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13879 longTmp[0] = 0; 13880 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13881 SINGLE_LONG_FORMAT, null, longTmp, null); 13882 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13883 longTmp[0] = 0; 13884 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13885 SINGLE_LONG_FORMAT, null, longTmp, null); 13886 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13887 return longOut; 13888 } 13889 13890 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13891 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13892 boolean dumpDetails = false; 13893 boolean dumpFullDetails = false; 13894 boolean dumpDalvik = false; 13895 boolean oomOnly = false; 13896 boolean isCompact = false; 13897 boolean localOnly = false; 13898 boolean packages = false; 13899 13900 int opti = 0; 13901 while (opti < args.length) { 13902 String opt = args[opti]; 13903 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13904 break; 13905 } 13906 opti++; 13907 if ("-a".equals(opt)) { 13908 dumpDetails = true; 13909 dumpFullDetails = true; 13910 dumpDalvik = true; 13911 } else if ("-d".equals(opt)) { 13912 dumpDalvik = true; 13913 } else if ("-c".equals(opt)) { 13914 isCompact = true; 13915 } else if ("--oom".equals(opt)) { 13916 oomOnly = true; 13917 } else if ("--local".equals(opt)) { 13918 localOnly = true; 13919 } else if ("--package".equals(opt)) { 13920 packages = true; 13921 } else if ("-h".equals(opt)) { 13922 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13923 pw.println(" -a: include all available information for each process."); 13924 pw.println(" -d: include dalvik details when dumping process details."); 13925 pw.println(" -c: dump in a compact machine-parseable representation."); 13926 pw.println(" --oom: only show processes organized by oom adj."); 13927 pw.println(" --local: only collect details locally, don't call process."); 13928 pw.println(" --package: interpret process arg as package, dumping all"); 13929 pw.println(" processes that have loaded that package."); 13930 pw.println("If [process] is specified it can be the name or "); 13931 pw.println("pid of a specific process to dump."); 13932 return; 13933 } else { 13934 pw.println("Unknown argument: " + opt + "; use -h for help"); 13935 } 13936 } 13937 13938 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13939 long uptime = SystemClock.uptimeMillis(); 13940 long realtime = SystemClock.elapsedRealtime(); 13941 final long[] tmpLong = new long[1]; 13942 13943 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13944 if (procs == null) { 13945 // No Java processes. Maybe they want to print a native process. 13946 if (args != null && args.length > opti 13947 && args[opti].charAt(0) != '-') { 13948 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13949 = new ArrayList<ProcessCpuTracker.Stats>(); 13950 updateCpuStatsNow(); 13951 int findPid = -1; 13952 try { 13953 findPid = Integer.parseInt(args[opti]); 13954 } catch (NumberFormatException e) { 13955 } 13956 synchronized (mProcessCpuTracker) { 13957 final int N = mProcessCpuTracker.countStats(); 13958 for (int i=0; i<N; i++) { 13959 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13960 if (st.pid == findPid || (st.baseName != null 13961 && st.baseName.equals(args[opti]))) { 13962 nativeProcs.add(st); 13963 } 13964 } 13965 } 13966 if (nativeProcs.size() > 0) { 13967 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13968 isCompact); 13969 Debug.MemoryInfo mi = null; 13970 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13971 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13972 final int pid = r.pid; 13973 if (!isCheckinRequest && dumpDetails) { 13974 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13975 } 13976 if (mi == null) { 13977 mi = new Debug.MemoryInfo(); 13978 } 13979 if (dumpDetails || (!brief && !oomOnly)) { 13980 Debug.getMemoryInfo(pid, mi); 13981 } else { 13982 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13983 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13984 } 13985 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13986 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13987 if (isCheckinRequest) { 13988 pw.println(); 13989 } 13990 } 13991 return; 13992 } 13993 } 13994 pw.println("No process found for: " + args[opti]); 13995 return; 13996 } 13997 13998 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13999 dumpDetails = true; 14000 } 14001 14002 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14003 14004 String[] innerArgs = new String[args.length-opti]; 14005 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14006 14007 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14008 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14009 long nativePss = 0; 14010 long dalvikPss = 0; 14011 long otherPss = 0; 14012 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14013 14014 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14015 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14016 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14017 14018 long totalPss = 0; 14019 long cachedPss = 0; 14020 14021 Debug.MemoryInfo mi = null; 14022 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14023 final ProcessRecord r = procs.get(i); 14024 final IApplicationThread thread; 14025 final int pid; 14026 final int oomAdj; 14027 final boolean hasActivities; 14028 synchronized (this) { 14029 thread = r.thread; 14030 pid = r.pid; 14031 oomAdj = r.getSetAdjWithServices(); 14032 hasActivities = r.activities.size() > 0; 14033 } 14034 if (thread != null) { 14035 if (!isCheckinRequest && dumpDetails) { 14036 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14037 } 14038 if (mi == null) { 14039 mi = new Debug.MemoryInfo(); 14040 } 14041 if (dumpDetails || (!brief && !oomOnly)) { 14042 Debug.getMemoryInfo(pid, mi); 14043 } else { 14044 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14045 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14046 } 14047 if (dumpDetails) { 14048 if (localOnly) { 14049 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14050 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14051 if (isCheckinRequest) { 14052 pw.println(); 14053 } 14054 } else { 14055 try { 14056 pw.flush(); 14057 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14058 dumpDalvik, innerArgs); 14059 } catch (RemoteException e) { 14060 if (!isCheckinRequest) { 14061 pw.println("Got RemoteException!"); 14062 pw.flush(); 14063 } 14064 } 14065 } 14066 } 14067 14068 final long myTotalPss = mi.getTotalPss(); 14069 final long myTotalUss = mi.getTotalUss(); 14070 14071 synchronized (this) { 14072 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14073 // Record this for posterity if the process has been stable. 14074 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14075 } 14076 } 14077 14078 if (!isCheckinRequest && mi != null) { 14079 totalPss += myTotalPss; 14080 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14081 (hasActivities ? " / activities)" : ")"), 14082 r.processName, myTotalPss, pid, hasActivities); 14083 procMems.add(pssItem); 14084 procMemsMap.put(pid, pssItem); 14085 14086 nativePss += mi.nativePss; 14087 dalvikPss += mi.dalvikPss; 14088 otherPss += mi.otherPss; 14089 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14090 long mem = mi.getOtherPss(j); 14091 miscPss[j] += mem; 14092 otherPss -= mem; 14093 } 14094 14095 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14096 cachedPss += myTotalPss; 14097 } 14098 14099 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14100 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14101 || oomIndex == (oomPss.length-1)) { 14102 oomPss[oomIndex] += myTotalPss; 14103 if (oomProcs[oomIndex] == null) { 14104 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14105 } 14106 oomProcs[oomIndex].add(pssItem); 14107 break; 14108 } 14109 } 14110 } 14111 } 14112 } 14113 14114 long nativeProcTotalPss = 0; 14115 14116 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14117 // If we are showing aggregations, also look for native processes to 14118 // include so that our aggregations are more accurate. 14119 updateCpuStatsNow(); 14120 synchronized (mProcessCpuTracker) { 14121 final int N = mProcessCpuTracker.countStats(); 14122 for (int i=0; i<N; i++) { 14123 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14124 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14125 if (mi == null) { 14126 mi = new Debug.MemoryInfo(); 14127 } 14128 if (!brief && !oomOnly) { 14129 Debug.getMemoryInfo(st.pid, mi); 14130 } else { 14131 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14132 mi.nativePrivateDirty = (int)tmpLong[0]; 14133 } 14134 14135 final long myTotalPss = mi.getTotalPss(); 14136 totalPss += myTotalPss; 14137 nativeProcTotalPss += myTotalPss; 14138 14139 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14140 st.name, myTotalPss, st.pid, false); 14141 procMems.add(pssItem); 14142 14143 nativePss += mi.nativePss; 14144 dalvikPss += mi.dalvikPss; 14145 otherPss += mi.otherPss; 14146 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14147 long mem = mi.getOtherPss(j); 14148 miscPss[j] += mem; 14149 otherPss -= mem; 14150 } 14151 oomPss[0] += myTotalPss; 14152 if (oomProcs[0] == null) { 14153 oomProcs[0] = new ArrayList<MemItem>(); 14154 } 14155 oomProcs[0].add(pssItem); 14156 } 14157 } 14158 } 14159 14160 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14161 14162 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14163 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14164 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14165 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14166 String label = Debug.MemoryInfo.getOtherLabel(j); 14167 catMems.add(new MemItem(label, label, miscPss[j], j)); 14168 } 14169 14170 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14171 for (int j=0; j<oomPss.length; j++) { 14172 if (oomPss[j] != 0) { 14173 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14174 : DUMP_MEM_OOM_LABEL[j]; 14175 MemItem item = new MemItem(label, label, oomPss[j], 14176 DUMP_MEM_OOM_ADJ[j]); 14177 item.subitems = oomProcs[j]; 14178 oomMems.add(item); 14179 } 14180 } 14181 14182 if (!brief && !oomOnly && !isCompact) { 14183 pw.println(); 14184 pw.println("Total PSS by process:"); 14185 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14186 pw.println(); 14187 } 14188 if (!isCompact) { 14189 pw.println("Total PSS by OOM adjustment:"); 14190 } 14191 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14192 if (!brief && !oomOnly) { 14193 PrintWriter out = categoryPw != null ? categoryPw : pw; 14194 if (!isCompact) { 14195 out.println(); 14196 out.println("Total PSS by category:"); 14197 } 14198 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14199 } 14200 if (!isCompact) { 14201 pw.println(); 14202 } 14203 MemInfoReader memInfo = new MemInfoReader(); 14204 memInfo.readMemInfo(); 14205 if (nativeProcTotalPss > 0) { 14206 synchronized (this) { 14207 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14208 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14209 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14210 } 14211 } 14212 if (!brief) { 14213 if (!isCompact) { 14214 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14215 pw.print(" kB (status "); 14216 switch (mLastMemoryLevel) { 14217 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14218 pw.println("normal)"); 14219 break; 14220 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14221 pw.println("moderate)"); 14222 break; 14223 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14224 pw.println("low)"); 14225 break; 14226 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14227 pw.println("critical)"); 14228 break; 14229 default: 14230 pw.print(mLastMemoryLevel); 14231 pw.println(")"); 14232 break; 14233 } 14234 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14235 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14236 pw.print(cachedPss); pw.print(" cached pss + "); 14237 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14238 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14239 } else { 14240 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14241 pw.print(cachedPss + memInfo.getCachedSizeKb() 14242 + memInfo.getFreeSizeKb()); pw.print(","); 14243 pw.println(totalPss - cachedPss); 14244 } 14245 } 14246 if (!isCompact) { 14247 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14248 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14249 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14250 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14251 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14252 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14253 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14254 } 14255 if (!brief) { 14256 if (memInfo.getZramTotalSizeKb() != 0) { 14257 if (!isCompact) { 14258 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14259 pw.print(" kB physical used for "); 14260 pw.print(memInfo.getSwapTotalSizeKb() 14261 - memInfo.getSwapFreeSizeKb()); 14262 pw.print(" kB in swap ("); 14263 pw.print(memInfo.getSwapTotalSizeKb()); 14264 pw.println(" kB total swap)"); 14265 } else { 14266 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14267 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14268 pw.println(memInfo.getSwapFreeSizeKb()); 14269 } 14270 } 14271 final long[] ksm = getKsmInfo(); 14272 if (!isCompact) { 14273 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14274 || ksm[KSM_VOLATILE] != 0) { 14275 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14276 pw.print(" kB saved from shared "); 14277 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14278 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14279 pw.print(" kB unshared; "); 14280 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14281 } 14282 pw.print(" Tuning: "); 14283 pw.print(ActivityManager.staticGetMemoryClass()); 14284 pw.print(" (large "); 14285 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14286 pw.print("), oom "); 14287 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14288 pw.print(" kB"); 14289 pw.print(", restore limit "); 14290 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14291 pw.print(" kB"); 14292 if (ActivityManager.isLowRamDeviceStatic()) { 14293 pw.print(" (low-ram)"); 14294 } 14295 if (ActivityManager.isHighEndGfx()) { 14296 pw.print(" (high-end-gfx)"); 14297 } 14298 pw.println(); 14299 } else { 14300 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14301 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14302 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14303 pw.print("tuning,"); 14304 pw.print(ActivityManager.staticGetMemoryClass()); 14305 pw.print(','); 14306 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14307 pw.print(','); 14308 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14309 if (ActivityManager.isLowRamDeviceStatic()) { 14310 pw.print(",low-ram"); 14311 } 14312 if (ActivityManager.isHighEndGfx()) { 14313 pw.print(",high-end-gfx"); 14314 } 14315 pw.println(); 14316 } 14317 } 14318 } 14319 } 14320 14321 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14322 String name) { 14323 sb.append(" "); 14324 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14325 sb.append(' '); 14326 sb.append(ProcessList.makeProcStateString(procState)); 14327 sb.append(' '); 14328 ProcessList.appendRamKb(sb, pss); 14329 sb.append(" kB: "); 14330 sb.append(name); 14331 } 14332 14333 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14334 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14335 sb.append(" ("); 14336 sb.append(mi.pid); 14337 sb.append(") "); 14338 sb.append(mi.adjType); 14339 sb.append('\n'); 14340 if (mi.adjReason != null) { 14341 sb.append(" "); 14342 sb.append(mi.adjReason); 14343 sb.append('\n'); 14344 } 14345 } 14346 14347 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14348 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14349 for (int i=0, N=memInfos.size(); i<N; i++) { 14350 ProcessMemInfo mi = memInfos.get(i); 14351 infoMap.put(mi.pid, mi); 14352 } 14353 updateCpuStatsNow(); 14354 synchronized (mProcessCpuTracker) { 14355 final int N = mProcessCpuTracker.countStats(); 14356 for (int i=0; i<N; i++) { 14357 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14358 if (st.vsize > 0) { 14359 long pss = Debug.getPss(st.pid, null); 14360 if (pss > 0) { 14361 if (infoMap.indexOfKey(st.pid) < 0) { 14362 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14363 ProcessList.NATIVE_ADJ, -1, "native", null); 14364 mi.pss = pss; 14365 memInfos.add(mi); 14366 } 14367 } 14368 } 14369 } 14370 } 14371 14372 long totalPss = 0; 14373 for (int i=0, N=memInfos.size(); i<N; i++) { 14374 ProcessMemInfo mi = memInfos.get(i); 14375 if (mi.pss == 0) { 14376 mi.pss = Debug.getPss(mi.pid, null); 14377 } 14378 totalPss += mi.pss; 14379 } 14380 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14381 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14382 if (lhs.oomAdj != rhs.oomAdj) { 14383 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14384 } 14385 if (lhs.pss != rhs.pss) { 14386 return lhs.pss < rhs.pss ? 1 : -1; 14387 } 14388 return 0; 14389 } 14390 }); 14391 14392 StringBuilder tag = new StringBuilder(128); 14393 StringBuilder stack = new StringBuilder(128); 14394 tag.append("Low on memory -- "); 14395 appendMemBucket(tag, totalPss, "total", false); 14396 appendMemBucket(stack, totalPss, "total", true); 14397 14398 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14399 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14400 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14401 14402 boolean firstLine = true; 14403 int lastOomAdj = Integer.MIN_VALUE; 14404 long extraNativeRam = 0; 14405 long cachedPss = 0; 14406 for (int i=0, N=memInfos.size(); i<N; i++) { 14407 ProcessMemInfo mi = memInfos.get(i); 14408 14409 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14410 cachedPss += mi.pss; 14411 } 14412 14413 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14414 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14415 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14416 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14417 if (lastOomAdj != mi.oomAdj) { 14418 lastOomAdj = mi.oomAdj; 14419 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14420 tag.append(" / "); 14421 } 14422 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14423 if (firstLine) { 14424 stack.append(":"); 14425 firstLine = false; 14426 } 14427 stack.append("\n\t at "); 14428 } else { 14429 stack.append("$"); 14430 } 14431 } else { 14432 tag.append(" "); 14433 stack.append("$"); 14434 } 14435 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14436 appendMemBucket(tag, mi.pss, mi.name, false); 14437 } 14438 appendMemBucket(stack, mi.pss, mi.name, true); 14439 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14440 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14441 stack.append("("); 14442 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14443 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14444 stack.append(DUMP_MEM_OOM_LABEL[k]); 14445 stack.append(":"); 14446 stack.append(DUMP_MEM_OOM_ADJ[k]); 14447 } 14448 } 14449 stack.append(")"); 14450 } 14451 } 14452 14453 appendMemInfo(fullNativeBuilder, mi); 14454 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14455 // The short form only has native processes that are >= 1MB. 14456 if (mi.pss >= 1000) { 14457 appendMemInfo(shortNativeBuilder, mi); 14458 } else { 14459 extraNativeRam += mi.pss; 14460 } 14461 } else { 14462 // Short form has all other details, but if we have collected RAM 14463 // from smaller native processes let's dump a summary of that. 14464 if (extraNativeRam > 0) { 14465 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14466 -1, extraNativeRam, "(Other native)"); 14467 shortNativeBuilder.append('\n'); 14468 extraNativeRam = 0; 14469 } 14470 appendMemInfo(fullJavaBuilder, mi); 14471 } 14472 } 14473 14474 fullJavaBuilder.append(" "); 14475 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14476 fullJavaBuilder.append(" kB: TOTAL\n"); 14477 14478 MemInfoReader memInfo = new MemInfoReader(); 14479 memInfo.readMemInfo(); 14480 final long[] infos = memInfo.getRawInfo(); 14481 14482 StringBuilder memInfoBuilder = new StringBuilder(1024); 14483 Debug.getMemInfo(infos); 14484 memInfoBuilder.append(" MemInfo: "); 14485 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14486 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14487 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14488 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14489 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14490 memInfoBuilder.append(" "); 14491 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14492 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14493 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14494 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14495 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14496 memInfoBuilder.append(" ZRAM: "); 14497 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14498 memInfoBuilder.append(" kB RAM, "); 14499 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14500 memInfoBuilder.append(" kB swap total, "); 14501 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14502 memInfoBuilder.append(" kB swap free\n"); 14503 } 14504 final long[] ksm = getKsmInfo(); 14505 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14506 || ksm[KSM_VOLATILE] != 0) { 14507 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14508 memInfoBuilder.append(" kB saved from shared "); 14509 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14510 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14511 memInfoBuilder.append(" kB unshared; "); 14512 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14513 } 14514 memInfoBuilder.append(" Free RAM: "); 14515 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14516 + memInfo.getFreeSizeKb()); 14517 memInfoBuilder.append(" kB\n"); 14518 memInfoBuilder.append(" Used RAM: "); 14519 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14520 memInfoBuilder.append(" kB\n"); 14521 memInfoBuilder.append(" Lost RAM: "); 14522 memInfoBuilder.append(memInfo.getTotalSizeKb() 14523 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14524 - memInfo.getKernelUsedSizeKb()); 14525 memInfoBuilder.append(" kB\n"); 14526 Slog.i(TAG, "Low on memory:"); 14527 Slog.i(TAG, shortNativeBuilder.toString()); 14528 Slog.i(TAG, fullJavaBuilder.toString()); 14529 Slog.i(TAG, memInfoBuilder.toString()); 14530 14531 StringBuilder dropBuilder = new StringBuilder(1024); 14532 /* 14533 StringWriter oomSw = new StringWriter(); 14534 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14535 StringWriter catSw = new StringWriter(); 14536 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14537 String[] emptyArgs = new String[] { }; 14538 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14539 oomPw.flush(); 14540 String oomString = oomSw.toString(); 14541 */ 14542 dropBuilder.append("Low on memory:"); 14543 dropBuilder.append(stack); 14544 dropBuilder.append('\n'); 14545 dropBuilder.append(fullNativeBuilder); 14546 dropBuilder.append(fullJavaBuilder); 14547 dropBuilder.append('\n'); 14548 dropBuilder.append(memInfoBuilder); 14549 dropBuilder.append('\n'); 14550 /* 14551 dropBuilder.append(oomString); 14552 dropBuilder.append('\n'); 14553 */ 14554 StringWriter catSw = new StringWriter(); 14555 synchronized (ActivityManagerService.this) { 14556 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14557 String[] emptyArgs = new String[] { }; 14558 catPw.println(); 14559 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14560 catPw.println(); 14561 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14562 false, false, null); 14563 catPw.println(); 14564 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14565 catPw.flush(); 14566 } 14567 dropBuilder.append(catSw.toString()); 14568 addErrorToDropBox("lowmem", null, "system_server", null, 14569 null, tag.toString(), dropBuilder.toString(), null, null); 14570 //Slog.i(TAG, "Sent to dropbox:"); 14571 //Slog.i(TAG, dropBuilder.toString()); 14572 synchronized (ActivityManagerService.this) { 14573 long now = SystemClock.uptimeMillis(); 14574 if (mLastMemUsageReportTime < now) { 14575 mLastMemUsageReportTime = now; 14576 } 14577 } 14578 } 14579 14580 /** 14581 * Searches array of arguments for the specified string 14582 * @param args array of argument strings 14583 * @param value value to search for 14584 * @return true if the value is contained in the array 14585 */ 14586 private static boolean scanArgs(String[] args, String value) { 14587 if (args != null) { 14588 for (String arg : args) { 14589 if (value.equals(arg)) { 14590 return true; 14591 } 14592 } 14593 } 14594 return false; 14595 } 14596 14597 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14598 ContentProviderRecord cpr, boolean always) { 14599 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14600 14601 if (!inLaunching || always) { 14602 synchronized (cpr) { 14603 cpr.launchingApp = null; 14604 cpr.notifyAll(); 14605 } 14606 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14607 String names[] = cpr.info.authority.split(";"); 14608 for (int j = 0; j < names.length; j++) { 14609 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14610 } 14611 } 14612 14613 for (int i=0; i<cpr.connections.size(); i++) { 14614 ContentProviderConnection conn = cpr.connections.get(i); 14615 if (conn.waiting) { 14616 // If this connection is waiting for the provider, then we don't 14617 // need to mess with its process unless we are always removing 14618 // or for some reason the provider is not currently launching. 14619 if (inLaunching && !always) { 14620 continue; 14621 } 14622 } 14623 ProcessRecord capp = conn.client; 14624 conn.dead = true; 14625 if (conn.stableCount > 0) { 14626 if (!capp.persistent && capp.thread != null 14627 && capp.pid != 0 14628 && capp.pid != MY_PID) { 14629 capp.kill("depends on provider " 14630 + cpr.name.flattenToShortString() 14631 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14632 } 14633 } else if (capp.thread != null && conn.provider.provider != null) { 14634 try { 14635 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14636 } catch (RemoteException e) { 14637 } 14638 // In the protocol here, we don't expect the client to correctly 14639 // clean up this connection, we'll just remove it. 14640 cpr.connections.remove(i); 14641 conn.client.conProviders.remove(conn); 14642 } 14643 } 14644 14645 if (inLaunching && always) { 14646 mLaunchingProviders.remove(cpr); 14647 } 14648 return inLaunching; 14649 } 14650 14651 /** 14652 * Main code for cleaning up a process when it has gone away. This is 14653 * called both as a result of the process dying, or directly when stopping 14654 * a process when running in single process mode. 14655 * 14656 * @return Returns true if the given process has been restarted, so the 14657 * app that was passed in must remain on the process lists. 14658 */ 14659 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14660 boolean restarting, boolean allowRestart, int index) { 14661 if (index >= 0) { 14662 removeLruProcessLocked(app); 14663 ProcessList.remove(app.pid); 14664 } 14665 14666 mProcessesToGc.remove(app); 14667 mPendingPssProcesses.remove(app); 14668 14669 // Dismiss any open dialogs. 14670 if (app.crashDialog != null && !app.forceCrashReport) { 14671 app.crashDialog.dismiss(); 14672 app.crashDialog = null; 14673 } 14674 if (app.anrDialog != null) { 14675 app.anrDialog.dismiss(); 14676 app.anrDialog = null; 14677 } 14678 if (app.waitDialog != null) { 14679 app.waitDialog.dismiss(); 14680 app.waitDialog = null; 14681 } 14682 14683 app.crashing = false; 14684 app.notResponding = false; 14685 14686 app.resetPackageList(mProcessStats); 14687 app.unlinkDeathRecipient(); 14688 app.makeInactive(mProcessStats); 14689 app.waitingToKill = null; 14690 app.forcingToForeground = null; 14691 updateProcessForegroundLocked(app, false, false); 14692 app.foregroundActivities = false; 14693 app.hasShownUi = false; 14694 app.treatLikeActivity = false; 14695 app.hasAboveClient = false; 14696 app.hasClientActivities = false; 14697 14698 mServices.killServicesLocked(app, allowRestart); 14699 14700 boolean restart = false; 14701 14702 // Remove published content providers. 14703 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14704 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14705 final boolean always = app.bad || !allowRestart; 14706 if (removeDyingProviderLocked(app, cpr, always) || always) { 14707 // We left the provider in the launching list, need to 14708 // restart it. 14709 restart = true; 14710 } 14711 14712 cpr.provider = null; 14713 cpr.proc = null; 14714 } 14715 app.pubProviders.clear(); 14716 14717 // Take care of any launching providers waiting for this process. 14718 if (checkAppInLaunchingProvidersLocked(app, false)) { 14719 restart = true; 14720 } 14721 14722 // Unregister from connected content providers. 14723 if (!app.conProviders.isEmpty()) { 14724 for (int i=0; i<app.conProviders.size(); i++) { 14725 ContentProviderConnection conn = app.conProviders.get(i); 14726 conn.provider.connections.remove(conn); 14727 } 14728 app.conProviders.clear(); 14729 } 14730 14731 // At this point there may be remaining entries in mLaunchingProviders 14732 // where we were the only one waiting, so they are no longer of use. 14733 // Look for these and clean up if found. 14734 // XXX Commented out for now. Trying to figure out a way to reproduce 14735 // the actual situation to identify what is actually going on. 14736 if (false) { 14737 for (int i=0; i<mLaunchingProviders.size(); i++) { 14738 ContentProviderRecord cpr = (ContentProviderRecord) 14739 mLaunchingProviders.get(i); 14740 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14741 synchronized (cpr) { 14742 cpr.launchingApp = null; 14743 cpr.notifyAll(); 14744 } 14745 } 14746 } 14747 } 14748 14749 skipCurrentReceiverLocked(app); 14750 14751 // Unregister any receivers. 14752 for (int i=app.receivers.size()-1; i>=0; i--) { 14753 removeReceiverLocked(app.receivers.valueAt(i)); 14754 } 14755 app.receivers.clear(); 14756 14757 // If the app is undergoing backup, tell the backup manager about it 14758 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14759 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14760 + mBackupTarget.appInfo + " died during backup"); 14761 try { 14762 IBackupManager bm = IBackupManager.Stub.asInterface( 14763 ServiceManager.getService(Context.BACKUP_SERVICE)); 14764 bm.agentDisconnected(app.info.packageName); 14765 } catch (RemoteException e) { 14766 // can't happen; backup manager is local 14767 } 14768 } 14769 14770 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14771 ProcessChangeItem item = mPendingProcessChanges.get(i); 14772 if (item.pid == app.pid) { 14773 mPendingProcessChanges.remove(i); 14774 mAvailProcessChanges.add(item); 14775 } 14776 } 14777 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14778 14779 // If the caller is restarting this app, then leave it in its 14780 // current lists and let the caller take care of it. 14781 if (restarting) { 14782 return false; 14783 } 14784 14785 if (!app.persistent || app.isolated) { 14786 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14787 "Removing non-persistent process during cleanup: " + app); 14788 mProcessNames.remove(app.processName, app.uid); 14789 mIsolatedProcesses.remove(app.uid); 14790 if (mHeavyWeightProcess == app) { 14791 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14792 mHeavyWeightProcess.userId, 0)); 14793 mHeavyWeightProcess = null; 14794 } 14795 } else if (!app.removed) { 14796 // This app is persistent, so we need to keep its record around. 14797 // If it is not already on the pending app list, add it there 14798 // and start a new process for it. 14799 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14800 mPersistentStartingProcesses.add(app); 14801 restart = true; 14802 } 14803 } 14804 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14805 "Clean-up removing on hold: " + app); 14806 mProcessesOnHold.remove(app); 14807 14808 if (app == mHomeProcess) { 14809 mHomeProcess = null; 14810 } 14811 if (app == mPreviousProcess) { 14812 mPreviousProcess = null; 14813 } 14814 14815 if (restart && !app.isolated) { 14816 // We have components that still need to be running in the 14817 // process, so re-launch it. 14818 if (index < 0) { 14819 ProcessList.remove(app.pid); 14820 } 14821 mProcessNames.put(app.processName, app.uid, app); 14822 startProcessLocked(app, "restart", app.processName); 14823 return true; 14824 } else if (app.pid > 0 && app.pid != MY_PID) { 14825 // Goodbye! 14826 boolean removed; 14827 synchronized (mPidsSelfLocked) { 14828 mPidsSelfLocked.remove(app.pid); 14829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14830 } 14831 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14832 if (app.isolated) { 14833 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14834 } 14835 app.setPid(0); 14836 } 14837 return false; 14838 } 14839 14840 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14841 // Look through the content providers we are waiting to have launched, 14842 // and if any run in this process then either schedule a restart of 14843 // the process or kill the client waiting for it if this process has 14844 // gone bad. 14845 int NL = mLaunchingProviders.size(); 14846 boolean restart = false; 14847 for (int i=0; i<NL; i++) { 14848 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14849 if (cpr.launchingApp == app) { 14850 if (!alwaysBad && !app.bad) { 14851 restart = true; 14852 } else { 14853 removeDyingProviderLocked(app, cpr, true); 14854 // cpr should have been removed from mLaunchingProviders 14855 NL = mLaunchingProviders.size(); 14856 i--; 14857 } 14858 } 14859 } 14860 return restart; 14861 } 14862 14863 // ========================================================= 14864 // SERVICES 14865 // ========================================================= 14866 14867 @Override 14868 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14869 int flags) { 14870 enforceNotIsolatedCaller("getServices"); 14871 synchronized (this) { 14872 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14873 } 14874 } 14875 14876 @Override 14877 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14878 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14879 synchronized (this) { 14880 return mServices.getRunningServiceControlPanelLocked(name); 14881 } 14882 } 14883 14884 @Override 14885 public ComponentName startService(IApplicationThread caller, Intent service, 14886 String resolvedType, int userId) { 14887 enforceNotIsolatedCaller("startService"); 14888 // Refuse possible leaked file descriptors 14889 if (service != null && service.hasFileDescriptors() == true) { 14890 throw new IllegalArgumentException("File descriptors passed in Intent"); 14891 } 14892 14893 if (DEBUG_SERVICE) 14894 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14895 synchronized(this) { 14896 final int callingPid = Binder.getCallingPid(); 14897 final int callingUid = Binder.getCallingUid(); 14898 final long origId = Binder.clearCallingIdentity(); 14899 ComponentName res = mServices.startServiceLocked(caller, service, 14900 resolvedType, callingPid, callingUid, userId); 14901 Binder.restoreCallingIdentity(origId); 14902 return res; 14903 } 14904 } 14905 14906 ComponentName startServiceInPackage(int uid, 14907 Intent service, String resolvedType, int userId) { 14908 synchronized(this) { 14909 if (DEBUG_SERVICE) 14910 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14911 final long origId = Binder.clearCallingIdentity(); 14912 ComponentName res = mServices.startServiceLocked(null, service, 14913 resolvedType, -1, uid, userId); 14914 Binder.restoreCallingIdentity(origId); 14915 return res; 14916 } 14917 } 14918 14919 @Override 14920 public int stopService(IApplicationThread caller, Intent service, 14921 String resolvedType, int userId) { 14922 enforceNotIsolatedCaller("stopService"); 14923 // Refuse possible leaked file descriptors 14924 if (service != null && service.hasFileDescriptors() == true) { 14925 throw new IllegalArgumentException("File descriptors passed in Intent"); 14926 } 14927 14928 synchronized(this) { 14929 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14930 } 14931 } 14932 14933 @Override 14934 public IBinder peekService(Intent service, String resolvedType) { 14935 enforceNotIsolatedCaller("peekService"); 14936 // Refuse possible leaked file descriptors 14937 if (service != null && service.hasFileDescriptors() == true) { 14938 throw new IllegalArgumentException("File descriptors passed in Intent"); 14939 } 14940 synchronized(this) { 14941 return mServices.peekServiceLocked(service, resolvedType); 14942 } 14943 } 14944 14945 @Override 14946 public boolean stopServiceToken(ComponentName className, IBinder token, 14947 int startId) { 14948 synchronized(this) { 14949 return mServices.stopServiceTokenLocked(className, token, startId); 14950 } 14951 } 14952 14953 @Override 14954 public void setServiceForeground(ComponentName className, IBinder token, 14955 int id, Notification notification, boolean removeNotification) { 14956 synchronized(this) { 14957 mServices.setServiceForegroundLocked(className, token, id, notification, 14958 removeNotification); 14959 } 14960 } 14961 14962 @Override 14963 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14964 boolean requireFull, String name, String callerPackage) { 14965 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14966 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14967 } 14968 14969 int unsafeConvertIncomingUser(int userId) { 14970 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14971 ? mCurrentUserId : userId; 14972 } 14973 14974 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14975 int allowMode, String name, String callerPackage) { 14976 final int callingUserId = UserHandle.getUserId(callingUid); 14977 if (callingUserId == userId) { 14978 return userId; 14979 } 14980 14981 // Note that we may be accessing mCurrentUserId outside of a lock... 14982 // shouldn't be a big deal, if this is being called outside 14983 // of a locked context there is intrinsically a race with 14984 // the value the caller will receive and someone else changing it. 14985 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14986 // we will switch to the calling user if access to the current user fails. 14987 int targetUserId = unsafeConvertIncomingUser(userId); 14988 14989 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14990 final boolean allow; 14991 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14992 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14993 // If the caller has this permission, they always pass go. And collect $200. 14994 allow = true; 14995 } else if (allowMode == ALLOW_FULL_ONLY) { 14996 // We require full access, sucks to be you. 14997 allow = false; 14998 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14999 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15000 // If the caller does not have either permission, they are always doomed. 15001 allow = false; 15002 } else if (allowMode == ALLOW_NON_FULL) { 15003 // We are blanket allowing non-full access, you lucky caller! 15004 allow = true; 15005 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15006 // We may or may not allow this depending on whether the two users are 15007 // in the same profile. 15008 synchronized (mUserProfileGroupIdsSelfLocked) { 15009 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15010 UserInfo.NO_PROFILE_GROUP_ID); 15011 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15012 UserInfo.NO_PROFILE_GROUP_ID); 15013 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15014 && callingProfile == targetProfile; 15015 } 15016 } else { 15017 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15018 } 15019 if (!allow) { 15020 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15021 // In this case, they would like to just execute as their 15022 // owner user instead of failing. 15023 targetUserId = callingUserId; 15024 } else { 15025 StringBuilder builder = new StringBuilder(128); 15026 builder.append("Permission Denial: "); 15027 builder.append(name); 15028 if (callerPackage != null) { 15029 builder.append(" from "); 15030 builder.append(callerPackage); 15031 } 15032 builder.append(" asks to run as user "); 15033 builder.append(userId); 15034 builder.append(" but is calling from user "); 15035 builder.append(UserHandle.getUserId(callingUid)); 15036 builder.append("; this requires "); 15037 builder.append(INTERACT_ACROSS_USERS_FULL); 15038 if (allowMode != ALLOW_FULL_ONLY) { 15039 builder.append(" or "); 15040 builder.append(INTERACT_ACROSS_USERS); 15041 } 15042 String msg = builder.toString(); 15043 Slog.w(TAG, msg); 15044 throw new SecurityException(msg); 15045 } 15046 } 15047 } 15048 if (!allowAll && targetUserId < 0) { 15049 throw new IllegalArgumentException( 15050 "Call does not support special user #" + targetUserId); 15051 } 15052 // Check shell permission 15053 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15054 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15055 targetUserId)) { 15056 throw new SecurityException("Shell does not have permission to access user " 15057 + targetUserId + "\n " + Debug.getCallers(3)); 15058 } 15059 } 15060 return targetUserId; 15061 } 15062 15063 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15064 String className, int flags) { 15065 boolean result = false; 15066 // For apps that don't have pre-defined UIDs, check for permission 15067 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15068 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15069 if (ActivityManager.checkUidPermission( 15070 INTERACT_ACROSS_USERS, 15071 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15072 ComponentName comp = new ComponentName(aInfo.packageName, className); 15073 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15074 + " requests FLAG_SINGLE_USER, but app does not hold " 15075 + INTERACT_ACROSS_USERS; 15076 Slog.w(TAG, msg); 15077 throw new SecurityException(msg); 15078 } 15079 // Permission passed 15080 result = true; 15081 } 15082 } else if ("system".equals(componentProcessName)) { 15083 result = true; 15084 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15085 // Phone app and persistent apps are allowed to export singleuser providers. 15086 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15087 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15088 } 15089 if (DEBUG_MU) { 15090 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15091 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15092 } 15093 return result; 15094 } 15095 15096 /** 15097 * Checks to see if the caller is in the same app as the singleton 15098 * component, or the component is in a special app. It allows special apps 15099 * to export singleton components but prevents exporting singleton 15100 * components for regular apps. 15101 */ 15102 boolean isValidSingletonCall(int callingUid, int componentUid) { 15103 int componentAppId = UserHandle.getAppId(componentUid); 15104 return UserHandle.isSameApp(callingUid, componentUid) 15105 || componentAppId == Process.SYSTEM_UID 15106 || componentAppId == Process.PHONE_UID 15107 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15108 == PackageManager.PERMISSION_GRANTED; 15109 } 15110 15111 public int bindService(IApplicationThread caller, IBinder token, 15112 Intent service, String resolvedType, 15113 IServiceConnection connection, int flags, int userId) { 15114 enforceNotIsolatedCaller("bindService"); 15115 15116 // Refuse possible leaked file descriptors 15117 if (service != null && service.hasFileDescriptors() == true) { 15118 throw new IllegalArgumentException("File descriptors passed in Intent"); 15119 } 15120 15121 synchronized(this) { 15122 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15123 connection, flags, userId); 15124 } 15125 } 15126 15127 public boolean unbindService(IServiceConnection connection) { 15128 synchronized (this) { 15129 return mServices.unbindServiceLocked(connection); 15130 } 15131 } 15132 15133 public void publishService(IBinder token, Intent intent, IBinder service) { 15134 // Refuse possible leaked file descriptors 15135 if (intent != null && intent.hasFileDescriptors() == true) { 15136 throw new IllegalArgumentException("File descriptors passed in Intent"); 15137 } 15138 15139 synchronized(this) { 15140 if (!(token instanceof ServiceRecord)) { 15141 throw new IllegalArgumentException("Invalid service token"); 15142 } 15143 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15144 } 15145 } 15146 15147 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15148 // Refuse possible leaked file descriptors 15149 if (intent != null && intent.hasFileDescriptors() == true) { 15150 throw new IllegalArgumentException("File descriptors passed in Intent"); 15151 } 15152 15153 synchronized(this) { 15154 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15155 } 15156 } 15157 15158 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15159 synchronized(this) { 15160 if (!(token instanceof ServiceRecord)) { 15161 throw new IllegalArgumentException("Invalid service token"); 15162 } 15163 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15164 } 15165 } 15166 15167 // ========================================================= 15168 // BACKUP AND RESTORE 15169 // ========================================================= 15170 15171 // Cause the target app to be launched if necessary and its backup agent 15172 // instantiated. The backup agent will invoke backupAgentCreated() on the 15173 // activity manager to announce its creation. 15174 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15175 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15176 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15177 15178 synchronized(this) { 15179 // !!! TODO: currently no check here that we're already bound 15180 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15181 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15182 synchronized (stats) { 15183 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15184 } 15185 15186 // Backup agent is now in use, its package can't be stopped. 15187 try { 15188 AppGlobals.getPackageManager().setPackageStoppedState( 15189 app.packageName, false, UserHandle.getUserId(app.uid)); 15190 } catch (RemoteException e) { 15191 } catch (IllegalArgumentException e) { 15192 Slog.w(TAG, "Failed trying to unstop package " 15193 + app.packageName + ": " + e); 15194 } 15195 15196 BackupRecord r = new BackupRecord(ss, app, backupMode); 15197 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15198 ? new ComponentName(app.packageName, app.backupAgentName) 15199 : new ComponentName("android", "FullBackupAgent"); 15200 // startProcessLocked() returns existing proc's record if it's already running 15201 ProcessRecord proc = startProcessLocked(app.processName, app, 15202 false, 0, "backup", hostingName, false, false, false); 15203 if (proc == null) { 15204 Slog.e(TAG, "Unable to start backup agent process " + r); 15205 return false; 15206 } 15207 15208 r.app = proc; 15209 mBackupTarget = r; 15210 mBackupAppName = app.packageName; 15211 15212 // Try not to kill the process during backup 15213 updateOomAdjLocked(proc); 15214 15215 // If the process is already attached, schedule the creation of the backup agent now. 15216 // If it is not yet live, this will be done when it attaches to the framework. 15217 if (proc.thread != null) { 15218 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15219 try { 15220 proc.thread.scheduleCreateBackupAgent(app, 15221 compatibilityInfoForPackageLocked(app), backupMode); 15222 } catch (RemoteException e) { 15223 // Will time out on the backup manager side 15224 } 15225 } else { 15226 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15227 } 15228 // Invariants: at this point, the target app process exists and the application 15229 // is either already running or in the process of coming up. mBackupTarget and 15230 // mBackupAppName describe the app, so that when it binds back to the AM we 15231 // know that it's scheduled for a backup-agent operation. 15232 } 15233 15234 return true; 15235 } 15236 15237 @Override 15238 public void clearPendingBackup() { 15239 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15240 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15241 15242 synchronized (this) { 15243 mBackupTarget = null; 15244 mBackupAppName = null; 15245 } 15246 } 15247 15248 // A backup agent has just come up 15249 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15250 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15251 + " = " + agent); 15252 15253 synchronized(this) { 15254 if (!agentPackageName.equals(mBackupAppName)) { 15255 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15256 return; 15257 } 15258 } 15259 15260 long oldIdent = Binder.clearCallingIdentity(); 15261 try { 15262 IBackupManager bm = IBackupManager.Stub.asInterface( 15263 ServiceManager.getService(Context.BACKUP_SERVICE)); 15264 bm.agentConnected(agentPackageName, agent); 15265 } catch (RemoteException e) { 15266 // can't happen; the backup manager service is local 15267 } catch (Exception e) { 15268 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15269 e.printStackTrace(); 15270 } finally { 15271 Binder.restoreCallingIdentity(oldIdent); 15272 } 15273 } 15274 15275 // done with this agent 15276 public void unbindBackupAgent(ApplicationInfo appInfo) { 15277 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15278 if (appInfo == null) { 15279 Slog.w(TAG, "unbind backup agent for null app"); 15280 return; 15281 } 15282 15283 synchronized(this) { 15284 try { 15285 if (mBackupAppName == null) { 15286 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15287 return; 15288 } 15289 15290 if (!mBackupAppName.equals(appInfo.packageName)) { 15291 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15292 return; 15293 } 15294 15295 // Not backing this app up any more; reset its OOM adjustment 15296 final ProcessRecord proc = mBackupTarget.app; 15297 updateOomAdjLocked(proc); 15298 15299 // If the app crashed during backup, 'thread' will be null here 15300 if (proc.thread != null) { 15301 try { 15302 proc.thread.scheduleDestroyBackupAgent(appInfo, 15303 compatibilityInfoForPackageLocked(appInfo)); 15304 } catch (Exception e) { 15305 Slog.e(TAG, "Exception when unbinding backup agent:"); 15306 e.printStackTrace(); 15307 } 15308 } 15309 } finally { 15310 mBackupTarget = null; 15311 mBackupAppName = null; 15312 } 15313 } 15314 } 15315 // ========================================================= 15316 // BROADCASTS 15317 // ========================================================= 15318 15319 private final List getStickiesLocked(String action, IntentFilter filter, 15320 List cur, int userId) { 15321 final ContentResolver resolver = mContext.getContentResolver(); 15322 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15323 if (stickies == null) { 15324 return cur; 15325 } 15326 final ArrayList<Intent> list = stickies.get(action); 15327 if (list == null) { 15328 return cur; 15329 } 15330 int N = list.size(); 15331 for (int i=0; i<N; i++) { 15332 Intent intent = list.get(i); 15333 if (filter.match(resolver, intent, true, TAG) >= 0) { 15334 if (cur == null) { 15335 cur = new ArrayList<Intent>(); 15336 } 15337 cur.add(intent); 15338 } 15339 } 15340 return cur; 15341 } 15342 15343 boolean isPendingBroadcastProcessLocked(int pid) { 15344 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15345 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15346 } 15347 15348 void skipPendingBroadcastLocked(int pid) { 15349 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15350 for (BroadcastQueue queue : mBroadcastQueues) { 15351 queue.skipPendingBroadcastLocked(pid); 15352 } 15353 } 15354 15355 // The app just attached; send any pending broadcasts that it should receive 15356 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15357 boolean didSomething = false; 15358 for (BroadcastQueue queue : mBroadcastQueues) { 15359 didSomething |= queue.sendPendingBroadcastsLocked(app); 15360 } 15361 return didSomething; 15362 } 15363 15364 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15365 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15366 enforceNotIsolatedCaller("registerReceiver"); 15367 int callingUid; 15368 int callingPid; 15369 synchronized(this) { 15370 ProcessRecord callerApp = null; 15371 if (caller != null) { 15372 callerApp = getRecordForAppLocked(caller); 15373 if (callerApp == null) { 15374 throw new SecurityException( 15375 "Unable to find app for caller " + caller 15376 + " (pid=" + Binder.getCallingPid() 15377 + ") when registering receiver " + receiver); 15378 } 15379 if (callerApp.info.uid != Process.SYSTEM_UID && 15380 !callerApp.pkgList.containsKey(callerPackage) && 15381 !"android".equals(callerPackage)) { 15382 throw new SecurityException("Given caller package " + callerPackage 15383 + " is not running in process " + callerApp); 15384 } 15385 callingUid = callerApp.info.uid; 15386 callingPid = callerApp.pid; 15387 } else { 15388 callerPackage = null; 15389 callingUid = Binder.getCallingUid(); 15390 callingPid = Binder.getCallingPid(); 15391 } 15392 15393 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15394 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15395 15396 List allSticky = null; 15397 15398 // Look for any matching sticky broadcasts... 15399 Iterator actions = filter.actionsIterator(); 15400 if (actions != null) { 15401 while (actions.hasNext()) { 15402 String action = (String)actions.next(); 15403 allSticky = getStickiesLocked(action, filter, allSticky, 15404 UserHandle.USER_ALL); 15405 allSticky = getStickiesLocked(action, filter, allSticky, 15406 UserHandle.getUserId(callingUid)); 15407 } 15408 } else { 15409 allSticky = getStickiesLocked(null, filter, allSticky, 15410 UserHandle.USER_ALL); 15411 allSticky = getStickiesLocked(null, filter, allSticky, 15412 UserHandle.getUserId(callingUid)); 15413 } 15414 15415 // The first sticky in the list is returned directly back to 15416 // the client. 15417 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15418 15419 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15420 + ": " + sticky); 15421 15422 if (receiver == null) { 15423 return sticky; 15424 } 15425 15426 ReceiverList rl 15427 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15428 if (rl == null) { 15429 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15430 userId, receiver); 15431 if (rl.app != null) { 15432 rl.app.receivers.add(rl); 15433 } else { 15434 try { 15435 receiver.asBinder().linkToDeath(rl, 0); 15436 } catch (RemoteException e) { 15437 return sticky; 15438 } 15439 rl.linkedToDeath = true; 15440 } 15441 mRegisteredReceivers.put(receiver.asBinder(), rl); 15442 } else if (rl.uid != callingUid) { 15443 throw new IllegalArgumentException( 15444 "Receiver requested to register for uid " + callingUid 15445 + " was previously registered for uid " + rl.uid); 15446 } else if (rl.pid != callingPid) { 15447 throw new IllegalArgumentException( 15448 "Receiver requested to register for pid " + callingPid 15449 + " was previously registered for pid " + rl.pid); 15450 } else if (rl.userId != userId) { 15451 throw new IllegalArgumentException( 15452 "Receiver requested to register for user " + userId 15453 + " was previously registered for user " + rl.userId); 15454 } 15455 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15456 permission, callingUid, userId); 15457 rl.add(bf); 15458 if (!bf.debugCheck()) { 15459 Slog.w(TAG, "==> For Dynamic broadast"); 15460 } 15461 mReceiverResolver.addFilter(bf); 15462 15463 // Enqueue broadcasts for all existing stickies that match 15464 // this filter. 15465 if (allSticky != null) { 15466 ArrayList receivers = new ArrayList(); 15467 receivers.add(bf); 15468 15469 int N = allSticky.size(); 15470 for (int i=0; i<N; i++) { 15471 Intent intent = (Intent)allSticky.get(i); 15472 BroadcastQueue queue = broadcastQueueForIntent(intent); 15473 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15474 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15475 null, null, false, true, true, -1); 15476 queue.enqueueParallelBroadcastLocked(r); 15477 queue.scheduleBroadcastsLocked(); 15478 } 15479 } 15480 15481 return sticky; 15482 } 15483 } 15484 15485 public void unregisterReceiver(IIntentReceiver receiver) { 15486 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15487 15488 final long origId = Binder.clearCallingIdentity(); 15489 try { 15490 boolean doTrim = false; 15491 15492 synchronized(this) { 15493 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15494 if (rl != null) { 15495 if (rl.curBroadcast != null) { 15496 BroadcastRecord r = rl.curBroadcast; 15497 final boolean doNext = finishReceiverLocked( 15498 receiver.asBinder(), r.resultCode, r.resultData, 15499 r.resultExtras, r.resultAbort); 15500 if (doNext) { 15501 doTrim = true; 15502 r.queue.processNextBroadcast(false); 15503 } 15504 } 15505 15506 if (rl.app != null) { 15507 rl.app.receivers.remove(rl); 15508 } 15509 removeReceiverLocked(rl); 15510 if (rl.linkedToDeath) { 15511 rl.linkedToDeath = false; 15512 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15513 } 15514 } 15515 } 15516 15517 // If we actually concluded any broadcasts, we might now be able 15518 // to trim the recipients' apps from our working set 15519 if (doTrim) { 15520 trimApplications(); 15521 return; 15522 } 15523 15524 } finally { 15525 Binder.restoreCallingIdentity(origId); 15526 } 15527 } 15528 15529 void removeReceiverLocked(ReceiverList rl) { 15530 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15531 int N = rl.size(); 15532 for (int i=0; i<N; i++) { 15533 mReceiverResolver.removeFilter(rl.get(i)); 15534 } 15535 } 15536 15537 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15538 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15539 ProcessRecord r = mLruProcesses.get(i); 15540 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15541 try { 15542 r.thread.dispatchPackageBroadcast(cmd, packages); 15543 } catch (RemoteException ex) { 15544 } 15545 } 15546 } 15547 } 15548 15549 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15550 int callingUid, int[] users) { 15551 List<ResolveInfo> receivers = null; 15552 try { 15553 HashSet<ComponentName> singleUserReceivers = null; 15554 boolean scannedFirstReceivers = false; 15555 for (int user : users) { 15556 // Skip users that have Shell restrictions 15557 if (callingUid == Process.SHELL_UID 15558 && getUserManagerLocked().hasUserRestriction( 15559 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15560 continue; 15561 } 15562 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15563 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15564 if (user != 0 && newReceivers != null) { 15565 // If this is not the primary user, we need to check for 15566 // any receivers that should be filtered out. 15567 for (int i=0; i<newReceivers.size(); i++) { 15568 ResolveInfo ri = newReceivers.get(i); 15569 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15570 newReceivers.remove(i); 15571 i--; 15572 } 15573 } 15574 } 15575 if (newReceivers != null && newReceivers.size() == 0) { 15576 newReceivers = null; 15577 } 15578 if (receivers == null) { 15579 receivers = newReceivers; 15580 } else if (newReceivers != null) { 15581 // We need to concatenate the additional receivers 15582 // found with what we have do far. This would be easy, 15583 // but we also need to de-dup any receivers that are 15584 // singleUser. 15585 if (!scannedFirstReceivers) { 15586 // Collect any single user receivers we had already retrieved. 15587 scannedFirstReceivers = true; 15588 for (int i=0; i<receivers.size(); i++) { 15589 ResolveInfo ri = receivers.get(i); 15590 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15591 ComponentName cn = new ComponentName( 15592 ri.activityInfo.packageName, ri.activityInfo.name); 15593 if (singleUserReceivers == null) { 15594 singleUserReceivers = new HashSet<ComponentName>(); 15595 } 15596 singleUserReceivers.add(cn); 15597 } 15598 } 15599 } 15600 // Add the new results to the existing results, tracking 15601 // and de-dupping single user receivers. 15602 for (int i=0; i<newReceivers.size(); i++) { 15603 ResolveInfo ri = newReceivers.get(i); 15604 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15605 ComponentName cn = new ComponentName( 15606 ri.activityInfo.packageName, ri.activityInfo.name); 15607 if (singleUserReceivers == null) { 15608 singleUserReceivers = new HashSet<ComponentName>(); 15609 } 15610 if (!singleUserReceivers.contains(cn)) { 15611 singleUserReceivers.add(cn); 15612 receivers.add(ri); 15613 } 15614 } else { 15615 receivers.add(ri); 15616 } 15617 } 15618 } 15619 } 15620 } catch (RemoteException ex) { 15621 // pm is in same process, this will never happen. 15622 } 15623 return receivers; 15624 } 15625 15626 private final int broadcastIntentLocked(ProcessRecord callerApp, 15627 String callerPackage, Intent intent, String resolvedType, 15628 IIntentReceiver resultTo, int resultCode, String resultData, 15629 Bundle map, String requiredPermission, int appOp, 15630 boolean ordered, boolean sticky, int callingPid, int callingUid, 15631 int userId) { 15632 intent = new Intent(intent); 15633 15634 // By default broadcasts do not go to stopped apps. 15635 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15636 15637 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15638 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15639 + " ordered=" + ordered + " userid=" + userId); 15640 if ((resultTo != null) && !ordered) { 15641 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15642 } 15643 15644 userId = handleIncomingUser(callingPid, callingUid, userId, 15645 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15646 15647 // Make sure that the user who is receiving this broadcast is started. 15648 // If not, we will just skip it. 15649 15650 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15651 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15652 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15653 Slog.w(TAG, "Skipping broadcast of " + intent 15654 + ": user " + userId + " is stopped"); 15655 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15656 } 15657 } 15658 15659 /* 15660 * Prevent non-system code (defined here to be non-persistent 15661 * processes) from sending protected broadcasts. 15662 */ 15663 int callingAppId = UserHandle.getAppId(callingUid); 15664 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15665 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15666 || callingAppId == Process.NFC_UID || callingUid == 0) { 15667 // Always okay. 15668 } else if (callerApp == null || !callerApp.persistent) { 15669 try { 15670 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15671 intent.getAction())) { 15672 String msg = "Permission Denial: not allowed to send broadcast " 15673 + intent.getAction() + " from pid=" 15674 + callingPid + ", uid=" + callingUid; 15675 Slog.w(TAG, msg); 15676 throw new SecurityException(msg); 15677 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15678 // Special case for compatibility: we don't want apps to send this, 15679 // but historically it has not been protected and apps may be using it 15680 // to poke their own app widget. So, instead of making it protected, 15681 // just limit it to the caller. 15682 if (callerApp == null) { 15683 String msg = "Permission Denial: not allowed to send broadcast " 15684 + intent.getAction() + " from unknown caller."; 15685 Slog.w(TAG, msg); 15686 throw new SecurityException(msg); 15687 } else if (intent.getComponent() != null) { 15688 // They are good enough to send to an explicit component... verify 15689 // it is being sent to the calling app. 15690 if (!intent.getComponent().getPackageName().equals( 15691 callerApp.info.packageName)) { 15692 String msg = "Permission Denial: not allowed to send broadcast " 15693 + intent.getAction() + " to " 15694 + intent.getComponent().getPackageName() + " from " 15695 + callerApp.info.packageName; 15696 Slog.w(TAG, msg); 15697 throw new SecurityException(msg); 15698 } 15699 } else { 15700 // Limit broadcast to their own package. 15701 intent.setPackage(callerApp.info.packageName); 15702 } 15703 } 15704 } catch (RemoteException e) { 15705 Slog.w(TAG, "Remote exception", e); 15706 return ActivityManager.BROADCAST_SUCCESS; 15707 } 15708 } 15709 15710 final String action = intent.getAction(); 15711 if (action != null) { 15712 switch (action) { 15713 case Intent.ACTION_UID_REMOVED: 15714 case Intent.ACTION_PACKAGE_REMOVED: 15715 case Intent.ACTION_PACKAGE_CHANGED: 15716 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15717 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15718 // Handle special intents: if this broadcast is from the package 15719 // manager about a package being removed, we need to remove all of 15720 // its activities from the history stack. 15721 if (checkComponentPermission( 15722 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15723 callingPid, callingUid, -1, true) 15724 != PackageManager.PERMISSION_GRANTED) { 15725 String msg = "Permission Denial: " + intent.getAction() 15726 + " broadcast from " + callerPackage + " (pid=" + callingPid 15727 + ", uid=" + callingUid + ")" 15728 + " requires " 15729 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15730 Slog.w(TAG, msg); 15731 throw new SecurityException(msg); 15732 } 15733 switch (action) { 15734 case Intent.ACTION_UID_REMOVED: 15735 final Bundle intentExtras = intent.getExtras(); 15736 final int uid = intentExtras != null 15737 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15738 if (uid >= 0) { 15739 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15740 synchronized (bs) { 15741 bs.removeUidStatsLocked(uid); 15742 } 15743 mAppOpsService.uidRemoved(uid); 15744 } 15745 break; 15746 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15747 // If resources are unavailable just force stop all those packages 15748 // and flush the attribute cache as well. 15749 String list[] = 15750 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15751 if (list != null && list.length > 0) { 15752 for (int i = 0; i < list.length; i++) { 15753 forceStopPackageLocked(list[i], -1, false, true, true, 15754 false, false, userId, "storage unmount"); 15755 } 15756 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15757 sendPackageBroadcastLocked( 15758 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15759 userId); 15760 } 15761 break; 15762 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15763 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15764 break; 15765 case Intent.ACTION_PACKAGE_REMOVED: 15766 case Intent.ACTION_PACKAGE_CHANGED: 15767 Uri data = intent.getData(); 15768 String ssp; 15769 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15770 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15771 boolean fullUninstall = removed && 15772 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15773 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15774 forceStopPackageLocked(ssp, UserHandle.getAppId( 15775 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15776 false, true, true, false, fullUninstall, userId, 15777 removed ? "pkg removed" : "pkg changed"); 15778 } 15779 if (removed) { 15780 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15781 new String[] {ssp}, userId); 15782 if (fullUninstall) { 15783 mAppOpsService.packageRemoved( 15784 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15785 15786 // Remove all permissions granted from/to this package 15787 removeUriPermissionsForPackageLocked(ssp, userId, true); 15788 15789 removeTasksByPackageNameLocked(ssp, userId); 15790 } 15791 } else { 15792 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15793 } 15794 } 15795 break; 15796 } 15797 break; 15798 case Intent.ACTION_PACKAGE_ADDED: 15799 // Special case for adding a package: by default turn on compatibility mode. 15800 Uri data = intent.getData(); 15801 String ssp; 15802 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15803 final boolean replacing = 15804 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15805 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15806 15807 if (replacing) { 15808 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15809 } 15810 } 15811 break; 15812 case Intent.ACTION_TIMEZONE_CHANGED: 15813 // If this is the time zone changed action, queue up a message that will reset 15814 // the timezone of all currently running processes. This message will get 15815 // queued up before the broadcast happens. 15816 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15817 break; 15818 case Intent.ACTION_TIME_CHANGED: 15819 // If the user set the time, let all running processes know. 15820 final int is24Hour = 15821 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15822 : 0; 15823 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15824 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15825 synchronized (stats) { 15826 stats.noteCurrentTimeChangedLocked(); 15827 } 15828 break; 15829 case Intent.ACTION_CLEAR_DNS_CACHE: 15830 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15831 break; 15832 case Proxy.PROXY_CHANGE_ACTION: 15833 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15834 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15835 break; 15836 } 15837 } 15838 15839 // Add to the sticky list if requested. 15840 if (sticky) { 15841 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15842 callingPid, callingUid) 15843 != PackageManager.PERMISSION_GRANTED) { 15844 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15845 + callingPid + ", uid=" + callingUid 15846 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15847 Slog.w(TAG, msg); 15848 throw new SecurityException(msg); 15849 } 15850 if (requiredPermission != null) { 15851 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15852 + " and enforce permission " + requiredPermission); 15853 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15854 } 15855 if (intent.getComponent() != null) { 15856 throw new SecurityException( 15857 "Sticky broadcasts can't target a specific component"); 15858 } 15859 // We use userId directly here, since the "all" target is maintained 15860 // as a separate set of sticky broadcasts. 15861 if (userId != UserHandle.USER_ALL) { 15862 // But first, if this is not a broadcast to all users, then 15863 // make sure it doesn't conflict with an existing broadcast to 15864 // all users. 15865 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15866 UserHandle.USER_ALL); 15867 if (stickies != null) { 15868 ArrayList<Intent> list = stickies.get(intent.getAction()); 15869 if (list != null) { 15870 int N = list.size(); 15871 int i; 15872 for (i=0; i<N; i++) { 15873 if (intent.filterEquals(list.get(i))) { 15874 throw new IllegalArgumentException( 15875 "Sticky broadcast " + intent + " for user " 15876 + userId + " conflicts with existing global broadcast"); 15877 } 15878 } 15879 } 15880 } 15881 } 15882 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15883 if (stickies == null) { 15884 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15885 mStickyBroadcasts.put(userId, stickies); 15886 } 15887 ArrayList<Intent> list = stickies.get(intent.getAction()); 15888 if (list == null) { 15889 list = new ArrayList<Intent>(); 15890 stickies.put(intent.getAction(), list); 15891 } 15892 int N = list.size(); 15893 int i; 15894 for (i=0; i<N; i++) { 15895 if (intent.filterEquals(list.get(i))) { 15896 // This sticky already exists, replace it. 15897 list.set(i, new Intent(intent)); 15898 break; 15899 } 15900 } 15901 if (i >= N) { 15902 list.add(new Intent(intent)); 15903 } 15904 } 15905 15906 int[] users; 15907 if (userId == UserHandle.USER_ALL) { 15908 // Caller wants broadcast to go to all started users. 15909 users = mStartedUserArray; 15910 } else { 15911 // Caller wants broadcast to go to one specific user. 15912 users = new int[] {userId}; 15913 } 15914 15915 // Figure out who all will receive this broadcast. 15916 List receivers = null; 15917 List<BroadcastFilter> registeredReceivers = null; 15918 // Need to resolve the intent to interested receivers... 15919 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15920 == 0) { 15921 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15922 } 15923 if (intent.getComponent() == null) { 15924 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15925 // Query one target user at a time, excluding shell-restricted users 15926 UserManagerService ums = getUserManagerLocked(); 15927 for (int i = 0; i < users.length; i++) { 15928 if (ums.hasUserRestriction( 15929 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15930 continue; 15931 } 15932 List<BroadcastFilter> registeredReceiversForUser = 15933 mReceiverResolver.queryIntent(intent, 15934 resolvedType, false, users[i]); 15935 if (registeredReceivers == null) { 15936 registeredReceivers = registeredReceiversForUser; 15937 } else if (registeredReceiversForUser != null) { 15938 registeredReceivers.addAll(registeredReceiversForUser); 15939 } 15940 } 15941 } else { 15942 registeredReceivers = mReceiverResolver.queryIntent(intent, 15943 resolvedType, false, userId); 15944 } 15945 } 15946 15947 final boolean replacePending = 15948 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15949 15950 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15951 + " replacePending=" + replacePending); 15952 15953 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15954 if (!ordered && NR > 0) { 15955 // If we are not serializing this broadcast, then send the 15956 // registered receivers separately so they don't wait for the 15957 // components to be launched. 15958 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15959 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15960 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15961 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15962 ordered, sticky, false, userId); 15963 if (DEBUG_BROADCAST) Slog.v( 15964 TAG, "Enqueueing parallel broadcast " + r); 15965 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15966 if (!replaced) { 15967 queue.enqueueParallelBroadcastLocked(r); 15968 queue.scheduleBroadcastsLocked(); 15969 } 15970 registeredReceivers = null; 15971 NR = 0; 15972 } 15973 15974 // Merge into one list. 15975 int ir = 0; 15976 if (receivers != null) { 15977 // A special case for PACKAGE_ADDED: do not allow the package 15978 // being added to see this broadcast. This prevents them from 15979 // using this as a back door to get run as soon as they are 15980 // installed. Maybe in the future we want to have a special install 15981 // broadcast or such for apps, but we'd like to deliberately make 15982 // this decision. 15983 String skipPackages[] = null; 15984 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15985 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15986 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15987 Uri data = intent.getData(); 15988 if (data != null) { 15989 String pkgName = data.getSchemeSpecificPart(); 15990 if (pkgName != null) { 15991 skipPackages = new String[] { pkgName }; 15992 } 15993 } 15994 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15995 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15996 } 15997 if (skipPackages != null && (skipPackages.length > 0)) { 15998 for (String skipPackage : skipPackages) { 15999 if (skipPackage != null) { 16000 int NT = receivers.size(); 16001 for (int it=0; it<NT; it++) { 16002 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16003 if (curt.activityInfo.packageName.equals(skipPackage)) { 16004 receivers.remove(it); 16005 it--; 16006 NT--; 16007 } 16008 } 16009 } 16010 } 16011 } 16012 16013 int NT = receivers != null ? receivers.size() : 0; 16014 int it = 0; 16015 ResolveInfo curt = null; 16016 BroadcastFilter curr = null; 16017 while (it < NT && ir < NR) { 16018 if (curt == null) { 16019 curt = (ResolveInfo)receivers.get(it); 16020 } 16021 if (curr == null) { 16022 curr = registeredReceivers.get(ir); 16023 } 16024 if (curr.getPriority() >= curt.priority) { 16025 // Insert this broadcast record into the final list. 16026 receivers.add(it, curr); 16027 ir++; 16028 curr = null; 16029 it++; 16030 NT++; 16031 } else { 16032 // Skip to the next ResolveInfo in the final list. 16033 it++; 16034 curt = null; 16035 } 16036 } 16037 } 16038 while (ir < NR) { 16039 if (receivers == null) { 16040 receivers = new ArrayList(); 16041 } 16042 receivers.add(registeredReceivers.get(ir)); 16043 ir++; 16044 } 16045 16046 if ((receivers != null && receivers.size() > 0) 16047 || resultTo != null) { 16048 BroadcastQueue queue = broadcastQueueForIntent(intent); 16049 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16050 callerPackage, callingPid, callingUid, resolvedType, 16051 requiredPermission, appOp, receivers, resultTo, resultCode, 16052 resultData, map, ordered, sticky, false, userId); 16053 if (DEBUG_BROADCAST) Slog.v( 16054 TAG, "Enqueueing ordered broadcast " + r 16055 + ": prev had " + queue.mOrderedBroadcasts.size()); 16056 if (DEBUG_BROADCAST) { 16057 int seq = r.intent.getIntExtra("seq", -1); 16058 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16059 } 16060 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16061 if (!replaced) { 16062 queue.enqueueOrderedBroadcastLocked(r); 16063 queue.scheduleBroadcastsLocked(); 16064 } 16065 } 16066 16067 return ActivityManager.BROADCAST_SUCCESS; 16068 } 16069 16070 final Intent verifyBroadcastLocked(Intent intent) { 16071 // Refuse possible leaked file descriptors 16072 if (intent != null && intent.hasFileDescriptors() == true) { 16073 throw new IllegalArgumentException("File descriptors passed in Intent"); 16074 } 16075 16076 int flags = intent.getFlags(); 16077 16078 if (!mProcessesReady) { 16079 // if the caller really truly claims to know what they're doing, go 16080 // ahead and allow the broadcast without launching any receivers 16081 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16082 intent = new Intent(intent); 16083 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16084 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16085 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16086 + " before boot completion"); 16087 throw new IllegalStateException("Cannot broadcast before boot completed"); 16088 } 16089 } 16090 16091 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16092 throw new IllegalArgumentException( 16093 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16094 } 16095 16096 return intent; 16097 } 16098 16099 public final int broadcastIntent(IApplicationThread caller, 16100 Intent intent, String resolvedType, IIntentReceiver resultTo, 16101 int resultCode, String resultData, Bundle map, 16102 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16103 enforceNotIsolatedCaller("broadcastIntent"); 16104 synchronized(this) { 16105 intent = verifyBroadcastLocked(intent); 16106 16107 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16108 final int callingPid = Binder.getCallingPid(); 16109 final int callingUid = Binder.getCallingUid(); 16110 final long origId = Binder.clearCallingIdentity(); 16111 int res = broadcastIntentLocked(callerApp, 16112 callerApp != null ? callerApp.info.packageName : null, 16113 intent, resolvedType, resultTo, 16114 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16115 callingPid, callingUid, userId); 16116 Binder.restoreCallingIdentity(origId); 16117 return res; 16118 } 16119 } 16120 16121 int broadcastIntentInPackage(String packageName, int uid, 16122 Intent intent, String resolvedType, IIntentReceiver resultTo, 16123 int resultCode, String resultData, Bundle map, 16124 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16125 synchronized(this) { 16126 intent = verifyBroadcastLocked(intent); 16127 16128 final long origId = Binder.clearCallingIdentity(); 16129 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16130 resultTo, resultCode, resultData, map, requiredPermission, 16131 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16132 Binder.restoreCallingIdentity(origId); 16133 return res; 16134 } 16135 } 16136 16137 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16138 // Refuse possible leaked file descriptors 16139 if (intent != null && intent.hasFileDescriptors() == true) { 16140 throw new IllegalArgumentException("File descriptors passed in Intent"); 16141 } 16142 16143 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16144 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16145 16146 synchronized(this) { 16147 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16148 != PackageManager.PERMISSION_GRANTED) { 16149 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16150 + Binder.getCallingPid() 16151 + ", uid=" + Binder.getCallingUid() 16152 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16153 Slog.w(TAG, msg); 16154 throw new SecurityException(msg); 16155 } 16156 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16157 if (stickies != null) { 16158 ArrayList<Intent> list = stickies.get(intent.getAction()); 16159 if (list != null) { 16160 int N = list.size(); 16161 int i; 16162 for (i=0; i<N; i++) { 16163 if (intent.filterEquals(list.get(i))) { 16164 list.remove(i); 16165 break; 16166 } 16167 } 16168 if (list.size() <= 0) { 16169 stickies.remove(intent.getAction()); 16170 } 16171 } 16172 if (stickies.size() <= 0) { 16173 mStickyBroadcasts.remove(userId); 16174 } 16175 } 16176 } 16177 } 16178 16179 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16180 String resultData, Bundle resultExtras, boolean resultAbort) { 16181 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16182 if (r == null) { 16183 Slog.w(TAG, "finishReceiver called but not found on queue"); 16184 return false; 16185 } 16186 16187 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16188 } 16189 16190 void backgroundServicesFinishedLocked(int userId) { 16191 for (BroadcastQueue queue : mBroadcastQueues) { 16192 queue.backgroundServicesFinishedLocked(userId); 16193 } 16194 } 16195 16196 public void finishReceiver(IBinder who, int resultCode, String resultData, 16197 Bundle resultExtras, boolean resultAbort) { 16198 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16199 16200 // Refuse possible leaked file descriptors 16201 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16202 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16203 } 16204 16205 final long origId = Binder.clearCallingIdentity(); 16206 try { 16207 boolean doNext = false; 16208 BroadcastRecord r; 16209 16210 synchronized(this) { 16211 r = broadcastRecordForReceiverLocked(who); 16212 if (r != null) { 16213 doNext = r.queue.finishReceiverLocked(r, resultCode, 16214 resultData, resultExtras, resultAbort, true); 16215 } 16216 } 16217 16218 if (doNext) { 16219 r.queue.processNextBroadcast(false); 16220 } 16221 trimApplications(); 16222 } finally { 16223 Binder.restoreCallingIdentity(origId); 16224 } 16225 } 16226 16227 // ========================================================= 16228 // INSTRUMENTATION 16229 // ========================================================= 16230 16231 public boolean startInstrumentation(ComponentName className, 16232 String profileFile, int flags, Bundle arguments, 16233 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16234 int userId, String abiOverride) { 16235 enforceNotIsolatedCaller("startInstrumentation"); 16236 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16237 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16238 // Refuse possible leaked file descriptors 16239 if (arguments != null && arguments.hasFileDescriptors()) { 16240 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16241 } 16242 16243 synchronized(this) { 16244 InstrumentationInfo ii = null; 16245 ApplicationInfo ai = null; 16246 try { 16247 ii = mContext.getPackageManager().getInstrumentationInfo( 16248 className, STOCK_PM_FLAGS); 16249 ai = AppGlobals.getPackageManager().getApplicationInfo( 16250 ii.targetPackage, STOCK_PM_FLAGS, userId); 16251 } catch (PackageManager.NameNotFoundException e) { 16252 } catch (RemoteException e) { 16253 } 16254 if (ii == null) { 16255 reportStartInstrumentationFailure(watcher, className, 16256 "Unable to find instrumentation info for: " + className); 16257 return false; 16258 } 16259 if (ai == null) { 16260 reportStartInstrumentationFailure(watcher, className, 16261 "Unable to find instrumentation target package: " + ii.targetPackage); 16262 return false; 16263 } 16264 16265 int match = mContext.getPackageManager().checkSignatures( 16266 ii.targetPackage, ii.packageName); 16267 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16268 String msg = "Permission Denial: starting instrumentation " 16269 + className + " from pid=" 16270 + Binder.getCallingPid() 16271 + ", uid=" + Binder.getCallingPid() 16272 + " not allowed because package " + ii.packageName 16273 + " does not have a signature matching the target " 16274 + ii.targetPackage; 16275 reportStartInstrumentationFailure(watcher, className, msg); 16276 throw new SecurityException(msg); 16277 } 16278 16279 final long origId = Binder.clearCallingIdentity(); 16280 // Instrumentation can kill and relaunch even persistent processes 16281 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16282 "start instr"); 16283 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16284 app.instrumentationClass = className; 16285 app.instrumentationInfo = ai; 16286 app.instrumentationProfileFile = profileFile; 16287 app.instrumentationArguments = arguments; 16288 app.instrumentationWatcher = watcher; 16289 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16290 app.instrumentationResultClass = className; 16291 Binder.restoreCallingIdentity(origId); 16292 } 16293 16294 return true; 16295 } 16296 16297 /** 16298 * Report errors that occur while attempting to start Instrumentation. Always writes the 16299 * error to the logs, but if somebody is watching, send the report there too. This enables 16300 * the "am" command to report errors with more information. 16301 * 16302 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16303 * @param cn The component name of the instrumentation. 16304 * @param report The error report. 16305 */ 16306 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16307 ComponentName cn, String report) { 16308 Slog.w(TAG, report); 16309 try { 16310 if (watcher != null) { 16311 Bundle results = new Bundle(); 16312 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16313 results.putString("Error", report); 16314 watcher.instrumentationStatus(cn, -1, results); 16315 } 16316 } catch (RemoteException e) { 16317 Slog.w(TAG, e); 16318 } 16319 } 16320 16321 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16322 if (app.instrumentationWatcher != null) { 16323 try { 16324 // NOTE: IInstrumentationWatcher *must* be oneway here 16325 app.instrumentationWatcher.instrumentationFinished( 16326 app.instrumentationClass, 16327 resultCode, 16328 results); 16329 } catch (RemoteException e) { 16330 } 16331 } 16332 if (app.instrumentationUiAutomationConnection != null) { 16333 try { 16334 app.instrumentationUiAutomationConnection.shutdown(); 16335 } catch (RemoteException re) { 16336 /* ignore */ 16337 } 16338 // Only a UiAutomation can set this flag and now that 16339 // it is finished we make sure it is reset to its default. 16340 mUserIsMonkey = false; 16341 } 16342 app.instrumentationWatcher = null; 16343 app.instrumentationUiAutomationConnection = null; 16344 app.instrumentationClass = null; 16345 app.instrumentationInfo = null; 16346 app.instrumentationProfileFile = null; 16347 app.instrumentationArguments = null; 16348 16349 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16350 "finished inst"); 16351 } 16352 16353 public void finishInstrumentation(IApplicationThread target, 16354 int resultCode, Bundle results) { 16355 int userId = UserHandle.getCallingUserId(); 16356 // Refuse possible leaked file descriptors 16357 if (results != null && results.hasFileDescriptors()) { 16358 throw new IllegalArgumentException("File descriptors passed in Intent"); 16359 } 16360 16361 synchronized(this) { 16362 ProcessRecord app = getRecordForAppLocked(target); 16363 if (app == null) { 16364 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16365 return; 16366 } 16367 final long origId = Binder.clearCallingIdentity(); 16368 finishInstrumentationLocked(app, resultCode, results); 16369 Binder.restoreCallingIdentity(origId); 16370 } 16371 } 16372 16373 // ========================================================= 16374 // CONFIGURATION 16375 // ========================================================= 16376 16377 public ConfigurationInfo getDeviceConfigurationInfo() { 16378 ConfigurationInfo config = new ConfigurationInfo(); 16379 synchronized (this) { 16380 config.reqTouchScreen = mConfiguration.touchscreen; 16381 config.reqKeyboardType = mConfiguration.keyboard; 16382 config.reqNavigation = mConfiguration.navigation; 16383 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16384 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16385 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16386 } 16387 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16388 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16389 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16390 } 16391 config.reqGlEsVersion = GL_ES_VERSION; 16392 } 16393 return config; 16394 } 16395 16396 ActivityStack getFocusedStack() { 16397 return mStackSupervisor.getFocusedStack(); 16398 } 16399 16400 public Configuration getConfiguration() { 16401 Configuration ci; 16402 synchronized(this) { 16403 ci = new Configuration(mConfiguration); 16404 } 16405 return ci; 16406 } 16407 16408 public void updatePersistentConfiguration(Configuration values) { 16409 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16410 "updateConfiguration()"); 16411 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16412 "updateConfiguration()"); 16413 if (values == null) { 16414 throw new NullPointerException("Configuration must not be null"); 16415 } 16416 16417 synchronized(this) { 16418 final long origId = Binder.clearCallingIdentity(); 16419 updateConfigurationLocked(values, null, true, false); 16420 Binder.restoreCallingIdentity(origId); 16421 } 16422 } 16423 16424 public void updateConfiguration(Configuration values) { 16425 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16426 "updateConfiguration()"); 16427 16428 synchronized(this) { 16429 if (values == null && mWindowManager != null) { 16430 // sentinel: fetch the current configuration from the window manager 16431 values = mWindowManager.computeNewConfiguration(); 16432 } 16433 16434 if (mWindowManager != null) { 16435 mProcessList.applyDisplaySize(mWindowManager); 16436 } 16437 16438 final long origId = Binder.clearCallingIdentity(); 16439 if (values != null) { 16440 Settings.System.clearConfiguration(values); 16441 } 16442 updateConfigurationLocked(values, null, false, false); 16443 Binder.restoreCallingIdentity(origId); 16444 } 16445 } 16446 16447 /** 16448 * Do either or both things: (1) change the current configuration, and (2) 16449 * make sure the given activity is running with the (now) current 16450 * configuration. Returns true if the activity has been left running, or 16451 * false if <var>starting</var> is being destroyed to match the new 16452 * configuration. 16453 * @param persistent TODO 16454 */ 16455 boolean updateConfigurationLocked(Configuration values, 16456 ActivityRecord starting, boolean persistent, boolean initLocale) { 16457 int changes = 0; 16458 16459 if (values != null) { 16460 Configuration newConfig = new Configuration(mConfiguration); 16461 changes = newConfig.updateFrom(values); 16462 if (changes != 0) { 16463 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16464 Slog.i(TAG, "Updating configuration to: " + values); 16465 } 16466 16467 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16468 16469 if (values.locale != null && !initLocale) { 16470 saveLocaleLocked(values.locale, 16471 !values.locale.equals(mConfiguration.locale), 16472 values.userSetLocale); 16473 } 16474 16475 mConfigurationSeq++; 16476 if (mConfigurationSeq <= 0) { 16477 mConfigurationSeq = 1; 16478 } 16479 newConfig.seq = mConfigurationSeq; 16480 mConfiguration = newConfig; 16481 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16482 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16483 //mUsageStatsService.noteStartConfig(newConfig); 16484 16485 final Configuration configCopy = new Configuration(mConfiguration); 16486 16487 // TODO: If our config changes, should we auto dismiss any currently 16488 // showing dialogs? 16489 mShowDialogs = shouldShowDialogs(newConfig); 16490 16491 AttributeCache ac = AttributeCache.instance(); 16492 if (ac != null) { 16493 ac.updateConfiguration(configCopy); 16494 } 16495 16496 // Make sure all resources in our process are updated 16497 // right now, so that anyone who is going to retrieve 16498 // resource values after we return will be sure to get 16499 // the new ones. This is especially important during 16500 // boot, where the first config change needs to guarantee 16501 // all resources have that config before following boot 16502 // code is executed. 16503 mSystemThread.applyConfigurationToResources(configCopy); 16504 16505 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16506 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16507 msg.obj = new Configuration(configCopy); 16508 mHandler.sendMessage(msg); 16509 } 16510 16511 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16512 ProcessRecord app = mLruProcesses.get(i); 16513 try { 16514 if (app.thread != null) { 16515 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16516 + app.processName + " new config " + mConfiguration); 16517 app.thread.scheduleConfigurationChanged(configCopy); 16518 } 16519 } catch (Exception e) { 16520 } 16521 } 16522 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16523 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16524 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16525 | Intent.FLAG_RECEIVER_FOREGROUND); 16526 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16527 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16528 Process.SYSTEM_UID, UserHandle.USER_ALL); 16529 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16530 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16531 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16532 broadcastIntentLocked(null, null, intent, 16533 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16534 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16535 } 16536 } 16537 } 16538 16539 boolean kept = true; 16540 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16541 // mainStack is null during startup. 16542 if (mainStack != null) { 16543 if (changes != 0 && starting == null) { 16544 // If the configuration changed, and the caller is not already 16545 // in the process of starting an activity, then find the top 16546 // activity to check if its configuration needs to change. 16547 starting = mainStack.topRunningActivityLocked(null); 16548 } 16549 16550 if (starting != null) { 16551 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16552 // And we need to make sure at this point that all other activities 16553 // are made visible with the correct configuration. 16554 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16555 } 16556 } 16557 16558 if (values != null && mWindowManager != null) { 16559 mWindowManager.setNewConfiguration(mConfiguration); 16560 } 16561 16562 return kept; 16563 } 16564 16565 /** 16566 * Decide based on the configuration whether we should shouw the ANR, 16567 * crash, etc dialogs. The idea is that if there is no affordnace to 16568 * press the on-screen buttons, we shouldn't show the dialog. 16569 * 16570 * A thought: SystemUI might also want to get told about this, the Power 16571 * dialog / global actions also might want different behaviors. 16572 */ 16573 private static final boolean shouldShowDialogs(Configuration config) { 16574 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16575 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16576 } 16577 16578 /** 16579 * Save the locale. You must be inside a synchronized (this) block. 16580 */ 16581 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16582 if(isDiff) { 16583 SystemProperties.set("user.language", l.getLanguage()); 16584 SystemProperties.set("user.region", l.getCountry()); 16585 } 16586 16587 if(isPersist) { 16588 SystemProperties.set("persist.sys.language", l.getLanguage()); 16589 SystemProperties.set("persist.sys.country", l.getCountry()); 16590 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16591 16592 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16593 } 16594 } 16595 16596 @Override 16597 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16598 synchronized (this) { 16599 ActivityRecord srec = ActivityRecord.forToken(token); 16600 if (srec.task != null && srec.task.stack != null) { 16601 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16602 } 16603 } 16604 return false; 16605 } 16606 16607 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16608 Intent resultData) { 16609 16610 synchronized (this) { 16611 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16612 if (stack != null) { 16613 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16614 } 16615 return false; 16616 } 16617 } 16618 16619 public int getLaunchedFromUid(IBinder activityToken) { 16620 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16621 if (srec == null) { 16622 return -1; 16623 } 16624 return srec.launchedFromUid; 16625 } 16626 16627 public String getLaunchedFromPackage(IBinder activityToken) { 16628 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16629 if (srec == null) { 16630 return null; 16631 } 16632 return srec.launchedFromPackage; 16633 } 16634 16635 // ========================================================= 16636 // LIFETIME MANAGEMENT 16637 // ========================================================= 16638 16639 // Returns which broadcast queue the app is the current [or imminent] receiver 16640 // on, or 'null' if the app is not an active broadcast recipient. 16641 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16642 BroadcastRecord r = app.curReceiver; 16643 if (r != null) { 16644 return r.queue; 16645 } 16646 16647 // It's not the current receiver, but it might be starting up to become one 16648 synchronized (this) { 16649 for (BroadcastQueue queue : mBroadcastQueues) { 16650 r = queue.mPendingBroadcast; 16651 if (r != null && r.curApp == app) { 16652 // found it; report which queue it's in 16653 return queue; 16654 } 16655 } 16656 } 16657 16658 return null; 16659 } 16660 16661 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16662 boolean doingAll, long now) { 16663 if (mAdjSeq == app.adjSeq) { 16664 // This adjustment has already been computed. 16665 return app.curRawAdj; 16666 } 16667 16668 if (app.thread == null) { 16669 app.adjSeq = mAdjSeq; 16670 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16671 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16672 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16673 } 16674 16675 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16676 app.adjSource = null; 16677 app.adjTarget = null; 16678 app.empty = false; 16679 app.cached = false; 16680 16681 final int activitiesSize = app.activities.size(); 16682 16683 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16684 // The max adjustment doesn't allow this app to be anything 16685 // below foreground, so it is not worth doing work for it. 16686 app.adjType = "fixed"; 16687 app.adjSeq = mAdjSeq; 16688 app.curRawAdj = app.maxAdj; 16689 app.foregroundActivities = false; 16690 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16691 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16692 // System processes can do UI, and when they do we want to have 16693 // them trim their memory after the user leaves the UI. To 16694 // facilitate this, here we need to determine whether or not it 16695 // is currently showing UI. 16696 app.systemNoUi = true; 16697 if (app == TOP_APP) { 16698 app.systemNoUi = false; 16699 } else if (activitiesSize > 0) { 16700 for (int j = 0; j < activitiesSize; j++) { 16701 final ActivityRecord r = app.activities.get(j); 16702 if (r.visible) { 16703 app.systemNoUi = false; 16704 } 16705 } 16706 } 16707 if (!app.systemNoUi) { 16708 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16709 } 16710 return (app.curAdj=app.maxAdj); 16711 } 16712 16713 app.systemNoUi = false; 16714 16715 // Determine the importance of the process, starting with most 16716 // important to least, and assign an appropriate OOM adjustment. 16717 int adj; 16718 int schedGroup; 16719 int procState; 16720 boolean foregroundActivities = false; 16721 BroadcastQueue queue; 16722 if (app == TOP_APP) { 16723 // The last app on the list is the foreground app. 16724 adj = ProcessList.FOREGROUND_APP_ADJ; 16725 schedGroup = Process.THREAD_GROUP_DEFAULT; 16726 app.adjType = "top-activity"; 16727 foregroundActivities = true; 16728 procState = ActivityManager.PROCESS_STATE_TOP; 16729 } else if (app.instrumentationClass != null) { 16730 // Don't want to kill running instrumentation. 16731 adj = ProcessList.FOREGROUND_APP_ADJ; 16732 schedGroup = Process.THREAD_GROUP_DEFAULT; 16733 app.adjType = "instrumentation"; 16734 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16735 } else if ((queue = isReceivingBroadcast(app)) != null) { 16736 // An app that is currently receiving a broadcast also 16737 // counts as being in the foreground for OOM killer purposes. 16738 // It's placed in a sched group based on the nature of the 16739 // broadcast as reflected by which queue it's active in. 16740 adj = ProcessList.FOREGROUND_APP_ADJ; 16741 schedGroup = (queue == mFgBroadcastQueue) 16742 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16743 app.adjType = "broadcast"; 16744 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16745 } else if (app.executingServices.size() > 0) { 16746 // An app that is currently executing a service callback also 16747 // counts as being in the foreground. 16748 adj = ProcessList.FOREGROUND_APP_ADJ; 16749 schedGroup = app.execServicesFg ? 16750 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16751 app.adjType = "exec-service"; 16752 procState = ActivityManager.PROCESS_STATE_SERVICE; 16753 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16754 } else { 16755 // As far as we know the process is empty. We may change our mind later. 16756 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16757 // At this point we don't actually know the adjustment. Use the cached adj 16758 // value that the caller wants us to. 16759 adj = cachedAdj; 16760 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16761 app.cached = true; 16762 app.empty = true; 16763 app.adjType = "cch-empty"; 16764 } 16765 16766 // Examine all activities if not already foreground. 16767 if (!foregroundActivities && activitiesSize > 0) { 16768 for (int j = 0; j < activitiesSize; j++) { 16769 final ActivityRecord r = app.activities.get(j); 16770 if (r.app != app) { 16771 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16772 + app + "?!?"); 16773 continue; 16774 } 16775 if (r.visible) { 16776 // App has a visible activity; only upgrade adjustment. 16777 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16778 adj = ProcessList.VISIBLE_APP_ADJ; 16779 app.adjType = "visible"; 16780 } 16781 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16782 procState = ActivityManager.PROCESS_STATE_TOP; 16783 } 16784 schedGroup = Process.THREAD_GROUP_DEFAULT; 16785 app.cached = false; 16786 app.empty = false; 16787 foregroundActivities = true; 16788 break; 16789 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16790 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16791 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16792 app.adjType = "pausing"; 16793 } 16794 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16795 procState = ActivityManager.PROCESS_STATE_TOP; 16796 } 16797 schedGroup = Process.THREAD_GROUP_DEFAULT; 16798 app.cached = false; 16799 app.empty = false; 16800 foregroundActivities = true; 16801 } else if (r.state == ActivityState.STOPPING) { 16802 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16803 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16804 app.adjType = "stopping"; 16805 } 16806 // For the process state, we will at this point consider the 16807 // process to be cached. It will be cached either as an activity 16808 // or empty depending on whether the activity is finishing. We do 16809 // this so that we can treat the process as cached for purposes of 16810 // memory trimming (determing current memory level, trim command to 16811 // send to process) since there can be an arbitrary number of stopping 16812 // processes and they should soon all go into the cached state. 16813 if (!r.finishing) { 16814 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16815 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16816 } 16817 } 16818 app.cached = false; 16819 app.empty = false; 16820 foregroundActivities = true; 16821 } else { 16822 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16823 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16824 app.adjType = "cch-act"; 16825 } 16826 } 16827 } 16828 } 16829 16830 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16831 if (app.foregroundServices) { 16832 // The user is aware of this app, so make it visible. 16833 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16834 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16835 app.cached = false; 16836 app.adjType = "fg-service"; 16837 schedGroup = Process.THREAD_GROUP_DEFAULT; 16838 } else if (app.forcingToForeground != null) { 16839 // The user is aware of this app, so make it visible. 16840 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16841 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16842 app.cached = false; 16843 app.adjType = "force-fg"; 16844 app.adjSource = app.forcingToForeground; 16845 schedGroup = Process.THREAD_GROUP_DEFAULT; 16846 } 16847 } 16848 16849 if (app == mHeavyWeightProcess) { 16850 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16851 // We don't want to kill the current heavy-weight process. 16852 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16853 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16854 app.cached = false; 16855 app.adjType = "heavy"; 16856 } 16857 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16858 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16859 } 16860 } 16861 16862 if (app == mHomeProcess) { 16863 if (adj > ProcessList.HOME_APP_ADJ) { 16864 // This process is hosting what we currently consider to be the 16865 // home app, so we don't want to let it go into the background. 16866 adj = ProcessList.HOME_APP_ADJ; 16867 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16868 app.cached = false; 16869 app.adjType = "home"; 16870 } 16871 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16872 procState = ActivityManager.PROCESS_STATE_HOME; 16873 } 16874 } 16875 16876 if (app == mPreviousProcess && app.activities.size() > 0) { 16877 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16878 // This was the previous process that showed UI to the user. 16879 // We want to try to keep it around more aggressively, to give 16880 // a good experience around switching between two apps. 16881 adj = ProcessList.PREVIOUS_APP_ADJ; 16882 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16883 app.cached = false; 16884 app.adjType = "previous"; 16885 } 16886 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16887 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16888 } 16889 } 16890 16891 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16892 + " reason=" + app.adjType); 16893 16894 // By default, we use the computed adjustment. It may be changed if 16895 // there are applications dependent on our services or providers, but 16896 // this gives us a baseline and makes sure we don't get into an 16897 // infinite recursion. 16898 app.adjSeq = mAdjSeq; 16899 app.curRawAdj = adj; 16900 app.hasStartedServices = false; 16901 16902 if (mBackupTarget != null && app == mBackupTarget.app) { 16903 // If possible we want to avoid killing apps while they're being backed up 16904 if (adj > ProcessList.BACKUP_APP_ADJ) { 16905 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16906 adj = ProcessList.BACKUP_APP_ADJ; 16907 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16908 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16909 } 16910 app.adjType = "backup"; 16911 app.cached = false; 16912 } 16913 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16914 procState = ActivityManager.PROCESS_STATE_BACKUP; 16915 } 16916 } 16917 16918 boolean mayBeTop = false; 16919 16920 for (int is = app.services.size()-1; 16921 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16922 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16923 || procState > ActivityManager.PROCESS_STATE_TOP); 16924 is--) { 16925 ServiceRecord s = app.services.valueAt(is); 16926 if (s.startRequested) { 16927 app.hasStartedServices = true; 16928 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16929 procState = ActivityManager.PROCESS_STATE_SERVICE; 16930 } 16931 if (app.hasShownUi && app != mHomeProcess) { 16932 // If this process has shown some UI, let it immediately 16933 // go to the LRU list because it may be pretty heavy with 16934 // UI stuff. We'll tag it with a label just to help 16935 // debug and understand what is going on. 16936 if (adj > ProcessList.SERVICE_ADJ) { 16937 app.adjType = "cch-started-ui-services"; 16938 } 16939 } else { 16940 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16941 // This service has seen some activity within 16942 // recent memory, so we will keep its process ahead 16943 // of the background processes. 16944 if (adj > ProcessList.SERVICE_ADJ) { 16945 adj = ProcessList.SERVICE_ADJ; 16946 app.adjType = "started-services"; 16947 app.cached = false; 16948 } 16949 } 16950 // If we have let the service slide into the background 16951 // state, still have some text describing what it is doing 16952 // even though the service no longer has an impact. 16953 if (adj > ProcessList.SERVICE_ADJ) { 16954 app.adjType = "cch-started-services"; 16955 } 16956 } 16957 } 16958 for (int conni = s.connections.size()-1; 16959 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16960 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16961 || procState > ActivityManager.PROCESS_STATE_TOP); 16962 conni--) { 16963 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16964 for (int i = 0; 16965 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16966 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16967 || procState > ActivityManager.PROCESS_STATE_TOP); 16968 i++) { 16969 // XXX should compute this based on the max of 16970 // all connected clients. 16971 ConnectionRecord cr = clist.get(i); 16972 if (cr.binding.client == app) { 16973 // Binding to ourself is not interesting. 16974 continue; 16975 } 16976 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16977 ProcessRecord client = cr.binding.client; 16978 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16979 TOP_APP, doingAll, now); 16980 int clientProcState = client.curProcState; 16981 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16982 // If the other app is cached for any reason, for purposes here 16983 // we are going to consider it empty. The specific cached state 16984 // doesn't propagate except under certain conditions. 16985 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16986 } 16987 String adjType = null; 16988 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16989 // Not doing bind OOM management, so treat 16990 // this guy more like a started service. 16991 if (app.hasShownUi && app != mHomeProcess) { 16992 // If this process has shown some UI, let it immediately 16993 // go to the LRU list because it may be pretty heavy with 16994 // UI stuff. We'll tag it with a label just to help 16995 // debug and understand what is going on. 16996 if (adj > clientAdj) { 16997 adjType = "cch-bound-ui-services"; 16998 } 16999 app.cached = false; 17000 clientAdj = adj; 17001 clientProcState = procState; 17002 } else { 17003 if (now >= (s.lastActivity 17004 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17005 // This service has not seen activity within 17006 // recent memory, so allow it to drop to the 17007 // LRU list if there is no other reason to keep 17008 // it around. We'll also tag it with a label just 17009 // to help debug and undertand what is going on. 17010 if (adj > clientAdj) { 17011 adjType = "cch-bound-services"; 17012 } 17013 clientAdj = adj; 17014 } 17015 } 17016 } 17017 if (adj > clientAdj) { 17018 // If this process has recently shown UI, and 17019 // the process that is binding to it is less 17020 // important than being visible, then we don't 17021 // care about the binding as much as we care 17022 // about letting this process get into the LRU 17023 // list to be killed and restarted if needed for 17024 // memory. 17025 if (app.hasShownUi && app != mHomeProcess 17026 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17027 adjType = "cch-bound-ui-services"; 17028 } else { 17029 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17030 |Context.BIND_IMPORTANT)) != 0) { 17031 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17032 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17033 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17034 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17035 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17036 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17037 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17038 adj = clientAdj; 17039 } else { 17040 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17041 adj = ProcessList.VISIBLE_APP_ADJ; 17042 } 17043 } 17044 if (!client.cached) { 17045 app.cached = false; 17046 } 17047 adjType = "service"; 17048 } 17049 } 17050 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17051 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17052 schedGroup = Process.THREAD_GROUP_DEFAULT; 17053 } 17054 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17055 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17056 // Special handling of clients who are in the top state. 17057 // We *may* want to consider this process to be in the 17058 // top state as well, but only if there is not another 17059 // reason for it to be running. Being on the top is a 17060 // special state, meaning you are specifically running 17061 // for the current top app. If the process is already 17062 // running in the background for some other reason, it 17063 // is more important to continue considering it to be 17064 // in the background state. 17065 mayBeTop = true; 17066 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17067 } else { 17068 // Special handling for above-top states (persistent 17069 // processes). These should not bring the current process 17070 // into the top state, since they are not on top. Instead 17071 // give them the best state after that. 17072 clientProcState = 17073 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17074 } 17075 } 17076 } else { 17077 if (clientProcState < 17078 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17079 clientProcState = 17080 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17081 } 17082 } 17083 if (procState > clientProcState) { 17084 procState = clientProcState; 17085 } 17086 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17087 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17088 app.pendingUiClean = true; 17089 } 17090 if (adjType != null) { 17091 app.adjType = adjType; 17092 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17093 .REASON_SERVICE_IN_USE; 17094 app.adjSource = cr.binding.client; 17095 app.adjSourceProcState = clientProcState; 17096 app.adjTarget = s.name; 17097 } 17098 } 17099 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17100 app.treatLikeActivity = true; 17101 } 17102 final ActivityRecord a = cr.activity; 17103 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17104 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17105 (a.visible || a.state == ActivityState.RESUMED 17106 || a.state == ActivityState.PAUSING)) { 17107 adj = ProcessList.FOREGROUND_APP_ADJ; 17108 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17109 schedGroup = Process.THREAD_GROUP_DEFAULT; 17110 } 17111 app.cached = false; 17112 app.adjType = "service"; 17113 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17114 .REASON_SERVICE_IN_USE; 17115 app.adjSource = a; 17116 app.adjSourceProcState = procState; 17117 app.adjTarget = s.name; 17118 } 17119 } 17120 } 17121 } 17122 } 17123 17124 for (int provi = app.pubProviders.size()-1; 17125 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17126 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17127 || procState > ActivityManager.PROCESS_STATE_TOP); 17128 provi--) { 17129 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17130 for (int i = cpr.connections.size()-1; 17131 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17132 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17133 || procState > ActivityManager.PROCESS_STATE_TOP); 17134 i--) { 17135 ContentProviderConnection conn = cpr.connections.get(i); 17136 ProcessRecord client = conn.client; 17137 if (client == app) { 17138 // Being our own client is not interesting. 17139 continue; 17140 } 17141 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17142 int clientProcState = client.curProcState; 17143 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17144 // If the other app is cached for any reason, for purposes here 17145 // we are going to consider it empty. 17146 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17147 } 17148 if (adj > clientAdj) { 17149 if (app.hasShownUi && app != mHomeProcess 17150 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17151 app.adjType = "cch-ui-provider"; 17152 } else { 17153 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17154 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17155 app.adjType = "provider"; 17156 } 17157 app.cached &= client.cached; 17158 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17159 .REASON_PROVIDER_IN_USE; 17160 app.adjSource = client; 17161 app.adjSourceProcState = clientProcState; 17162 app.adjTarget = cpr.name; 17163 } 17164 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17165 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17166 // Special handling of clients who are in the top state. 17167 // We *may* want to consider this process to be in the 17168 // top state as well, but only if there is not another 17169 // reason for it to be running. Being on the top is a 17170 // special state, meaning you are specifically running 17171 // for the current top app. If the process is already 17172 // running in the background for some other reason, it 17173 // is more important to continue considering it to be 17174 // in the background state. 17175 mayBeTop = true; 17176 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17177 } else { 17178 // Special handling for above-top states (persistent 17179 // processes). These should not bring the current process 17180 // into the top state, since they are not on top. Instead 17181 // give them the best state after that. 17182 clientProcState = 17183 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17184 } 17185 } 17186 if (procState > clientProcState) { 17187 procState = clientProcState; 17188 } 17189 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17190 schedGroup = Process.THREAD_GROUP_DEFAULT; 17191 } 17192 } 17193 // If the provider has external (non-framework) process 17194 // dependencies, ensure that its adjustment is at least 17195 // FOREGROUND_APP_ADJ. 17196 if (cpr.hasExternalProcessHandles()) { 17197 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17198 adj = ProcessList.FOREGROUND_APP_ADJ; 17199 schedGroup = Process.THREAD_GROUP_DEFAULT; 17200 app.cached = false; 17201 app.adjType = "provider"; 17202 app.adjTarget = cpr.name; 17203 } 17204 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17205 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17206 } 17207 } 17208 } 17209 17210 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17211 // A client of one of our services or providers is in the top state. We 17212 // *may* want to be in the top state, but not if we are already running in 17213 // the background for some other reason. For the decision here, we are going 17214 // to pick out a few specific states that we want to remain in when a client 17215 // is top (states that tend to be longer-term) and otherwise allow it to go 17216 // to the top state. 17217 switch (procState) { 17218 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17219 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17220 case ActivityManager.PROCESS_STATE_SERVICE: 17221 // These all are longer-term states, so pull them up to the top 17222 // of the background states, but not all the way to the top state. 17223 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17224 break; 17225 default: 17226 // Otherwise, top is a better choice, so take it. 17227 procState = ActivityManager.PROCESS_STATE_TOP; 17228 break; 17229 } 17230 } 17231 17232 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17233 if (app.hasClientActivities) { 17234 // This is a cached process, but with client activities. Mark it so. 17235 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17236 app.adjType = "cch-client-act"; 17237 } else if (app.treatLikeActivity) { 17238 // This is a cached process, but somebody wants us to treat it like it has 17239 // an activity, okay! 17240 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17241 app.adjType = "cch-as-act"; 17242 } 17243 } 17244 17245 if (adj == ProcessList.SERVICE_ADJ) { 17246 if (doingAll) { 17247 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17248 mNewNumServiceProcs++; 17249 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17250 if (!app.serviceb) { 17251 // This service isn't far enough down on the LRU list to 17252 // normally be a B service, but if we are low on RAM and it 17253 // is large we want to force it down since we would prefer to 17254 // keep launcher over it. 17255 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17256 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17257 app.serviceHighRam = true; 17258 app.serviceb = true; 17259 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17260 } else { 17261 mNewNumAServiceProcs++; 17262 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17263 } 17264 } else { 17265 app.serviceHighRam = false; 17266 } 17267 } 17268 if (app.serviceb) { 17269 adj = ProcessList.SERVICE_B_ADJ; 17270 } 17271 } 17272 17273 app.curRawAdj = adj; 17274 17275 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17276 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17277 if (adj > app.maxAdj) { 17278 adj = app.maxAdj; 17279 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17280 schedGroup = Process.THREAD_GROUP_DEFAULT; 17281 } 17282 } 17283 17284 // Do final modification to adj. Everything we do between here and applying 17285 // the final setAdj must be done in this function, because we will also use 17286 // it when computing the final cached adj later. Note that we don't need to 17287 // worry about this for max adj above, since max adj will always be used to 17288 // keep it out of the cached vaues. 17289 app.curAdj = app.modifyRawOomAdj(adj); 17290 app.curSchedGroup = schedGroup; 17291 app.curProcState = procState; 17292 app.foregroundActivities = foregroundActivities; 17293 17294 return app.curRawAdj; 17295 } 17296 17297 /** 17298 * Schedule PSS collection of a process. 17299 */ 17300 void requestPssLocked(ProcessRecord proc, int procState) { 17301 if (mPendingPssProcesses.contains(proc)) { 17302 return; 17303 } 17304 if (mPendingPssProcesses.size() == 0) { 17305 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17306 } 17307 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17308 proc.pssProcState = procState; 17309 mPendingPssProcesses.add(proc); 17310 } 17311 17312 /** 17313 * Schedule PSS collection of all processes. 17314 */ 17315 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17316 if (!always) { 17317 if (now < (mLastFullPssTime + 17318 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17319 return; 17320 } 17321 } 17322 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17323 mLastFullPssTime = now; 17324 mFullPssPending = true; 17325 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17326 mPendingPssProcesses.clear(); 17327 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17328 ProcessRecord app = mLruProcesses.get(i); 17329 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17330 app.pssProcState = app.setProcState; 17331 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17332 isSleeping(), now); 17333 mPendingPssProcesses.add(app); 17334 } 17335 } 17336 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17337 } 17338 17339 /** 17340 * Ask a given process to GC right now. 17341 */ 17342 final void performAppGcLocked(ProcessRecord app) { 17343 try { 17344 app.lastRequestedGc = SystemClock.uptimeMillis(); 17345 if (app.thread != null) { 17346 if (app.reportLowMemory) { 17347 app.reportLowMemory = false; 17348 app.thread.scheduleLowMemory(); 17349 } else { 17350 app.thread.processInBackground(); 17351 } 17352 } 17353 } catch (Exception e) { 17354 // whatever. 17355 } 17356 } 17357 17358 /** 17359 * Returns true if things are idle enough to perform GCs. 17360 */ 17361 private final boolean canGcNowLocked() { 17362 boolean processingBroadcasts = false; 17363 for (BroadcastQueue q : mBroadcastQueues) { 17364 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17365 processingBroadcasts = true; 17366 } 17367 } 17368 return !processingBroadcasts 17369 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17370 } 17371 17372 /** 17373 * Perform GCs on all processes that are waiting for it, but only 17374 * if things are idle. 17375 */ 17376 final void performAppGcsLocked() { 17377 final int N = mProcessesToGc.size(); 17378 if (N <= 0) { 17379 return; 17380 } 17381 if (canGcNowLocked()) { 17382 while (mProcessesToGc.size() > 0) { 17383 ProcessRecord proc = mProcessesToGc.remove(0); 17384 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17385 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17386 <= SystemClock.uptimeMillis()) { 17387 // To avoid spamming the system, we will GC processes one 17388 // at a time, waiting a few seconds between each. 17389 performAppGcLocked(proc); 17390 scheduleAppGcsLocked(); 17391 return; 17392 } else { 17393 // It hasn't been long enough since we last GCed this 17394 // process... put it in the list to wait for its time. 17395 addProcessToGcListLocked(proc); 17396 break; 17397 } 17398 } 17399 } 17400 17401 scheduleAppGcsLocked(); 17402 } 17403 } 17404 17405 /** 17406 * If all looks good, perform GCs on all processes waiting for them. 17407 */ 17408 final void performAppGcsIfAppropriateLocked() { 17409 if (canGcNowLocked()) { 17410 performAppGcsLocked(); 17411 return; 17412 } 17413 // Still not idle, wait some more. 17414 scheduleAppGcsLocked(); 17415 } 17416 17417 /** 17418 * Schedule the execution of all pending app GCs. 17419 */ 17420 final void scheduleAppGcsLocked() { 17421 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17422 17423 if (mProcessesToGc.size() > 0) { 17424 // Schedule a GC for the time to the next process. 17425 ProcessRecord proc = mProcessesToGc.get(0); 17426 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17427 17428 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17429 long now = SystemClock.uptimeMillis(); 17430 if (when < (now+GC_TIMEOUT)) { 17431 when = now + GC_TIMEOUT; 17432 } 17433 mHandler.sendMessageAtTime(msg, when); 17434 } 17435 } 17436 17437 /** 17438 * Add a process to the array of processes waiting to be GCed. Keeps the 17439 * list in sorted order by the last GC time. The process can't already be 17440 * on the list. 17441 */ 17442 final void addProcessToGcListLocked(ProcessRecord proc) { 17443 boolean added = false; 17444 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17445 if (mProcessesToGc.get(i).lastRequestedGc < 17446 proc.lastRequestedGc) { 17447 added = true; 17448 mProcessesToGc.add(i+1, proc); 17449 break; 17450 } 17451 } 17452 if (!added) { 17453 mProcessesToGc.add(0, proc); 17454 } 17455 } 17456 17457 /** 17458 * Set up to ask a process to GC itself. This will either do it 17459 * immediately, or put it on the list of processes to gc the next 17460 * time things are idle. 17461 */ 17462 final void scheduleAppGcLocked(ProcessRecord app) { 17463 long now = SystemClock.uptimeMillis(); 17464 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17465 return; 17466 } 17467 if (!mProcessesToGc.contains(app)) { 17468 addProcessToGcListLocked(app); 17469 scheduleAppGcsLocked(); 17470 } 17471 } 17472 17473 final void checkExcessivePowerUsageLocked(boolean doKills) { 17474 updateCpuStatsNow(); 17475 17476 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17477 boolean doWakeKills = doKills; 17478 boolean doCpuKills = doKills; 17479 if (mLastPowerCheckRealtime == 0) { 17480 doWakeKills = false; 17481 } 17482 if (mLastPowerCheckUptime == 0) { 17483 doCpuKills = false; 17484 } 17485 if (stats.isScreenOn()) { 17486 doWakeKills = false; 17487 } 17488 final long curRealtime = SystemClock.elapsedRealtime(); 17489 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17490 final long curUptime = SystemClock.uptimeMillis(); 17491 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17492 mLastPowerCheckRealtime = curRealtime; 17493 mLastPowerCheckUptime = curUptime; 17494 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17495 doWakeKills = false; 17496 } 17497 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17498 doCpuKills = false; 17499 } 17500 int i = mLruProcesses.size(); 17501 while (i > 0) { 17502 i--; 17503 ProcessRecord app = mLruProcesses.get(i); 17504 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17505 long wtime; 17506 synchronized (stats) { 17507 wtime = stats.getProcessWakeTime(app.info.uid, 17508 app.pid, curRealtime); 17509 } 17510 long wtimeUsed = wtime - app.lastWakeTime; 17511 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17512 if (DEBUG_POWER) { 17513 StringBuilder sb = new StringBuilder(128); 17514 sb.append("Wake for "); 17515 app.toShortString(sb); 17516 sb.append(": over "); 17517 TimeUtils.formatDuration(realtimeSince, sb); 17518 sb.append(" used "); 17519 TimeUtils.formatDuration(wtimeUsed, sb); 17520 sb.append(" ("); 17521 sb.append((wtimeUsed*100)/realtimeSince); 17522 sb.append("%)"); 17523 Slog.i(TAG, sb.toString()); 17524 sb.setLength(0); 17525 sb.append("CPU for "); 17526 app.toShortString(sb); 17527 sb.append(": over "); 17528 TimeUtils.formatDuration(uptimeSince, sb); 17529 sb.append(" used "); 17530 TimeUtils.formatDuration(cputimeUsed, sb); 17531 sb.append(" ("); 17532 sb.append((cputimeUsed*100)/uptimeSince); 17533 sb.append("%)"); 17534 Slog.i(TAG, sb.toString()); 17535 } 17536 // If a process has held a wake lock for more 17537 // than 50% of the time during this period, 17538 // that sounds bad. Kill! 17539 if (doWakeKills && realtimeSince > 0 17540 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17541 synchronized (stats) { 17542 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17543 realtimeSince, wtimeUsed); 17544 } 17545 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17546 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17547 } else if (doCpuKills && uptimeSince > 0 17548 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17549 synchronized (stats) { 17550 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17551 uptimeSince, cputimeUsed); 17552 } 17553 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17554 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17555 } else { 17556 app.lastWakeTime = wtime; 17557 app.lastCpuTime = app.curCpuTime; 17558 } 17559 } 17560 } 17561 } 17562 17563 private final boolean applyOomAdjLocked(ProcessRecord app, 17564 ProcessRecord TOP_APP, boolean doingAll, long now) { 17565 boolean success = true; 17566 17567 if (app.curRawAdj != app.setRawAdj) { 17568 app.setRawAdj = app.curRawAdj; 17569 } 17570 17571 int changes = 0; 17572 17573 if (app.curAdj != app.setAdj) { 17574 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17575 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17576 TAG, "Set " + app.pid + " " + app.processName + 17577 " adj " + app.curAdj + ": " + app.adjType); 17578 app.setAdj = app.curAdj; 17579 } 17580 17581 if (app.setSchedGroup != app.curSchedGroup) { 17582 app.setSchedGroup = app.curSchedGroup; 17583 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17584 "Setting process group of " + app.processName 17585 + " to " + app.curSchedGroup); 17586 if (app.waitingToKill != null && 17587 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17588 app.kill(app.waitingToKill, true); 17589 success = false; 17590 } else { 17591 if (true) { 17592 long oldId = Binder.clearCallingIdentity(); 17593 try { 17594 Process.setProcessGroup(app.pid, app.curSchedGroup); 17595 } catch (Exception e) { 17596 Slog.w(TAG, "Failed setting process group of " + app.pid 17597 + " to " + app.curSchedGroup); 17598 e.printStackTrace(); 17599 } finally { 17600 Binder.restoreCallingIdentity(oldId); 17601 } 17602 } else { 17603 if (app.thread != null) { 17604 try { 17605 app.thread.setSchedulingGroup(app.curSchedGroup); 17606 } catch (RemoteException e) { 17607 } 17608 } 17609 } 17610 Process.setSwappiness(app.pid, 17611 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17612 } 17613 } 17614 if (app.repForegroundActivities != app.foregroundActivities) { 17615 app.repForegroundActivities = app.foregroundActivities; 17616 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17617 } 17618 if (app.repProcState != app.curProcState) { 17619 app.repProcState = app.curProcState; 17620 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17621 if (app.thread != null) { 17622 try { 17623 if (false) { 17624 //RuntimeException h = new RuntimeException("here"); 17625 Slog.i(TAG, "Sending new process state " + app.repProcState 17626 + " to " + app /*, h*/); 17627 } 17628 app.thread.setProcessState(app.repProcState); 17629 } catch (RemoteException e) { 17630 } 17631 } 17632 } 17633 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17634 app.setProcState)) { 17635 app.lastStateTime = now; 17636 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17637 isSleeping(), now); 17638 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17639 + ProcessList.makeProcStateString(app.setProcState) + " to " 17640 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17641 + (app.nextPssTime-now) + ": " + app); 17642 } else { 17643 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17644 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17645 requestPssLocked(app, app.setProcState); 17646 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17647 isSleeping(), now); 17648 } else if (false && DEBUG_PSS) { 17649 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17650 } 17651 } 17652 if (app.setProcState != app.curProcState) { 17653 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17654 "Proc state change of " + app.processName 17655 + " to " + app.curProcState); 17656 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17657 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17658 if (setImportant && !curImportant) { 17659 // This app is no longer something we consider important enough to allow to 17660 // use arbitrary amounts of battery power. Note 17661 // its current wake lock time to later know to kill it if 17662 // it is not behaving well. 17663 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17664 synchronized (stats) { 17665 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17666 app.pid, SystemClock.elapsedRealtime()); 17667 } 17668 app.lastCpuTime = app.curCpuTime; 17669 17670 } 17671 app.setProcState = app.curProcState; 17672 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17673 app.notCachedSinceIdle = false; 17674 } 17675 if (!doingAll) { 17676 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17677 } else { 17678 app.procStateChanged = true; 17679 } 17680 } 17681 17682 if (changes != 0) { 17683 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17684 int i = mPendingProcessChanges.size()-1; 17685 ProcessChangeItem item = null; 17686 while (i >= 0) { 17687 item = mPendingProcessChanges.get(i); 17688 if (item.pid == app.pid) { 17689 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17690 break; 17691 } 17692 i--; 17693 } 17694 if (i < 0) { 17695 // No existing item in pending changes; need a new one. 17696 final int NA = mAvailProcessChanges.size(); 17697 if (NA > 0) { 17698 item = mAvailProcessChanges.remove(NA-1); 17699 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17700 } else { 17701 item = new ProcessChangeItem(); 17702 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17703 } 17704 item.changes = 0; 17705 item.pid = app.pid; 17706 item.uid = app.info.uid; 17707 if (mPendingProcessChanges.size() == 0) { 17708 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17709 "*** Enqueueing dispatch processes changed!"); 17710 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17711 } 17712 mPendingProcessChanges.add(item); 17713 } 17714 item.changes |= changes; 17715 item.processState = app.repProcState; 17716 item.foregroundActivities = app.repForegroundActivities; 17717 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17718 + Integer.toHexString(System.identityHashCode(item)) 17719 + " " + app.toShortString() + ": changes=" + item.changes 17720 + " procState=" + item.processState 17721 + " foreground=" + item.foregroundActivities 17722 + " type=" + app.adjType + " source=" + app.adjSource 17723 + " target=" + app.adjTarget); 17724 } 17725 17726 return success; 17727 } 17728 17729 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17730 if (proc.thread != null) { 17731 if (proc.baseProcessTracker != null) { 17732 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17733 } 17734 if (proc.repProcState >= 0) { 17735 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17736 proc.repProcState); 17737 } 17738 } 17739 } 17740 17741 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17742 ProcessRecord TOP_APP, boolean doingAll, long now) { 17743 if (app.thread == null) { 17744 return false; 17745 } 17746 17747 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17748 17749 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17750 } 17751 17752 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17753 boolean oomAdj) { 17754 if (isForeground != proc.foregroundServices) { 17755 proc.foregroundServices = isForeground; 17756 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17757 proc.info.uid); 17758 if (isForeground) { 17759 if (curProcs == null) { 17760 curProcs = new ArrayList<ProcessRecord>(); 17761 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17762 } 17763 if (!curProcs.contains(proc)) { 17764 curProcs.add(proc); 17765 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17766 proc.info.packageName, proc.info.uid); 17767 } 17768 } else { 17769 if (curProcs != null) { 17770 if (curProcs.remove(proc)) { 17771 mBatteryStatsService.noteEvent( 17772 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17773 proc.info.packageName, proc.info.uid); 17774 if (curProcs.size() <= 0) { 17775 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17776 } 17777 } 17778 } 17779 } 17780 if (oomAdj) { 17781 updateOomAdjLocked(); 17782 } 17783 } 17784 } 17785 17786 private final ActivityRecord resumedAppLocked() { 17787 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17788 String pkg; 17789 int uid; 17790 if (act != null) { 17791 pkg = act.packageName; 17792 uid = act.info.applicationInfo.uid; 17793 } else { 17794 pkg = null; 17795 uid = -1; 17796 } 17797 // Has the UID or resumed package name changed? 17798 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17799 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17800 if (mCurResumedPackage != null) { 17801 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17802 mCurResumedPackage, mCurResumedUid); 17803 } 17804 mCurResumedPackage = pkg; 17805 mCurResumedUid = uid; 17806 if (mCurResumedPackage != null) { 17807 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17808 mCurResumedPackage, mCurResumedUid); 17809 } 17810 } 17811 return act; 17812 } 17813 17814 final boolean updateOomAdjLocked(ProcessRecord app) { 17815 final ActivityRecord TOP_ACT = resumedAppLocked(); 17816 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17817 final boolean wasCached = app.cached; 17818 17819 mAdjSeq++; 17820 17821 // This is the desired cached adjusment we want to tell it to use. 17822 // If our app is currently cached, we know it, and that is it. Otherwise, 17823 // we don't know it yet, and it needs to now be cached we will then 17824 // need to do a complete oom adj. 17825 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17826 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17827 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17828 SystemClock.uptimeMillis()); 17829 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17830 // Changed to/from cached state, so apps after it in the LRU 17831 // list may also be changed. 17832 updateOomAdjLocked(); 17833 } 17834 return success; 17835 } 17836 17837 final void updateOomAdjLocked() { 17838 final ActivityRecord TOP_ACT = resumedAppLocked(); 17839 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17840 final long now = SystemClock.uptimeMillis(); 17841 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17842 final int N = mLruProcesses.size(); 17843 17844 if (false) { 17845 RuntimeException e = new RuntimeException(); 17846 e.fillInStackTrace(); 17847 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17848 } 17849 17850 mAdjSeq++; 17851 mNewNumServiceProcs = 0; 17852 mNewNumAServiceProcs = 0; 17853 17854 final int emptyProcessLimit; 17855 final int cachedProcessLimit; 17856 if (mProcessLimit <= 0) { 17857 emptyProcessLimit = cachedProcessLimit = 0; 17858 } else if (mProcessLimit == 1) { 17859 emptyProcessLimit = 1; 17860 cachedProcessLimit = 0; 17861 } else { 17862 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17863 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17864 } 17865 17866 // Let's determine how many processes we have running vs. 17867 // how many slots we have for background processes; we may want 17868 // to put multiple processes in a slot of there are enough of 17869 // them. 17870 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17871 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17872 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17873 if (numEmptyProcs > cachedProcessLimit) { 17874 // If there are more empty processes than our limit on cached 17875 // processes, then use the cached process limit for the factor. 17876 // This ensures that the really old empty processes get pushed 17877 // down to the bottom, so if we are running low on memory we will 17878 // have a better chance at keeping around more cached processes 17879 // instead of a gazillion empty processes. 17880 numEmptyProcs = cachedProcessLimit; 17881 } 17882 int emptyFactor = numEmptyProcs/numSlots; 17883 if (emptyFactor < 1) emptyFactor = 1; 17884 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17885 if (cachedFactor < 1) cachedFactor = 1; 17886 int stepCached = 0; 17887 int stepEmpty = 0; 17888 int numCached = 0; 17889 int numEmpty = 0; 17890 int numTrimming = 0; 17891 17892 mNumNonCachedProcs = 0; 17893 mNumCachedHiddenProcs = 0; 17894 17895 // First update the OOM adjustment for each of the 17896 // application processes based on their current state. 17897 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17898 int nextCachedAdj = curCachedAdj+1; 17899 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17900 int nextEmptyAdj = curEmptyAdj+2; 17901 for (int i=N-1; i>=0; i--) { 17902 ProcessRecord app = mLruProcesses.get(i); 17903 if (!app.killedByAm && app.thread != null) { 17904 app.procStateChanged = false; 17905 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17906 17907 // If we haven't yet assigned the final cached adj 17908 // to the process, do that now. 17909 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17910 switch (app.curProcState) { 17911 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17912 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17913 // This process is a cached process holding activities... 17914 // assign it the next cached value for that type, and then 17915 // step that cached level. 17916 app.curRawAdj = curCachedAdj; 17917 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17918 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17919 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17920 + ")"); 17921 if (curCachedAdj != nextCachedAdj) { 17922 stepCached++; 17923 if (stepCached >= cachedFactor) { 17924 stepCached = 0; 17925 curCachedAdj = nextCachedAdj; 17926 nextCachedAdj += 2; 17927 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17928 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17929 } 17930 } 17931 } 17932 break; 17933 default: 17934 // For everything else, assign next empty cached process 17935 // level and bump that up. Note that this means that 17936 // long-running services that have dropped down to the 17937 // cached level will be treated as empty (since their process 17938 // state is still as a service), which is what we want. 17939 app.curRawAdj = curEmptyAdj; 17940 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17941 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17942 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17943 + ")"); 17944 if (curEmptyAdj != nextEmptyAdj) { 17945 stepEmpty++; 17946 if (stepEmpty >= emptyFactor) { 17947 stepEmpty = 0; 17948 curEmptyAdj = nextEmptyAdj; 17949 nextEmptyAdj += 2; 17950 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17951 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17952 } 17953 } 17954 } 17955 break; 17956 } 17957 } 17958 17959 applyOomAdjLocked(app, TOP_APP, true, now); 17960 17961 // Count the number of process types. 17962 switch (app.curProcState) { 17963 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17964 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17965 mNumCachedHiddenProcs++; 17966 numCached++; 17967 if (numCached > cachedProcessLimit) { 17968 app.kill("cached #" + numCached, true); 17969 } 17970 break; 17971 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17972 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17973 && app.lastActivityTime < oldTime) { 17974 app.kill("empty for " 17975 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17976 / 1000) + "s", true); 17977 } else { 17978 numEmpty++; 17979 if (numEmpty > emptyProcessLimit) { 17980 app.kill("empty #" + numEmpty, true); 17981 } 17982 } 17983 break; 17984 default: 17985 mNumNonCachedProcs++; 17986 break; 17987 } 17988 17989 if (app.isolated && app.services.size() <= 0) { 17990 // If this is an isolated process, and there are no 17991 // services running in it, then the process is no longer 17992 // needed. We agressively kill these because we can by 17993 // definition not re-use the same process again, and it is 17994 // good to avoid having whatever code was running in them 17995 // left sitting around after no longer needed. 17996 app.kill("isolated not needed", true); 17997 } 17998 17999 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18000 && !app.killedByAm) { 18001 numTrimming++; 18002 } 18003 } 18004 } 18005 18006 mNumServiceProcs = mNewNumServiceProcs; 18007 18008 // Now determine the memory trimming level of background processes. 18009 // Unfortunately we need to start at the back of the list to do this 18010 // properly. We only do this if the number of background apps we 18011 // are managing to keep around is less than half the maximum we desire; 18012 // if we are keeping a good number around, we'll let them use whatever 18013 // memory they want. 18014 final int numCachedAndEmpty = numCached + numEmpty; 18015 int memFactor; 18016 if (numCached <= ProcessList.TRIM_CACHED_APPS 18017 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18018 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18019 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18020 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18021 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18022 } else { 18023 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18024 } 18025 } else { 18026 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18027 } 18028 // We always allow the memory level to go up (better). We only allow it to go 18029 // down if we are in a state where that is allowed, *and* the total number of processes 18030 // has gone down since last time. 18031 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18032 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18033 + " last=" + mLastNumProcesses); 18034 if (memFactor > mLastMemoryLevel) { 18035 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18036 memFactor = mLastMemoryLevel; 18037 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18038 } 18039 } 18040 mLastMemoryLevel = memFactor; 18041 mLastNumProcesses = mLruProcesses.size(); 18042 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18043 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18044 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18045 if (mLowRamStartTime == 0) { 18046 mLowRamStartTime = now; 18047 } 18048 int step = 0; 18049 int fgTrimLevel; 18050 switch (memFactor) { 18051 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18052 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18053 break; 18054 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18055 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18056 break; 18057 default: 18058 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18059 break; 18060 } 18061 int factor = numTrimming/3; 18062 int minFactor = 2; 18063 if (mHomeProcess != null) minFactor++; 18064 if (mPreviousProcess != null) minFactor++; 18065 if (factor < minFactor) factor = minFactor; 18066 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18067 for (int i=N-1; i>=0; i--) { 18068 ProcessRecord app = mLruProcesses.get(i); 18069 if (allChanged || app.procStateChanged) { 18070 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18071 app.procStateChanged = false; 18072 } 18073 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18074 && !app.killedByAm) { 18075 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18076 try { 18077 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18078 "Trimming memory of " + app.processName 18079 + " to " + curLevel); 18080 app.thread.scheduleTrimMemory(curLevel); 18081 } catch (RemoteException e) { 18082 } 18083 if (false) { 18084 // For now we won't do this; our memory trimming seems 18085 // to be good enough at this point that destroying 18086 // activities causes more harm than good. 18087 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18088 && app != mHomeProcess && app != mPreviousProcess) { 18089 // Need to do this on its own message because the stack may not 18090 // be in a consistent state at this point. 18091 // For these apps we will also finish their activities 18092 // to help them free memory. 18093 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18094 } 18095 } 18096 } 18097 app.trimMemoryLevel = curLevel; 18098 step++; 18099 if (step >= factor) { 18100 step = 0; 18101 switch (curLevel) { 18102 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18103 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18104 break; 18105 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18106 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18107 break; 18108 } 18109 } 18110 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18111 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18112 && app.thread != null) { 18113 try { 18114 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18115 "Trimming memory of heavy-weight " + app.processName 18116 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18117 app.thread.scheduleTrimMemory( 18118 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18119 } catch (RemoteException e) { 18120 } 18121 } 18122 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18123 } else { 18124 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18125 || app.systemNoUi) && app.pendingUiClean) { 18126 // If this application is now in the background and it 18127 // had done UI, then give it the special trim level to 18128 // have it free UI resources. 18129 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18130 if (app.trimMemoryLevel < level && app.thread != null) { 18131 try { 18132 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18133 "Trimming memory of bg-ui " + app.processName 18134 + " to " + level); 18135 app.thread.scheduleTrimMemory(level); 18136 } catch (RemoteException e) { 18137 } 18138 } 18139 app.pendingUiClean = false; 18140 } 18141 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18142 try { 18143 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18144 "Trimming memory of fg " + app.processName 18145 + " to " + fgTrimLevel); 18146 app.thread.scheduleTrimMemory(fgTrimLevel); 18147 } catch (RemoteException e) { 18148 } 18149 } 18150 app.trimMemoryLevel = fgTrimLevel; 18151 } 18152 } 18153 } else { 18154 if (mLowRamStartTime != 0) { 18155 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18156 mLowRamStartTime = 0; 18157 } 18158 for (int i=N-1; i>=0; i--) { 18159 ProcessRecord app = mLruProcesses.get(i); 18160 if (allChanged || app.procStateChanged) { 18161 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18162 app.procStateChanged = false; 18163 } 18164 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18165 || app.systemNoUi) && app.pendingUiClean) { 18166 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18167 && app.thread != null) { 18168 try { 18169 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18170 "Trimming memory of ui hidden " + app.processName 18171 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18172 app.thread.scheduleTrimMemory( 18173 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18174 } catch (RemoteException e) { 18175 } 18176 } 18177 app.pendingUiClean = false; 18178 } 18179 app.trimMemoryLevel = 0; 18180 } 18181 } 18182 18183 if (mAlwaysFinishActivities) { 18184 // Need to do this on its own message because the stack may not 18185 // be in a consistent state at this point. 18186 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18187 } 18188 18189 if (allChanged) { 18190 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18191 } 18192 18193 if (mProcessStats.shouldWriteNowLocked(now)) { 18194 mHandler.post(new Runnable() { 18195 @Override public void run() { 18196 synchronized (ActivityManagerService.this) { 18197 mProcessStats.writeStateAsyncLocked(); 18198 } 18199 } 18200 }); 18201 } 18202 18203 if (DEBUG_OOM_ADJ) { 18204 if (false) { 18205 RuntimeException here = new RuntimeException("here"); 18206 here.fillInStackTrace(); 18207 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18208 } else { 18209 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18210 } 18211 } 18212 } 18213 18214 final void trimApplications() { 18215 synchronized (this) { 18216 int i; 18217 18218 // First remove any unused application processes whose package 18219 // has been removed. 18220 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18221 final ProcessRecord app = mRemovedProcesses.get(i); 18222 if (app.activities.size() == 0 18223 && app.curReceiver == null && app.services.size() == 0) { 18224 Slog.i( 18225 TAG, "Exiting empty application process " 18226 + app.processName + " (" 18227 + (app.thread != null ? app.thread.asBinder() : null) 18228 + ")\n"); 18229 if (app.pid > 0 && app.pid != MY_PID) { 18230 app.kill("empty", false); 18231 } else { 18232 try { 18233 app.thread.scheduleExit(); 18234 } catch (Exception e) { 18235 // Ignore exceptions. 18236 } 18237 } 18238 cleanUpApplicationRecordLocked(app, false, true, -1); 18239 mRemovedProcesses.remove(i); 18240 18241 if (app.persistent) { 18242 addAppLocked(app.info, false, null /* ABI override */); 18243 } 18244 } 18245 } 18246 18247 // Now update the oom adj for all processes. 18248 updateOomAdjLocked(); 18249 } 18250 } 18251 18252 /** This method sends the specified signal to each of the persistent apps */ 18253 public void signalPersistentProcesses(int sig) throws RemoteException { 18254 if (sig != Process.SIGNAL_USR1) { 18255 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18256 } 18257 18258 synchronized (this) { 18259 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18260 != PackageManager.PERMISSION_GRANTED) { 18261 throw new SecurityException("Requires permission " 18262 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18263 } 18264 18265 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18266 ProcessRecord r = mLruProcesses.get(i); 18267 if (r.thread != null && r.persistent) { 18268 Process.sendSignal(r.pid, sig); 18269 } 18270 } 18271 } 18272 } 18273 18274 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18275 if (proc == null || proc == mProfileProc) { 18276 proc = mProfileProc; 18277 profileType = mProfileType; 18278 clearProfilerLocked(); 18279 } 18280 if (proc == null) { 18281 return; 18282 } 18283 try { 18284 proc.thread.profilerControl(false, null, profileType); 18285 } catch (RemoteException e) { 18286 throw new IllegalStateException("Process disappeared"); 18287 } 18288 } 18289 18290 private void clearProfilerLocked() { 18291 if (mProfileFd != null) { 18292 try { 18293 mProfileFd.close(); 18294 } catch (IOException e) { 18295 } 18296 } 18297 mProfileApp = null; 18298 mProfileProc = null; 18299 mProfileFile = null; 18300 mProfileType = 0; 18301 mAutoStopProfiler = false; 18302 mSamplingInterval = 0; 18303 } 18304 18305 public boolean profileControl(String process, int userId, boolean start, 18306 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18307 18308 try { 18309 synchronized (this) { 18310 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18311 // its own permission. 18312 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18313 != PackageManager.PERMISSION_GRANTED) { 18314 throw new SecurityException("Requires permission " 18315 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18316 } 18317 18318 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18319 throw new IllegalArgumentException("null profile info or fd"); 18320 } 18321 18322 ProcessRecord proc = null; 18323 if (process != null) { 18324 proc = findProcessLocked(process, userId, "profileControl"); 18325 } 18326 18327 if (start && (proc == null || proc.thread == null)) { 18328 throw new IllegalArgumentException("Unknown process: " + process); 18329 } 18330 18331 if (start) { 18332 stopProfilerLocked(null, 0); 18333 setProfileApp(proc.info, proc.processName, profilerInfo); 18334 mProfileProc = proc; 18335 mProfileType = profileType; 18336 ParcelFileDescriptor fd = profilerInfo.profileFd; 18337 try { 18338 fd = fd.dup(); 18339 } catch (IOException e) { 18340 fd = null; 18341 } 18342 profilerInfo.profileFd = fd; 18343 proc.thread.profilerControl(start, profilerInfo, profileType); 18344 fd = null; 18345 mProfileFd = null; 18346 } else { 18347 stopProfilerLocked(proc, profileType); 18348 if (profilerInfo != null && profilerInfo.profileFd != null) { 18349 try { 18350 profilerInfo.profileFd.close(); 18351 } catch (IOException e) { 18352 } 18353 } 18354 } 18355 18356 return true; 18357 } 18358 } catch (RemoteException e) { 18359 throw new IllegalStateException("Process disappeared"); 18360 } finally { 18361 if (profilerInfo != null && profilerInfo.profileFd != null) { 18362 try { 18363 profilerInfo.profileFd.close(); 18364 } catch (IOException e) { 18365 } 18366 } 18367 } 18368 } 18369 18370 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18371 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18372 userId, true, ALLOW_FULL_ONLY, callName, null); 18373 ProcessRecord proc = null; 18374 try { 18375 int pid = Integer.parseInt(process); 18376 synchronized (mPidsSelfLocked) { 18377 proc = mPidsSelfLocked.get(pid); 18378 } 18379 } catch (NumberFormatException e) { 18380 } 18381 18382 if (proc == null) { 18383 ArrayMap<String, SparseArray<ProcessRecord>> all 18384 = mProcessNames.getMap(); 18385 SparseArray<ProcessRecord> procs = all.get(process); 18386 if (procs != null && procs.size() > 0) { 18387 proc = procs.valueAt(0); 18388 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18389 for (int i=1; i<procs.size(); i++) { 18390 ProcessRecord thisProc = procs.valueAt(i); 18391 if (thisProc.userId == userId) { 18392 proc = thisProc; 18393 break; 18394 } 18395 } 18396 } 18397 } 18398 } 18399 18400 return proc; 18401 } 18402 18403 public boolean dumpHeap(String process, int userId, boolean managed, 18404 String path, ParcelFileDescriptor fd) throws RemoteException { 18405 18406 try { 18407 synchronized (this) { 18408 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18409 // its own permission (same as profileControl). 18410 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18411 != PackageManager.PERMISSION_GRANTED) { 18412 throw new SecurityException("Requires permission " 18413 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18414 } 18415 18416 if (fd == null) { 18417 throw new IllegalArgumentException("null fd"); 18418 } 18419 18420 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18421 if (proc == null || proc.thread == null) { 18422 throw new IllegalArgumentException("Unknown process: " + process); 18423 } 18424 18425 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18426 if (!isDebuggable) { 18427 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18428 throw new SecurityException("Process not debuggable: " + proc); 18429 } 18430 } 18431 18432 proc.thread.dumpHeap(managed, path, fd); 18433 fd = null; 18434 return true; 18435 } 18436 } catch (RemoteException e) { 18437 throw new IllegalStateException("Process disappeared"); 18438 } finally { 18439 if (fd != null) { 18440 try { 18441 fd.close(); 18442 } catch (IOException e) { 18443 } 18444 } 18445 } 18446 } 18447 18448 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18449 public void monitor() { 18450 synchronized (this) { } 18451 } 18452 18453 void onCoreSettingsChange(Bundle settings) { 18454 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18455 ProcessRecord processRecord = mLruProcesses.get(i); 18456 try { 18457 if (processRecord.thread != null) { 18458 processRecord.thread.setCoreSettings(settings); 18459 } 18460 } catch (RemoteException re) { 18461 /* ignore */ 18462 } 18463 } 18464 } 18465 18466 // Multi-user methods 18467 18468 /** 18469 * Start user, if its not already running, but don't bring it to foreground. 18470 */ 18471 @Override 18472 public boolean startUserInBackground(final int userId) { 18473 return startUser(userId, /* foreground */ false); 18474 } 18475 18476 /** 18477 * Start user, if its not already running, and bring it to foreground. 18478 */ 18479 boolean startUserInForeground(final int userId, Dialog dlg) { 18480 boolean result = startUser(userId, /* foreground */ true); 18481 dlg.dismiss(); 18482 return result; 18483 } 18484 18485 /** 18486 * Refreshes the list of users related to the current user when either a 18487 * user switch happens or when a new related user is started in the 18488 * background. 18489 */ 18490 private void updateCurrentProfileIdsLocked() { 18491 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18492 mCurrentUserId, false /* enabledOnly */); 18493 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18494 for (int i = 0; i < currentProfileIds.length; i++) { 18495 currentProfileIds[i] = profiles.get(i).id; 18496 } 18497 mCurrentProfileIds = currentProfileIds; 18498 18499 synchronized (mUserProfileGroupIdsSelfLocked) { 18500 mUserProfileGroupIdsSelfLocked.clear(); 18501 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18502 for (int i = 0; i < users.size(); i++) { 18503 UserInfo user = users.get(i); 18504 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18505 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18506 } 18507 } 18508 } 18509 } 18510 18511 private Set getProfileIdsLocked(int userId) { 18512 Set userIds = new HashSet<Integer>(); 18513 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18514 userId, false /* enabledOnly */); 18515 for (UserInfo user : profiles) { 18516 userIds.add(Integer.valueOf(user.id)); 18517 } 18518 return userIds; 18519 } 18520 18521 @Override 18522 public boolean switchUser(final int userId) { 18523 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18524 String userName; 18525 synchronized (this) { 18526 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18527 if (userInfo == null) { 18528 Slog.w(TAG, "No user info for user #" + userId); 18529 return false; 18530 } 18531 if (userInfo.isManagedProfile()) { 18532 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18533 return false; 18534 } 18535 userName = userInfo.name; 18536 mTargetUserId = userId; 18537 } 18538 mHandler.removeMessages(START_USER_SWITCH_MSG); 18539 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18540 return true; 18541 } 18542 18543 private void showUserSwitchDialog(int userId, String userName) { 18544 // The dialog will show and then initiate the user switch by calling startUserInForeground 18545 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18546 true /* above system */); 18547 d.show(); 18548 } 18549 18550 private boolean startUser(final int userId, final boolean foreground) { 18551 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18552 != PackageManager.PERMISSION_GRANTED) { 18553 String msg = "Permission Denial: switchUser() from pid=" 18554 + Binder.getCallingPid() 18555 + ", uid=" + Binder.getCallingUid() 18556 + " requires " + INTERACT_ACROSS_USERS_FULL; 18557 Slog.w(TAG, msg); 18558 throw new SecurityException(msg); 18559 } 18560 18561 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18562 18563 final long ident = Binder.clearCallingIdentity(); 18564 try { 18565 synchronized (this) { 18566 final int oldUserId = mCurrentUserId; 18567 if (oldUserId == userId) { 18568 return true; 18569 } 18570 18571 mStackSupervisor.setLockTaskModeLocked(null, false); 18572 18573 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18574 if (userInfo == null) { 18575 Slog.w(TAG, "No user info for user #" + userId); 18576 return false; 18577 } 18578 if (foreground && userInfo.isManagedProfile()) { 18579 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18580 return false; 18581 } 18582 18583 if (foreground) { 18584 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18585 R.anim.screen_user_enter); 18586 } 18587 18588 boolean needStart = false; 18589 18590 // If the user we are switching to is not currently started, then 18591 // we need to start it now. 18592 if (mStartedUsers.get(userId) == null) { 18593 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18594 updateStartedUserArrayLocked(); 18595 needStart = true; 18596 } 18597 18598 final Integer userIdInt = Integer.valueOf(userId); 18599 mUserLru.remove(userIdInt); 18600 mUserLru.add(userIdInt); 18601 18602 if (foreground) { 18603 mCurrentUserId = userId; 18604 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18605 updateCurrentProfileIdsLocked(); 18606 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18607 // Once the internal notion of the active user has switched, we lock the device 18608 // with the option to show the user switcher on the keyguard. 18609 mWindowManager.lockNow(null); 18610 } else { 18611 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18612 updateCurrentProfileIdsLocked(); 18613 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18614 mUserLru.remove(currentUserIdInt); 18615 mUserLru.add(currentUserIdInt); 18616 } 18617 18618 final UserStartedState uss = mStartedUsers.get(userId); 18619 18620 // Make sure user is in the started state. If it is currently 18621 // stopping, we need to knock that off. 18622 if (uss.mState == UserStartedState.STATE_STOPPING) { 18623 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18624 // so we can just fairly silently bring the user back from 18625 // the almost-dead. 18626 uss.mState = UserStartedState.STATE_RUNNING; 18627 updateStartedUserArrayLocked(); 18628 needStart = true; 18629 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18630 // This means ACTION_SHUTDOWN has been sent, so we will 18631 // need to treat this as a new boot of the user. 18632 uss.mState = UserStartedState.STATE_BOOTING; 18633 updateStartedUserArrayLocked(); 18634 needStart = true; 18635 } 18636 18637 if (uss.mState == UserStartedState.STATE_BOOTING) { 18638 // Booting up a new user, need to tell system services about it. 18639 // Note that this is on the same handler as scheduling of broadcasts, 18640 // which is important because it needs to go first. 18641 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18642 } 18643 18644 if (foreground) { 18645 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18646 oldUserId)); 18647 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18648 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18649 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18650 oldUserId, userId, uss)); 18651 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18652 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18653 } 18654 18655 if (needStart) { 18656 // Send USER_STARTED broadcast 18657 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18658 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18659 | Intent.FLAG_RECEIVER_FOREGROUND); 18660 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18661 broadcastIntentLocked(null, null, intent, 18662 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18663 false, false, MY_PID, Process.SYSTEM_UID, userId); 18664 } 18665 18666 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18667 if (userId != UserHandle.USER_OWNER) { 18668 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18669 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18670 broadcastIntentLocked(null, null, intent, null, 18671 new IIntentReceiver.Stub() { 18672 public void performReceive(Intent intent, int resultCode, 18673 String data, Bundle extras, boolean ordered, 18674 boolean sticky, int sendingUser) { 18675 onUserInitialized(uss, foreground, oldUserId, userId); 18676 } 18677 }, 0, null, null, null, AppOpsManager.OP_NONE, 18678 true, false, MY_PID, Process.SYSTEM_UID, 18679 userId); 18680 uss.initializing = true; 18681 } else { 18682 getUserManagerLocked().makeInitialized(userInfo.id); 18683 } 18684 } 18685 18686 if (foreground) { 18687 if (!uss.initializing) { 18688 moveUserToForeground(uss, oldUserId, userId); 18689 } 18690 } else { 18691 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18692 } 18693 18694 if (needStart) { 18695 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18696 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18697 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18698 broadcastIntentLocked(null, null, intent, 18699 null, new IIntentReceiver.Stub() { 18700 @Override 18701 public void performReceive(Intent intent, int resultCode, String data, 18702 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18703 throws RemoteException { 18704 } 18705 }, 0, null, null, 18706 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18707 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18708 } 18709 } 18710 } finally { 18711 Binder.restoreCallingIdentity(ident); 18712 } 18713 18714 return true; 18715 } 18716 18717 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18718 long ident = Binder.clearCallingIdentity(); 18719 try { 18720 Intent intent; 18721 if (oldUserId >= 0) { 18722 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18723 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18724 int count = profiles.size(); 18725 for (int i = 0; i < count; i++) { 18726 int profileUserId = profiles.get(i).id; 18727 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18728 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18729 | Intent.FLAG_RECEIVER_FOREGROUND); 18730 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18731 broadcastIntentLocked(null, null, intent, 18732 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18733 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18734 } 18735 } 18736 if (newUserId >= 0) { 18737 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18738 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18739 int count = profiles.size(); 18740 for (int i = 0; i < count; i++) { 18741 int profileUserId = profiles.get(i).id; 18742 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18743 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18744 | Intent.FLAG_RECEIVER_FOREGROUND); 18745 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18746 broadcastIntentLocked(null, null, intent, 18747 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18748 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18749 } 18750 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18751 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18752 | Intent.FLAG_RECEIVER_FOREGROUND); 18753 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18754 broadcastIntentLocked(null, null, intent, 18755 null, null, 0, null, null, 18756 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18757 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18758 } 18759 } finally { 18760 Binder.restoreCallingIdentity(ident); 18761 } 18762 } 18763 18764 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18765 final int newUserId) { 18766 final int N = mUserSwitchObservers.beginBroadcast(); 18767 if (N > 0) { 18768 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18769 int mCount = 0; 18770 @Override 18771 public void sendResult(Bundle data) throws RemoteException { 18772 synchronized (ActivityManagerService.this) { 18773 if (mCurUserSwitchCallback == this) { 18774 mCount++; 18775 if (mCount == N) { 18776 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18777 } 18778 } 18779 } 18780 } 18781 }; 18782 synchronized (this) { 18783 uss.switching = true; 18784 mCurUserSwitchCallback = callback; 18785 } 18786 for (int i=0; i<N; i++) { 18787 try { 18788 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18789 newUserId, callback); 18790 } catch (RemoteException e) { 18791 } 18792 } 18793 } else { 18794 synchronized (this) { 18795 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18796 } 18797 } 18798 mUserSwitchObservers.finishBroadcast(); 18799 } 18800 18801 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18802 synchronized (this) { 18803 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18804 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18805 } 18806 } 18807 18808 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18809 mCurUserSwitchCallback = null; 18810 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18811 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18812 oldUserId, newUserId, uss)); 18813 } 18814 18815 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18816 synchronized (this) { 18817 if (foreground) { 18818 moveUserToForeground(uss, oldUserId, newUserId); 18819 } 18820 } 18821 18822 completeSwitchAndInitalize(uss, newUserId, true, false); 18823 } 18824 18825 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18826 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18827 if (homeInFront) { 18828 startHomeActivityLocked(newUserId); 18829 } else { 18830 mStackSupervisor.resumeTopActivitiesLocked(); 18831 } 18832 EventLogTags.writeAmSwitchUser(newUserId); 18833 getUserManagerLocked().userForeground(newUserId); 18834 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18835 } 18836 18837 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18838 completeSwitchAndInitalize(uss, newUserId, false, true); 18839 } 18840 18841 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18842 boolean clearInitializing, boolean clearSwitching) { 18843 boolean unfrozen = false; 18844 synchronized (this) { 18845 if (clearInitializing) { 18846 uss.initializing = false; 18847 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18848 } 18849 if (clearSwitching) { 18850 uss.switching = false; 18851 } 18852 if (!uss.switching && !uss.initializing) { 18853 mWindowManager.stopFreezingScreen(); 18854 unfrozen = true; 18855 } 18856 } 18857 if (unfrozen) { 18858 final int N = mUserSwitchObservers.beginBroadcast(); 18859 for (int i=0; i<N; i++) { 18860 try { 18861 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18862 } catch (RemoteException e) { 18863 } 18864 } 18865 mUserSwitchObservers.finishBroadcast(); 18866 } 18867 } 18868 18869 void scheduleStartProfilesLocked() { 18870 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18871 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18872 DateUtils.SECOND_IN_MILLIS); 18873 } 18874 } 18875 18876 void startProfilesLocked() { 18877 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18878 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18879 mCurrentUserId, false /* enabledOnly */); 18880 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18881 for (UserInfo user : profiles) { 18882 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18883 && user.id != mCurrentUserId) { 18884 toStart.add(user); 18885 } 18886 } 18887 final int n = toStart.size(); 18888 int i = 0; 18889 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18890 startUserInBackground(toStart.get(i).id); 18891 } 18892 if (i < n) { 18893 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18894 } 18895 } 18896 18897 void finishUserBoot(UserStartedState uss) { 18898 synchronized (this) { 18899 if (uss.mState == UserStartedState.STATE_BOOTING 18900 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18901 uss.mState = UserStartedState.STATE_RUNNING; 18902 final int userId = uss.mHandle.getIdentifier(); 18903 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18904 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18905 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18906 broadcastIntentLocked(null, null, intent, 18907 null, null, 0, null, null, 18908 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18909 true, false, MY_PID, Process.SYSTEM_UID, userId); 18910 } 18911 } 18912 } 18913 18914 void finishUserSwitch(UserStartedState uss) { 18915 synchronized (this) { 18916 finishUserBoot(uss); 18917 18918 startProfilesLocked(); 18919 18920 int num = mUserLru.size(); 18921 int i = 0; 18922 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18923 Integer oldUserId = mUserLru.get(i); 18924 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18925 if (oldUss == null) { 18926 // Shouldn't happen, but be sane if it does. 18927 mUserLru.remove(i); 18928 num--; 18929 continue; 18930 } 18931 if (oldUss.mState == UserStartedState.STATE_STOPPING 18932 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18933 // This user is already stopping, doesn't count. 18934 num--; 18935 i++; 18936 continue; 18937 } 18938 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18939 // Owner and current can't be stopped, but count as running. 18940 i++; 18941 continue; 18942 } 18943 // This is a user to be stopped. 18944 stopUserLocked(oldUserId, null); 18945 num--; 18946 i++; 18947 } 18948 } 18949 } 18950 18951 @Override 18952 public int stopUser(final int userId, final IStopUserCallback callback) { 18953 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18954 != PackageManager.PERMISSION_GRANTED) { 18955 String msg = "Permission Denial: switchUser() from pid=" 18956 + Binder.getCallingPid() 18957 + ", uid=" + Binder.getCallingUid() 18958 + " requires " + INTERACT_ACROSS_USERS_FULL; 18959 Slog.w(TAG, msg); 18960 throw new SecurityException(msg); 18961 } 18962 if (userId <= 0) { 18963 throw new IllegalArgumentException("Can't stop primary user " + userId); 18964 } 18965 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18966 synchronized (this) { 18967 return stopUserLocked(userId, callback); 18968 } 18969 } 18970 18971 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18972 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18973 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18974 return ActivityManager.USER_OP_IS_CURRENT; 18975 } 18976 18977 final UserStartedState uss = mStartedUsers.get(userId); 18978 if (uss == null) { 18979 // User is not started, nothing to do... but we do need to 18980 // callback if requested. 18981 if (callback != null) { 18982 mHandler.post(new Runnable() { 18983 @Override 18984 public void run() { 18985 try { 18986 callback.userStopped(userId); 18987 } catch (RemoteException e) { 18988 } 18989 } 18990 }); 18991 } 18992 return ActivityManager.USER_OP_SUCCESS; 18993 } 18994 18995 if (callback != null) { 18996 uss.mStopCallbacks.add(callback); 18997 } 18998 18999 if (uss.mState != UserStartedState.STATE_STOPPING 19000 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19001 uss.mState = UserStartedState.STATE_STOPPING; 19002 updateStartedUserArrayLocked(); 19003 19004 long ident = Binder.clearCallingIdentity(); 19005 try { 19006 // We are going to broadcast ACTION_USER_STOPPING and then 19007 // once that is done send a final ACTION_SHUTDOWN and then 19008 // stop the user. 19009 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19010 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19011 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19012 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19013 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19014 // This is the result receiver for the final shutdown broadcast. 19015 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19016 @Override 19017 public void performReceive(Intent intent, int resultCode, String data, 19018 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19019 finishUserStop(uss); 19020 } 19021 }; 19022 // This is the result receiver for the initial stopping broadcast. 19023 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19024 @Override 19025 public void performReceive(Intent intent, int resultCode, String data, 19026 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19027 // On to the next. 19028 synchronized (ActivityManagerService.this) { 19029 if (uss.mState != UserStartedState.STATE_STOPPING) { 19030 // Whoops, we are being started back up. Abort, abort! 19031 return; 19032 } 19033 uss.mState = UserStartedState.STATE_SHUTDOWN; 19034 } 19035 mBatteryStatsService.noteEvent( 19036 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19037 Integer.toString(userId), userId); 19038 mSystemServiceManager.stopUser(userId); 19039 broadcastIntentLocked(null, null, shutdownIntent, 19040 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19041 true, false, MY_PID, Process.SYSTEM_UID, userId); 19042 } 19043 }; 19044 // Kick things off. 19045 broadcastIntentLocked(null, null, stoppingIntent, 19046 null, stoppingReceiver, 0, null, null, 19047 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19048 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19049 } finally { 19050 Binder.restoreCallingIdentity(ident); 19051 } 19052 } 19053 19054 return ActivityManager.USER_OP_SUCCESS; 19055 } 19056 19057 void finishUserStop(UserStartedState uss) { 19058 final int userId = uss.mHandle.getIdentifier(); 19059 boolean stopped; 19060 ArrayList<IStopUserCallback> callbacks; 19061 synchronized (this) { 19062 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19063 if (mStartedUsers.get(userId) != uss) { 19064 stopped = false; 19065 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19066 stopped = false; 19067 } else { 19068 stopped = true; 19069 // User can no longer run. 19070 mStartedUsers.remove(userId); 19071 mUserLru.remove(Integer.valueOf(userId)); 19072 updateStartedUserArrayLocked(); 19073 19074 // Clean up all state and processes associated with the user. 19075 // Kill all the processes for the user. 19076 forceStopUserLocked(userId, "finish user"); 19077 } 19078 19079 // Explicitly remove the old information in mRecentTasks. 19080 removeRecentTasksForUserLocked(userId); 19081 } 19082 19083 for (int i=0; i<callbacks.size(); i++) { 19084 try { 19085 if (stopped) callbacks.get(i).userStopped(userId); 19086 else callbacks.get(i).userStopAborted(userId); 19087 } catch (RemoteException e) { 19088 } 19089 } 19090 19091 if (stopped) { 19092 mSystemServiceManager.cleanupUser(userId); 19093 synchronized (this) { 19094 mStackSupervisor.removeUserLocked(userId); 19095 } 19096 } 19097 } 19098 19099 @Override 19100 public UserInfo getCurrentUser() { 19101 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19102 != PackageManager.PERMISSION_GRANTED) && ( 19103 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19104 != PackageManager.PERMISSION_GRANTED)) { 19105 String msg = "Permission Denial: getCurrentUser() from pid=" 19106 + Binder.getCallingPid() 19107 + ", uid=" + Binder.getCallingUid() 19108 + " requires " + INTERACT_ACROSS_USERS; 19109 Slog.w(TAG, msg); 19110 throw new SecurityException(msg); 19111 } 19112 synchronized (this) { 19113 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19114 return getUserManagerLocked().getUserInfo(userId); 19115 } 19116 } 19117 19118 int getCurrentUserIdLocked() { 19119 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19120 } 19121 19122 @Override 19123 public boolean isUserRunning(int userId, boolean orStopped) { 19124 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19125 != PackageManager.PERMISSION_GRANTED) { 19126 String msg = "Permission Denial: isUserRunning() from pid=" 19127 + Binder.getCallingPid() 19128 + ", uid=" + Binder.getCallingUid() 19129 + " requires " + INTERACT_ACROSS_USERS; 19130 Slog.w(TAG, msg); 19131 throw new SecurityException(msg); 19132 } 19133 synchronized (this) { 19134 return isUserRunningLocked(userId, orStopped); 19135 } 19136 } 19137 19138 boolean isUserRunningLocked(int userId, boolean orStopped) { 19139 UserStartedState state = mStartedUsers.get(userId); 19140 if (state == null) { 19141 return false; 19142 } 19143 if (orStopped) { 19144 return true; 19145 } 19146 return state.mState != UserStartedState.STATE_STOPPING 19147 && state.mState != UserStartedState.STATE_SHUTDOWN; 19148 } 19149 19150 @Override 19151 public int[] getRunningUserIds() { 19152 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19153 != PackageManager.PERMISSION_GRANTED) { 19154 String msg = "Permission Denial: isUserRunning() from pid=" 19155 + Binder.getCallingPid() 19156 + ", uid=" + Binder.getCallingUid() 19157 + " requires " + INTERACT_ACROSS_USERS; 19158 Slog.w(TAG, msg); 19159 throw new SecurityException(msg); 19160 } 19161 synchronized (this) { 19162 return mStartedUserArray; 19163 } 19164 } 19165 19166 private void updateStartedUserArrayLocked() { 19167 int num = 0; 19168 for (int i=0; i<mStartedUsers.size(); i++) { 19169 UserStartedState uss = mStartedUsers.valueAt(i); 19170 // This list does not include stopping users. 19171 if (uss.mState != UserStartedState.STATE_STOPPING 19172 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19173 num++; 19174 } 19175 } 19176 mStartedUserArray = new int[num]; 19177 num = 0; 19178 for (int i=0; i<mStartedUsers.size(); i++) { 19179 UserStartedState uss = mStartedUsers.valueAt(i); 19180 if (uss.mState != UserStartedState.STATE_STOPPING 19181 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19182 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19183 num++; 19184 } 19185 } 19186 } 19187 19188 @Override 19189 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19190 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19191 != PackageManager.PERMISSION_GRANTED) { 19192 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19193 + Binder.getCallingPid() 19194 + ", uid=" + Binder.getCallingUid() 19195 + " requires " + INTERACT_ACROSS_USERS_FULL; 19196 Slog.w(TAG, msg); 19197 throw new SecurityException(msg); 19198 } 19199 19200 mUserSwitchObservers.register(observer); 19201 } 19202 19203 @Override 19204 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19205 mUserSwitchObservers.unregister(observer); 19206 } 19207 19208 private boolean userExists(int userId) { 19209 if (userId == 0) { 19210 return true; 19211 } 19212 UserManagerService ums = getUserManagerLocked(); 19213 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19214 } 19215 19216 int[] getUsersLocked() { 19217 UserManagerService ums = getUserManagerLocked(); 19218 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19219 } 19220 19221 UserManagerService getUserManagerLocked() { 19222 if (mUserManager == null) { 19223 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19224 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19225 } 19226 return mUserManager; 19227 } 19228 19229 private int applyUserId(int uid, int userId) { 19230 return UserHandle.getUid(userId, uid); 19231 } 19232 19233 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19234 if (info == null) return null; 19235 ApplicationInfo newInfo = new ApplicationInfo(info); 19236 newInfo.uid = applyUserId(info.uid, userId); 19237 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19238 + info.packageName; 19239 return newInfo; 19240 } 19241 19242 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19243 if (aInfo == null 19244 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19245 return aInfo; 19246 } 19247 19248 ActivityInfo info = new ActivityInfo(aInfo); 19249 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19250 return info; 19251 } 19252 19253 private final class LocalService extends ActivityManagerInternal { 19254 @Override 19255 public void onWakefulnessChanged(int wakefulness) { 19256 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19257 } 19258 19259 @Override 19260 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19261 String processName, String abiOverride, int uid, Runnable crashHandler) { 19262 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19263 processName, abiOverride, uid, crashHandler); 19264 } 19265 } 19266 19267 /** 19268 * An implementation of IAppTask, that allows an app to manage its own tasks via 19269 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19270 * only the process that calls getAppTasks() can call the AppTask methods. 19271 */ 19272 class AppTaskImpl extends IAppTask.Stub { 19273 private int mTaskId; 19274 private int mCallingUid; 19275 19276 public AppTaskImpl(int taskId, int callingUid) { 19277 mTaskId = taskId; 19278 mCallingUid = callingUid; 19279 } 19280 19281 private void checkCaller() { 19282 if (mCallingUid != Binder.getCallingUid()) { 19283 throw new SecurityException("Caller " + mCallingUid 19284 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19285 } 19286 } 19287 19288 @Override 19289 public void finishAndRemoveTask() { 19290 checkCaller(); 19291 19292 synchronized (ActivityManagerService.this) { 19293 long origId = Binder.clearCallingIdentity(); 19294 try { 19295 if (!removeTaskByIdLocked(mTaskId, false)) { 19296 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19297 } 19298 } finally { 19299 Binder.restoreCallingIdentity(origId); 19300 } 19301 } 19302 } 19303 19304 @Override 19305 public ActivityManager.RecentTaskInfo getTaskInfo() { 19306 checkCaller(); 19307 19308 synchronized (ActivityManagerService.this) { 19309 long origId = Binder.clearCallingIdentity(); 19310 try { 19311 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19312 if (tr == null) { 19313 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19314 } 19315 return createRecentTaskInfoFromTaskRecord(tr); 19316 } finally { 19317 Binder.restoreCallingIdentity(origId); 19318 } 19319 } 19320 } 19321 19322 @Override 19323 public void moveToFront() { 19324 checkCaller(); 19325 19326 final TaskRecord tr; 19327 synchronized (ActivityManagerService.this) { 19328 tr = recentTaskForIdLocked(mTaskId); 19329 if (tr == null) { 19330 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19331 } 19332 if (tr.getRootActivity() != null) { 19333 moveTaskToFrontLocked(tr.taskId, 0, null); 19334 return; 19335 } 19336 } 19337 19338 startActivityFromRecentsInner(tr.taskId, null); 19339 } 19340 19341 @Override 19342 public int startActivity(IBinder whoThread, String callingPackage, 19343 Intent intent, String resolvedType, Bundle options) { 19344 checkCaller(); 19345 19346 int callingUser = UserHandle.getCallingUserId(); 19347 TaskRecord tr; 19348 IApplicationThread appThread; 19349 synchronized (ActivityManagerService.this) { 19350 tr = recentTaskForIdLocked(mTaskId); 19351 if (tr == null) { 19352 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19353 } 19354 appThread = ApplicationThreadNative.asInterface(whoThread); 19355 if (appThread == null) { 19356 throw new IllegalArgumentException("Bad app thread " + appThread); 19357 } 19358 } 19359 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19360 resolvedType, null, null, null, null, 0, 0, null, null, 19361 null, options, callingUser, null, tr); 19362 } 19363 19364 @Override 19365 public void setExcludeFromRecents(boolean exclude) { 19366 checkCaller(); 19367 19368 synchronized (ActivityManagerService.this) { 19369 long origId = Binder.clearCallingIdentity(); 19370 try { 19371 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19372 if (tr == null) { 19373 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19374 } 19375 Intent intent = tr.getBaseIntent(); 19376 if (exclude) { 19377 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19378 } else { 19379 intent.setFlags(intent.getFlags() 19380 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19381 } 19382 } finally { 19383 Binder.restoreCallingIdentity(origId); 19384 } 19385 } 19386 } 19387 } 19388} 19389