ActivityManagerService.java revision 18795a2299fefd88ee16393f22324b999ace6ce4
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 34 35import android.Manifest; 36import android.app.AppOpsManager; 37import android.app.ApplicationThreadNative; 38import android.app.IActivityContainer; 39import android.app.IActivityContainerCallback; 40import android.app.IAppTask; 41import android.app.ITaskStackListener; 42import android.app.ProfilerInfo; 43import android.app.admin.DevicePolicyManager; 44import android.app.usage.UsageEvents; 45import android.app.usage.UsageStatsManagerInternal; 46import android.appwidget.AppWidgetManager; 47import android.content.res.Resources; 48import android.graphics.Bitmap; 49import android.graphics.Point; 50import android.graphics.Rect; 51import android.os.BatteryStats; 52import android.os.PersistableBundle; 53import android.os.storage.IMountService; 54import android.os.storage.StorageManager; 55import android.service.voice.IVoiceInteractionSession; 56import android.util.ArrayMap; 57import android.util.ArraySet; 58import android.util.SparseIntArray; 59 60import com.android.internal.R; 61import com.android.internal.annotations.GuardedBy; 62import com.android.internal.app.IAppOpsService; 63import com.android.internal.app.IVoiceInteractor; 64import com.android.internal.app.ProcessMap; 65import com.android.internal.app.ProcessStats; 66import com.android.internal.os.BackgroundThread; 67import com.android.internal.os.BatteryStatsImpl; 68import com.android.internal.os.ProcessCpuTracker; 69import com.android.internal.os.TransferPipe; 70import com.android.internal.os.Zygote; 71import com.android.internal.util.FastPrintWriter; 72import com.android.internal.util.FastXmlSerializer; 73import com.android.internal.util.MemInfoReader; 74import com.android.internal.util.Preconditions; 75import com.android.server.AppOpsService; 76import com.android.server.AttributeCache; 77import com.android.server.IntentResolver; 78import com.android.server.LocalServices; 79import com.android.server.ServiceThread; 80import com.android.server.SystemService; 81import com.android.server.SystemServiceManager; 82import com.android.server.Watchdog; 83import com.android.server.am.ActivityStack.ActivityState; 84import com.android.server.firewall.IntentFirewall; 85import com.android.server.pm.Installer; 86import com.android.server.pm.UserManagerService; 87import com.android.server.statusbar.StatusBarManagerInternal; 88import com.android.server.wm.AppTransition; 89import com.android.server.wm.WindowManagerService; 90import com.google.android.collect.Lists; 91import com.google.android.collect.Maps; 92 93import libcore.io.IoUtils; 94 95import org.xmlpull.v1.XmlPullParser; 96import org.xmlpull.v1.XmlPullParserException; 97import org.xmlpull.v1.XmlSerializer; 98 99import android.app.Activity; 100import android.app.ActivityManager; 101import android.app.ActivityManager.RunningTaskInfo; 102import android.app.ActivityManager.StackInfo; 103import android.app.ActivityManagerInternal; 104import android.app.ActivityManagerNative; 105import android.app.ActivityOptions; 106import android.app.ActivityThread; 107import android.app.AlertDialog; 108import android.app.AppGlobals; 109import android.app.ApplicationErrorReport; 110import android.app.Dialog; 111import android.app.IActivityController; 112import android.app.IApplicationThread; 113import android.app.IInstrumentationWatcher; 114import android.app.INotificationManager; 115import android.app.IProcessObserver; 116import android.app.IServiceConnection; 117import android.app.IStopUserCallback; 118import android.app.IUiAutomationConnection; 119import android.app.IUserSwitchObserver; 120import android.app.Instrumentation; 121import android.app.Notification; 122import android.app.NotificationManager; 123import android.app.PendingIntent; 124import android.app.backup.IBackupManager; 125import android.content.ActivityNotFoundException; 126import android.content.BroadcastReceiver; 127import android.content.ClipData; 128import android.content.ComponentCallbacks2; 129import android.content.ComponentName; 130import android.content.ContentProvider; 131import android.content.ContentResolver; 132import android.content.Context; 133import android.content.DialogInterface; 134import android.content.IContentProvider; 135import android.content.IIntentReceiver; 136import android.content.IIntentSender; 137import android.content.Intent; 138import android.content.IntentFilter; 139import android.content.IntentSender; 140import android.content.pm.ActivityInfo; 141import android.content.pm.ApplicationInfo; 142import android.content.pm.ConfigurationInfo; 143import android.content.pm.IPackageDataObserver; 144import android.content.pm.IPackageManager; 145import android.content.pm.InstrumentationInfo; 146import android.content.pm.PackageInfo; 147import android.content.pm.PackageManager; 148import android.content.pm.ParceledListSlice; 149import android.content.pm.UserInfo; 150import android.content.pm.PackageManager.NameNotFoundException; 151import android.content.pm.PathPermission; 152import android.content.pm.ProviderInfo; 153import android.content.pm.ResolveInfo; 154import android.content.pm.ServiceInfo; 155import android.content.res.CompatibilityInfo; 156import android.content.res.Configuration; 157import android.net.Proxy; 158import android.net.ProxyInfo; 159import android.net.Uri; 160import android.os.Binder; 161import android.os.Build; 162import android.os.Bundle; 163import android.os.Debug; 164import android.os.DropBoxManager; 165import android.os.Environment; 166import android.os.FactoryTest; 167import android.os.FileObserver; 168import android.os.FileUtils; 169import android.os.Handler; 170import android.os.IBinder; 171import android.os.IPermissionController; 172import android.os.IRemoteCallback; 173import android.os.IUserManager; 174import android.os.Looper; 175import android.os.Message; 176import android.os.Parcel; 177import android.os.ParcelFileDescriptor; 178import android.os.PowerManagerInternal; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.SELinux; 183import android.os.ServiceManager; 184import android.os.StrictMode; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.UpdateLock; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.provider.Settings; 191import android.text.format.DateUtils; 192import android.text.format.Time; 193import android.util.AtomicFile; 194import android.util.EventLog; 195import android.util.Log; 196import android.util.Pair; 197import android.util.PrintWriterPrinter; 198import android.util.Slog; 199import android.util.SparseArray; 200import android.util.TimeUtils; 201import android.util.Xml; 202import android.view.Gravity; 203import android.view.LayoutInflater; 204import android.view.View; 205import android.view.WindowManager; 206 207import dalvik.system.VMRuntime; 208 209import java.io.BufferedInputStream; 210import java.io.BufferedOutputStream; 211import java.io.DataInputStream; 212import java.io.DataOutputStream; 213import java.io.File; 214import java.io.FileDescriptor; 215import java.io.FileInputStream; 216import java.io.FileNotFoundException; 217import java.io.FileOutputStream; 218import java.io.IOException; 219import java.io.InputStreamReader; 220import java.io.PrintWriter; 221import java.io.StringWriter; 222import java.lang.ref.WeakReference; 223import java.util.ArrayList; 224import java.util.Arrays; 225import java.util.Collections; 226import java.util.Comparator; 227import java.util.HashMap; 228import java.util.HashSet; 229import java.util.Iterator; 230import java.util.List; 231import java.util.Locale; 232import java.util.Map; 233import java.util.Set; 234import java.util.concurrent.atomic.AtomicBoolean; 235import java.util.concurrent.atomic.AtomicLong; 236 237public final class ActivityManagerService extends ActivityManagerNative 238 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 239 240 private static final String USER_DATA_DIR = "/data/user/"; 241 // File that stores last updated system version and called preboot receivers 242 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 243 244 static final String TAG = "ActivityManager"; 245 static final String TAG_MU = "ActivityManagerServiceMU"; 246 static final boolean DEBUG = false; 247 static final boolean localLOGV = DEBUG; 248 static final boolean DEBUG_BACKUP = localLOGV || false; 249 static final boolean DEBUG_BROADCAST = localLOGV || false; 250 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_CLEANUP = localLOGV || false; 253 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 254 static final boolean DEBUG_FOCUS = false; 255 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 256 static final boolean DEBUG_MU = localLOGV || false; 257 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 258 static final boolean DEBUG_LRU = localLOGV || false; 259 static final boolean DEBUG_PAUSE = localLOGV || false; 260 static final boolean DEBUG_POWER = localLOGV || false; 261 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 262 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 263 static final boolean DEBUG_PROCESSES = localLOGV || false; 264 static final boolean DEBUG_PROVIDER = localLOGV || false; 265 static final boolean DEBUG_RESULTS = localLOGV || false; 266 static final boolean DEBUG_SERVICE = localLOGV || false; 267 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 268 static final boolean DEBUG_STACK = localLOGV || false; 269 static final boolean DEBUG_SWITCH = localLOGV || false; 270 static final boolean DEBUG_TASKS = localLOGV || false; 271 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 272 static final boolean DEBUG_TRANSITION = localLOGV || false; 273 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 274 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 275 static final boolean DEBUG_VISBILITY = localLOGV || false; 276 static final boolean DEBUG_PSS = localLOGV || false; 277 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 278 static final boolean DEBUG_RECENTS = localLOGV || false; 279 static final boolean VALIDATE_TOKENS = false; 280 static final boolean SHOW_ACTIVITY_START_TIME = true; 281 282 // Control over CPU and battery monitoring. 283 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 284 static final boolean MONITOR_CPU_USAGE = true; 285 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 286 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 287 static final boolean MONITOR_THREAD_CPU_USAGE = false; 288 289 // The flags that are set for all calls we make to the package manager. 290 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 291 292 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 293 294 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 295 296 // Maximum number recent bitmaps to keep in memory. 297 static final int MAX_RECENT_BITMAPS = 3; 298 299 // Amount of time after a call to stopAppSwitches() during which we will 300 // prevent further untrusted switches from happening. 301 static final long APP_SWITCH_DELAY_TIME = 5*1000; 302 303 // How long we wait for a launched process to attach to the activity manager 304 // before we decide it's never going to come up for real. 305 static final int PROC_START_TIMEOUT = 10*1000; 306 307 // How long we wait for a launched process to attach to the activity manager 308 // before we decide it's never going to come up for real, when the process was 309 // started with a wrapper for instrumentation (such as Valgrind) because it 310 // could take much longer than usual. 311 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 312 313 // How long to wait after going idle before forcing apps to GC. 314 static final int GC_TIMEOUT = 5*1000; 315 316 // The minimum amount of time between successive GC requests for a process. 317 static final int GC_MIN_INTERVAL = 60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process. 320 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 321 322 // The minimum amount of time between successive PSS requests for a process 323 // when the request is due to the memory state being lowered. 324 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 325 326 // The rate at which we check for apps using excessive power -- 15 mins. 327 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on wake locks to start killing things. 331 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // The minimum sample duration we will allow before deciding we have 334 // enough data on CPU usage to start killing things. 335 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 336 337 // How long we allow a receiver to run before giving up on it. 338 static final int BROADCAST_FG_TIMEOUT = 10*1000; 339 static final int BROADCAST_BG_TIMEOUT = 60*1000; 340 341 // How long we wait until we timeout on key dispatching. 342 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 343 344 // How long we wait until we timeout on key dispatching during instrumentation. 345 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 346 347 // Amount of time we wait for observers to handle a user switch before 348 // giving up on them and unfreezing the screen. 349 static final int USER_SWITCH_TIMEOUT = 2*1000; 350 351 // Maximum number of users we allow to be running at a time. 352 static final int MAX_RUNNING_USERS = 3; 353 354 // How long to wait in getAssistContextExtras for the activity and foreground services 355 // to respond with the result. 356 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 357 358 // Maximum number of persisted Uri grants a package is allowed 359 static final int MAX_PERSISTED_URI_GRANTS = 128; 360 361 static final int MY_PID = Process.myPid(); 362 363 static final String[] EMPTY_STRING_ARRAY = new String[0]; 364 365 // How many bytes to write into the dropbox log before truncating 366 static final int DROPBOX_MAX_SIZE = 256 * 1024; 367 368 // Access modes for handleIncomingUser. 369 static final int ALLOW_NON_FULL = 0; 370 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 371 static final int ALLOW_FULL_ONLY = 2; 372 373 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 374 375 // Delay in notifying task stack change listeners (in millis) 376 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 377 378 /** All system services */ 379 SystemServiceManager mSystemServiceManager; 380 381 private Installer mInstaller; 382 383 /** Run all ActivityStacks through this */ 384 ActivityStackSupervisor mStackSupervisor; 385 386 /** Task stack change listeners. */ 387 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 388 new RemoteCallbackList<ITaskStackListener>(); 389 390 public IntentFirewall mIntentFirewall; 391 392 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 393 // default actuion automatically. Important for devices without direct input 394 // devices. 395 private boolean mShowDialogs = true; 396 397 BroadcastQueue mFgBroadcastQueue; 398 BroadcastQueue mBgBroadcastQueue; 399 // Convenient for easy iteration over the queues. Foreground is first 400 // so that dispatch of foreground broadcasts gets precedence. 401 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 402 403 BroadcastQueue broadcastQueueForIntent(Intent intent) { 404 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 405 if (DEBUG_BACKGROUND_BROADCAST) { 406 Slog.i(TAG, "Broadcast intent " + intent + " on " 407 + (isFg ? "foreground" : "background") 408 + " queue"); 409 } 410 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 411 } 412 413 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 414 for (BroadcastQueue queue : mBroadcastQueues) { 415 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 416 if (r != null) { 417 return r; 418 } 419 } 420 return null; 421 } 422 423 /** 424 * Activity we have told the window manager to have key focus. 425 */ 426 ActivityRecord mFocusedActivity = null; 427 428 /** 429 * List of intents that were used to start the most recent tasks. 430 */ 431 ArrayList<TaskRecord> mRecentTasks; 432 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 433 434 /** 435 * For addAppTask: cached of the last activity component that was added. 436 */ 437 ComponentName mLastAddedTaskComponent; 438 439 /** 440 * For addAppTask: cached of the last activity uid that was added. 441 */ 442 int mLastAddedTaskUid; 443 444 /** 445 * For addAppTask: cached of the last ActivityInfo that was added. 446 */ 447 ActivityInfo mLastAddedTaskActivity; 448 449 public class PendingAssistExtras extends Binder implements Runnable { 450 public final ActivityRecord activity; 451 public final Bundle extras; 452 public final Intent intent; 453 public final String hint; 454 public final int userHandle; 455 public boolean haveResult = false; 456 public Bundle result = null; 457 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 458 String _hint, int _userHandle) { 459 activity = _activity; 460 extras = _extras; 461 intent = _intent; 462 hint = _hint; 463 userHandle = _userHandle; 464 } 465 @Override 466 public void run() { 467 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 468 synchronized (this) { 469 haveResult = true; 470 notifyAll(); 471 } 472 } 473 } 474 475 final ArrayList<PendingAssistExtras> mPendingAssistExtras 476 = new ArrayList<PendingAssistExtras>(); 477 478 /** 479 * Process management. 480 */ 481 final ProcessList mProcessList = new ProcessList(); 482 483 /** 484 * All of the applications we currently have running organized by name. 485 * The keys are strings of the application package name (as 486 * returned by the package manager), and the keys are ApplicationRecord 487 * objects. 488 */ 489 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 490 491 /** 492 * Tracking long-term execution of processes to look for abuse and other 493 * bad app behavior. 494 */ 495 final ProcessStatsService mProcessStats; 496 497 /** 498 * The currently running isolated processes. 499 */ 500 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 501 502 /** 503 * Counter for assigning isolated process uids, to avoid frequently reusing the 504 * same ones. 505 */ 506 int mNextIsolatedProcessUid = 0; 507 508 /** 509 * The currently running heavy-weight process, if any. 510 */ 511 ProcessRecord mHeavyWeightProcess = null; 512 513 /** 514 * The last time that various processes have crashed. 515 */ 516 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 517 518 /** 519 * Information about a process that is currently marked as bad. 520 */ 521 static final class BadProcessInfo { 522 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 523 this.time = time; 524 this.shortMsg = shortMsg; 525 this.longMsg = longMsg; 526 this.stack = stack; 527 } 528 529 final long time; 530 final String shortMsg; 531 final String longMsg; 532 final String stack; 533 } 534 535 /** 536 * Set of applications that we consider to be bad, and will reject 537 * incoming broadcasts from (which the user has no control over). 538 * Processes are added to this set when they have crashed twice within 539 * a minimum amount of time; they are removed from it when they are 540 * later restarted (hopefully due to some user action). The value is the 541 * time it was added to the list. 542 */ 543 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 544 545 /** 546 * All of the processes we currently have running organized by pid. 547 * The keys are the pid running the application. 548 * 549 * <p>NOTE: This object is protected by its own lock, NOT the global 550 * activity manager lock! 551 */ 552 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 553 554 /** 555 * All of the processes that have been forced to be foreground. The key 556 * is the pid of the caller who requested it (we hold a death 557 * link on it). 558 */ 559 abstract class ForegroundToken implements IBinder.DeathRecipient { 560 int pid; 561 IBinder token; 562 } 563 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 564 565 /** 566 * List of records for processes that someone had tried to start before the 567 * system was ready. We don't start them at that point, but ensure they 568 * are started by the time booting is complete. 569 */ 570 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 571 572 /** 573 * List of persistent applications that are in the process 574 * of being started. 575 */ 576 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes that are being forcibly torn down. 580 */ 581 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * List of running applications, sorted by recent usage. 585 * The first entry in the list is the least recently used. 586 */ 587 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 588 589 /** 590 * Where in mLruProcesses that the processes hosting activities start. 591 */ 592 int mLruProcessActivityStart = 0; 593 594 /** 595 * Where in mLruProcesses that the processes hosting services start. 596 * This is after (lower index) than mLruProcessesActivityStart. 597 */ 598 int mLruProcessServiceStart = 0; 599 600 /** 601 * List of processes that should gc as soon as things are idle. 602 */ 603 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 604 605 /** 606 * Processes we want to collect PSS data from. 607 */ 608 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 609 610 /** 611 * Last time we requested PSS data of all processes. 612 */ 613 long mLastFullPssTime = SystemClock.uptimeMillis(); 614 615 /** 616 * If set, the next time we collect PSS data we should do a full collection 617 * with data from native processes and the kernel. 618 */ 619 boolean mFullPssPending = false; 620 621 /** 622 * This is the process holding what we currently consider to be 623 * the "home" activity. 624 */ 625 ProcessRecord mHomeProcess; 626 627 /** 628 * This is the process holding the activity the user last visited that 629 * is in a different process from the one they are currently in. 630 */ 631 ProcessRecord mPreviousProcess; 632 633 /** 634 * The time at which the previous process was last visible. 635 */ 636 long mPreviousProcessVisibleTime; 637 638 /** 639 * Which uses have been started, so are allowed to run code. 640 */ 641 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 642 643 /** 644 * LRU list of history of current users. Most recently current is at the end. 645 */ 646 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 647 648 /** 649 * Constant array of the users that are currently started. 650 */ 651 int[] mStartedUserArray = new int[] { 0 }; 652 653 /** 654 * Registered observers of the user switching mechanics. 655 */ 656 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 657 = new RemoteCallbackList<IUserSwitchObserver>(); 658 659 /** 660 * Currently active user switch. 661 */ 662 Object mCurUserSwitchCallback; 663 664 /** 665 * Packages that the user has asked to have run in screen size 666 * compatibility mode instead of filling the screen. 667 */ 668 final CompatModePackages mCompatModePackages; 669 670 /** 671 * Set of IntentSenderRecord objects that are currently active. 672 */ 673 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 674 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 675 676 /** 677 * Fingerprints (hashCode()) of stack traces that we've 678 * already logged DropBox entries for. Guarded by itself. If 679 * something (rogue user app) forces this over 680 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 681 */ 682 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 683 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 684 685 /** 686 * Strict Mode background batched logging state. 687 * 688 * The string buffer is guarded by itself, and its lock is also 689 * used to determine if another batched write is already 690 * in-flight. 691 */ 692 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 693 694 /** 695 * Keeps track of all IIntentReceivers that have been registered for 696 * broadcasts. Hash keys are the receiver IBinder, hash value is 697 * a ReceiverList. 698 */ 699 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 700 new HashMap<IBinder, ReceiverList>(); 701 702 /** 703 * Resolver for broadcast intents to registered receivers. 704 * Holds BroadcastFilter (subclass of IntentFilter). 705 */ 706 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 707 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 708 @Override 709 protected boolean allowFilterResult( 710 BroadcastFilter filter, List<BroadcastFilter> dest) { 711 IBinder target = filter.receiverList.receiver.asBinder(); 712 for (int i=dest.size()-1; i>=0; i--) { 713 if (dest.get(i).receiverList.receiver.asBinder() == target) { 714 return false; 715 } 716 } 717 return true; 718 } 719 720 @Override 721 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 722 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 723 || userId == filter.owningUserId) { 724 return super.newResult(filter, match, userId); 725 } 726 return null; 727 } 728 729 @Override 730 protected BroadcastFilter[] newArray(int size) { 731 return new BroadcastFilter[size]; 732 } 733 734 @Override 735 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 736 return packageName.equals(filter.packageName); 737 } 738 }; 739 740 /** 741 * State of all active sticky broadcasts per user. Keys are the action of the 742 * sticky Intent, values are an ArrayList of all broadcasted intents with 743 * that action (which should usually be one). The SparseArray is keyed 744 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 745 * for stickies that are sent to all users. 746 */ 747 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 748 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 749 750 final ActiveServices mServices; 751 752 /** 753 * Backup/restore process management 754 */ 755 String mBackupAppName = null; 756 BackupRecord mBackupTarget = null; 757 758 final ProviderMap mProviderMap; 759 760 /** 761 * List of content providers who have clients waiting for them. The 762 * application is currently being launched and the provider will be 763 * removed from this list once it is published. 764 */ 765 final ArrayList<ContentProviderRecord> mLaunchingProviders 766 = new ArrayList<ContentProviderRecord>(); 767 768 /** 769 * File storing persisted {@link #mGrantedUriPermissions}. 770 */ 771 private final AtomicFile mGrantFile; 772 773 /** XML constants used in {@link #mGrantFile} */ 774 private static final String TAG_URI_GRANTS = "uri-grants"; 775 private static final String TAG_URI_GRANT = "uri-grant"; 776 private static final String ATTR_USER_HANDLE = "userHandle"; 777 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 778 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 779 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 780 private static final String ATTR_TARGET_PKG = "targetPkg"; 781 private static final String ATTR_URI = "uri"; 782 private static final String ATTR_MODE_FLAGS = "modeFlags"; 783 private static final String ATTR_CREATED_TIME = "createdTime"; 784 private static final String ATTR_PREFIX = "prefix"; 785 786 /** 787 * Global set of specific {@link Uri} permissions that have been granted. 788 * This optimized lookup structure maps from {@link UriPermission#targetUid} 789 * to {@link UriPermission#uri} to {@link UriPermission}. 790 */ 791 @GuardedBy("this") 792 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 793 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 794 795 public static class GrantUri { 796 public final int sourceUserId; 797 public final Uri uri; 798 public boolean prefix; 799 800 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 801 this.sourceUserId = sourceUserId; 802 this.uri = uri; 803 this.prefix = prefix; 804 } 805 806 @Override 807 public int hashCode() { 808 int hashCode = 1; 809 hashCode = 31 * hashCode + sourceUserId; 810 hashCode = 31 * hashCode + uri.hashCode(); 811 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 812 return hashCode; 813 } 814 815 @Override 816 public boolean equals(Object o) { 817 if (o instanceof GrantUri) { 818 GrantUri other = (GrantUri) o; 819 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 820 && prefix == other.prefix; 821 } 822 return false; 823 } 824 825 @Override 826 public String toString() { 827 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 828 if (prefix) result += " [prefix]"; 829 return result; 830 } 831 832 public String toSafeString() { 833 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 834 if (prefix) result += " [prefix]"; 835 return result; 836 } 837 838 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 839 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 840 ContentProvider.getUriWithoutUserId(uri), false); 841 } 842 } 843 844 CoreSettingsObserver mCoreSettingsObserver; 845 846 /** 847 * Thread-local storage used to carry caller permissions over through 848 * indirect content-provider access. 849 */ 850 private class Identity { 851 public final IBinder token; 852 public final int pid; 853 public final int uid; 854 855 Identity(IBinder _token, int _pid, int _uid) { 856 token = _token; 857 pid = _pid; 858 uid = _uid; 859 } 860 } 861 862 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 863 864 /** 865 * All information we have collected about the runtime performance of 866 * any user id that can impact battery performance. 867 */ 868 final BatteryStatsService mBatteryStatsService; 869 870 /** 871 * Information about component usage 872 */ 873 UsageStatsManagerInternal mUsageStatsService; 874 875 /** 876 * Information about and control over application operations 877 */ 878 final AppOpsService mAppOpsService; 879 880 /** 881 * Save recent tasks information across reboots. 882 */ 883 final TaskPersister mTaskPersister; 884 885 /** 886 * Current configuration information. HistoryRecord objects are given 887 * a reference to this object to indicate which configuration they are 888 * currently running in, so this object must be kept immutable. 889 */ 890 Configuration mConfiguration = new Configuration(); 891 892 /** 893 * Current sequencing integer of the configuration, for skipping old 894 * configurations. 895 */ 896 int mConfigurationSeq = 0; 897 898 /** 899 * Hardware-reported OpenGLES version. 900 */ 901 final int GL_ES_VERSION; 902 903 /** 904 * List of initialization arguments to pass to all processes when binding applications to them. 905 * For example, references to the commonly used services. 906 */ 907 HashMap<String, IBinder> mAppBindArgs; 908 909 /** 910 * Temporary to avoid allocations. Protected by main lock. 911 */ 912 final StringBuilder mStringBuilder = new StringBuilder(256); 913 914 /** 915 * Used to control how we initialize the service. 916 */ 917 ComponentName mTopComponent; 918 String mTopAction = Intent.ACTION_MAIN; 919 String mTopData; 920 boolean mProcessesReady = false; 921 boolean mSystemReady = false; 922 boolean mBooting = false; 923 boolean mCallFinishBooting = false; 924 boolean mBootAnimationComplete = false; 925 boolean mWaitingUpdate = false; 926 boolean mDidUpdate = false; 927 boolean mOnBattery = false; 928 boolean mLaunchWarningShown = false; 929 930 Context mContext; 931 932 int mFactoryTest; 933 934 boolean mCheckedForSetup; 935 936 /** 937 * The time at which we will allow normal application switches again, 938 * after a call to {@link #stopAppSwitches()}. 939 */ 940 long mAppSwitchesAllowedTime; 941 942 /** 943 * This is set to true after the first switch after mAppSwitchesAllowedTime 944 * is set; any switches after that will clear the time. 945 */ 946 boolean mDidAppSwitch; 947 948 /** 949 * Last time (in realtime) at which we checked for power usage. 950 */ 951 long mLastPowerCheckRealtime; 952 953 /** 954 * Last time (in uptime) at which we checked for power usage. 955 */ 956 long mLastPowerCheckUptime; 957 958 /** 959 * Set while we are wanting to sleep, to prevent any 960 * activities from being started/resumed. 961 */ 962 private boolean mSleeping = false; 963 964 /** 965 * Set while we are running a voice interaction. This overrides 966 * sleeping while it is active. 967 */ 968 private boolean mRunningVoice = false; 969 970 /** 971 * State of external calls telling us if the device is awake or asleep. 972 */ 973 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 974 975 static final int LOCK_SCREEN_HIDDEN = 0; 976 static final int LOCK_SCREEN_LEAVING = 1; 977 static final int LOCK_SCREEN_SHOWN = 2; 978 /** 979 * State of external call telling us if the lock screen is shown. 980 */ 981 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 982 983 /** 984 * Set if we are shutting down the system, similar to sleeping. 985 */ 986 boolean mShuttingDown = false; 987 988 /** 989 * Current sequence id for oom_adj computation traversal. 990 */ 991 int mAdjSeq = 0; 992 993 /** 994 * Current sequence id for process LRU updating. 995 */ 996 int mLruSeq = 0; 997 998 /** 999 * Keep track of the non-cached/empty process we last found, to help 1000 * determine how to distribute cached/empty processes next time. 1001 */ 1002 int mNumNonCachedProcs = 0; 1003 1004 /** 1005 * Keep track of the number of cached hidden procs, to balance oom adj 1006 * distribution between those and empty procs. 1007 */ 1008 int mNumCachedHiddenProcs = 0; 1009 1010 /** 1011 * Keep track of the number of service processes we last found, to 1012 * determine on the next iteration which should be B services. 1013 */ 1014 int mNumServiceProcs = 0; 1015 int mNewNumAServiceProcs = 0; 1016 int mNewNumServiceProcs = 0; 1017 1018 /** 1019 * Allow the current computed overall memory level of the system to go down? 1020 * This is set to false when we are killing processes for reasons other than 1021 * memory management, so that the now smaller process list will not be taken as 1022 * an indication that memory is tighter. 1023 */ 1024 boolean mAllowLowerMemLevel = false; 1025 1026 /** 1027 * The last computed memory level, for holding when we are in a state that 1028 * processes are going away for other reasons. 1029 */ 1030 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1031 1032 /** 1033 * The last total number of process we have, to determine if changes actually look 1034 * like a shrinking number of process due to lower RAM. 1035 */ 1036 int mLastNumProcesses; 1037 1038 /** 1039 * The uptime of the last time we performed idle maintenance. 1040 */ 1041 long mLastIdleTime = SystemClock.uptimeMillis(); 1042 1043 /** 1044 * Total time spent with RAM that has been added in the past since the last idle time. 1045 */ 1046 long mLowRamTimeSinceLastIdle = 0; 1047 1048 /** 1049 * If RAM is currently low, when that horrible situation started. 1050 */ 1051 long mLowRamStartTime = 0; 1052 1053 /** 1054 * For reporting to battery stats the current top application. 1055 */ 1056 private String mCurResumedPackage = null; 1057 private int mCurResumedUid = -1; 1058 1059 /** 1060 * For reporting to battery stats the apps currently running foreground 1061 * service. The ProcessMap is package/uid tuples; each of these contain 1062 * an array of the currently foreground processes. 1063 */ 1064 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1065 = new ProcessMap<ArrayList<ProcessRecord>>(); 1066 1067 /** 1068 * This is set if we had to do a delayed dexopt of an app before launching 1069 * it, to increase the ANR timeouts in that case. 1070 */ 1071 boolean mDidDexOpt; 1072 1073 /** 1074 * Set if the systemServer made a call to enterSafeMode. 1075 */ 1076 boolean mSafeMode; 1077 1078 String mDebugApp = null; 1079 boolean mWaitForDebugger = false; 1080 boolean mDebugTransient = false; 1081 String mOrigDebugApp = null; 1082 boolean mOrigWaitForDebugger = false; 1083 boolean mAlwaysFinishActivities = false; 1084 IActivityController mController = null; 1085 String mProfileApp = null; 1086 ProcessRecord mProfileProc = null; 1087 String mProfileFile; 1088 ParcelFileDescriptor mProfileFd; 1089 int mSamplingInterval = 0; 1090 boolean mAutoStopProfiler = false; 1091 int mProfileType = 0; 1092 String mOpenGlTraceApp = null; 1093 1094 static class ProcessChangeItem { 1095 static final int CHANGE_ACTIVITIES = 1<<0; 1096 static final int CHANGE_PROCESS_STATE = 1<<1; 1097 int changes; 1098 int uid; 1099 int pid; 1100 int processState; 1101 boolean foregroundActivities; 1102 } 1103 1104 final RemoteCallbackList<IProcessObserver> mProcessObservers 1105 = new RemoteCallbackList<IProcessObserver>(); 1106 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1107 1108 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1109 = new ArrayList<ProcessChangeItem>(); 1110 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1111 = new ArrayList<ProcessChangeItem>(); 1112 1113 /** 1114 * Runtime CPU use collection thread. This object's lock is used to 1115 * perform synchronization with the thread (notifying it to run). 1116 */ 1117 final Thread mProcessCpuThread; 1118 1119 /** 1120 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1121 * Must acquire this object's lock when accessing it. 1122 * NOTE: this lock will be held while doing long operations (trawling 1123 * through all processes in /proc), so it should never be acquired by 1124 * any critical paths such as when holding the main activity manager lock. 1125 */ 1126 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1127 MONITOR_THREAD_CPU_USAGE); 1128 final AtomicLong mLastCpuTime = new AtomicLong(0); 1129 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1130 1131 long mLastWriteTime = 0; 1132 1133 /** 1134 * Used to retain an update lock when the foreground activity is in 1135 * immersive mode. 1136 */ 1137 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1138 1139 /** 1140 * Set to true after the system has finished booting. 1141 */ 1142 boolean mBooted = false; 1143 1144 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1145 int mProcessLimitOverride = -1; 1146 1147 WindowManagerService mWindowManager; 1148 1149 final ActivityThread mSystemThread; 1150 1151 // Holds the current foreground user's id 1152 int mCurrentUserId = 0; 1153 // Holds the target user's id during a user switch 1154 int mTargetUserId = UserHandle.USER_NULL; 1155 // If there are multiple profiles for the current user, their ids are here 1156 // Currently only the primary user can have managed profiles 1157 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1158 1159 /** 1160 * Mapping from each known user ID to the profile group ID it is associated with. 1161 */ 1162 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1163 1164 private UserManagerService mUserManager; 1165 1166 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1167 final ProcessRecord mApp; 1168 final int mPid; 1169 final IApplicationThread mAppThread; 1170 1171 AppDeathRecipient(ProcessRecord app, int pid, 1172 IApplicationThread thread) { 1173 if (localLOGV) Slog.v( 1174 TAG, "New death recipient " + this 1175 + " for thread " + thread.asBinder()); 1176 mApp = app; 1177 mPid = pid; 1178 mAppThread = thread; 1179 } 1180 1181 @Override 1182 public void binderDied() { 1183 if (localLOGV) Slog.v( 1184 TAG, "Death received in " + this 1185 + " for thread " + mAppThread.asBinder()); 1186 synchronized(ActivityManagerService.this) { 1187 appDiedLocked(mApp, mPid, mAppThread); 1188 } 1189 } 1190 } 1191 1192 static final int SHOW_ERROR_MSG = 1; 1193 static final int SHOW_NOT_RESPONDING_MSG = 2; 1194 static final int SHOW_FACTORY_ERROR_MSG = 3; 1195 static final int UPDATE_CONFIGURATION_MSG = 4; 1196 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1197 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1198 static final int SERVICE_TIMEOUT_MSG = 12; 1199 static final int UPDATE_TIME_ZONE = 13; 1200 static final int SHOW_UID_ERROR_MSG = 14; 1201 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1202 static final int PROC_START_TIMEOUT_MSG = 20; 1203 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1204 static final int KILL_APPLICATION_MSG = 22; 1205 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1206 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1207 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1208 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1209 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1210 static final int CLEAR_DNS_CACHE_MSG = 28; 1211 static final int UPDATE_HTTP_PROXY_MSG = 29; 1212 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1213 static final int DISPATCH_PROCESSES_CHANGED = 31; 1214 static final int DISPATCH_PROCESS_DIED = 32; 1215 static final int REPORT_MEM_USAGE_MSG = 33; 1216 static final int REPORT_USER_SWITCH_MSG = 34; 1217 static final int CONTINUE_USER_SWITCH_MSG = 35; 1218 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1219 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1220 static final int PERSIST_URI_GRANTS_MSG = 38; 1221 static final int REQUEST_ALL_PSS_MSG = 39; 1222 static final int START_PROFILES_MSG = 40; 1223 static final int UPDATE_TIME = 41; 1224 static final int SYSTEM_USER_START_MSG = 42; 1225 static final int SYSTEM_USER_CURRENT_MSG = 43; 1226 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1227 static final int FINISH_BOOTING_MSG = 45; 1228 static final int START_USER_SWITCH_MSG = 46; 1229 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1230 static final int DISMISS_DIALOG_MSG = 48; 1231 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1232 1233 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1234 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1235 static final int FIRST_COMPAT_MODE_MSG = 300; 1236 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1237 1238 CompatModeDialog mCompatModeDialog; 1239 long mLastMemUsageReportTime = 0; 1240 1241 /** 1242 * Flag whether the current user is a "monkey", i.e. whether 1243 * the UI is driven by a UI automation tool. 1244 */ 1245 private boolean mUserIsMonkey; 1246 1247 /** Flag whether the device has a Recents UI */ 1248 boolean mHasRecents; 1249 1250 /** The dimensions of the thumbnails in the Recents UI. */ 1251 int mThumbnailWidth; 1252 int mThumbnailHeight; 1253 1254 final ServiceThread mHandlerThread; 1255 final MainHandler mHandler; 1256 1257 final class MainHandler extends Handler { 1258 public MainHandler(Looper looper) { 1259 super(looper, null, true); 1260 } 1261 1262 @Override 1263 public void handleMessage(Message msg) { 1264 switch (msg.what) { 1265 case SHOW_ERROR_MSG: { 1266 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1267 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1268 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1269 synchronized (ActivityManagerService.this) { 1270 ProcessRecord proc = (ProcessRecord)data.get("app"); 1271 AppErrorResult res = (AppErrorResult) data.get("result"); 1272 if (proc != null && proc.crashDialog != null) { 1273 Slog.e(TAG, "App already has crash dialog: " + proc); 1274 if (res != null) { 1275 res.set(0); 1276 } 1277 return; 1278 } 1279 boolean isBackground = (UserHandle.getAppId(proc.uid) 1280 >= Process.FIRST_APPLICATION_UID 1281 && proc.pid != MY_PID); 1282 for (int userId : mCurrentProfileIds) { 1283 isBackground &= (proc.userId != userId); 1284 } 1285 if (isBackground && !showBackground) { 1286 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1287 if (res != null) { 1288 res.set(0); 1289 } 1290 return; 1291 } 1292 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1293 Dialog d = new AppErrorDialog(mContext, 1294 ActivityManagerService.this, res, proc); 1295 d.show(); 1296 proc.crashDialog = d; 1297 } else { 1298 // The device is asleep, so just pretend that the user 1299 // saw a crash dialog and hit "force quit". 1300 if (res != null) { 1301 res.set(0); 1302 } 1303 } 1304 } 1305 1306 ensureBootCompleted(); 1307 } break; 1308 case SHOW_NOT_RESPONDING_MSG: { 1309 synchronized (ActivityManagerService.this) { 1310 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1311 ProcessRecord proc = (ProcessRecord)data.get("app"); 1312 if (proc != null && proc.anrDialog != null) { 1313 Slog.e(TAG, "App already has anr dialog: " + proc); 1314 return; 1315 } 1316 1317 Intent intent = new Intent("android.intent.action.ANR"); 1318 if (!mProcessesReady) { 1319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1320 | Intent.FLAG_RECEIVER_FOREGROUND); 1321 } 1322 broadcastIntentLocked(null, null, intent, 1323 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1324 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1325 1326 if (mShowDialogs) { 1327 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1328 mContext, proc, (ActivityRecord)data.get("activity"), 1329 msg.arg1 != 0); 1330 d.show(); 1331 proc.anrDialog = d; 1332 } else { 1333 // Just kill the app if there is no dialog to be shown. 1334 killAppAtUsersRequest(proc, null); 1335 } 1336 } 1337 1338 ensureBootCompleted(); 1339 } break; 1340 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1341 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1342 synchronized (ActivityManagerService.this) { 1343 ProcessRecord proc = (ProcessRecord) data.get("app"); 1344 if (proc == null) { 1345 Slog.e(TAG, "App not found when showing strict mode dialog."); 1346 break; 1347 } 1348 if (proc.crashDialog != null) { 1349 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1350 return; 1351 } 1352 AppErrorResult res = (AppErrorResult) data.get("result"); 1353 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1354 Dialog d = new StrictModeViolationDialog(mContext, 1355 ActivityManagerService.this, res, proc); 1356 d.show(); 1357 proc.crashDialog = d; 1358 } else { 1359 // The device is asleep, so just pretend that the user 1360 // saw a crash dialog and hit "force quit". 1361 res.set(0); 1362 } 1363 } 1364 ensureBootCompleted(); 1365 } break; 1366 case SHOW_FACTORY_ERROR_MSG: { 1367 Dialog d = new FactoryErrorDialog( 1368 mContext, msg.getData().getCharSequence("msg")); 1369 d.show(); 1370 ensureBootCompleted(); 1371 } break; 1372 case UPDATE_CONFIGURATION_MSG: { 1373 final ContentResolver resolver = mContext.getContentResolver(); 1374 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1375 } break; 1376 case GC_BACKGROUND_PROCESSES_MSG: { 1377 synchronized (ActivityManagerService.this) { 1378 performAppGcsIfAppropriateLocked(); 1379 } 1380 } break; 1381 case WAIT_FOR_DEBUGGER_MSG: { 1382 synchronized (ActivityManagerService.this) { 1383 ProcessRecord app = (ProcessRecord)msg.obj; 1384 if (msg.arg1 != 0) { 1385 if (!app.waitedForDebugger) { 1386 Dialog d = new AppWaitingForDebuggerDialog( 1387 ActivityManagerService.this, 1388 mContext, app); 1389 app.waitDialog = d; 1390 app.waitedForDebugger = true; 1391 d.show(); 1392 } 1393 } else { 1394 if (app.waitDialog != null) { 1395 app.waitDialog.dismiss(); 1396 app.waitDialog = null; 1397 } 1398 } 1399 } 1400 } break; 1401 case SERVICE_TIMEOUT_MSG: { 1402 if (mDidDexOpt) { 1403 mDidDexOpt = false; 1404 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1405 nmsg.obj = msg.obj; 1406 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1407 return; 1408 } 1409 mServices.serviceTimeout((ProcessRecord)msg.obj); 1410 } break; 1411 case UPDATE_TIME_ZONE: { 1412 synchronized (ActivityManagerService.this) { 1413 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1414 ProcessRecord r = mLruProcesses.get(i); 1415 if (r.thread != null) { 1416 try { 1417 r.thread.updateTimeZone(); 1418 } catch (RemoteException ex) { 1419 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1420 } 1421 } 1422 } 1423 } 1424 } break; 1425 case CLEAR_DNS_CACHE_MSG: { 1426 synchronized (ActivityManagerService.this) { 1427 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1428 ProcessRecord r = mLruProcesses.get(i); 1429 if (r.thread != null) { 1430 try { 1431 r.thread.clearDnsCache(); 1432 } catch (RemoteException ex) { 1433 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1434 } 1435 } 1436 } 1437 } 1438 } break; 1439 case UPDATE_HTTP_PROXY_MSG: { 1440 ProxyInfo proxy = (ProxyInfo)msg.obj; 1441 String host = ""; 1442 String port = ""; 1443 String exclList = ""; 1444 Uri pacFileUrl = Uri.EMPTY; 1445 if (proxy != null) { 1446 host = proxy.getHost(); 1447 port = Integer.toString(proxy.getPort()); 1448 exclList = proxy.getExclusionListAsString(); 1449 pacFileUrl = proxy.getPacFileUrl(); 1450 } 1451 synchronized (ActivityManagerService.this) { 1452 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1453 ProcessRecord r = mLruProcesses.get(i); 1454 if (r.thread != null) { 1455 try { 1456 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1457 } catch (RemoteException ex) { 1458 Slog.w(TAG, "Failed to update http proxy for: " + 1459 r.info.processName); 1460 } 1461 } 1462 } 1463 } 1464 } break; 1465 case SHOW_UID_ERROR_MSG: { 1466 if (mShowDialogs) { 1467 AlertDialog d = new BaseErrorDialog(mContext); 1468 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1469 d.setCancelable(false); 1470 d.setTitle(mContext.getText(R.string.android_system_label)); 1471 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1472 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1473 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1474 d.show(); 1475 } 1476 } break; 1477 case SHOW_FINGERPRINT_ERROR_MSG: { 1478 if (mShowDialogs) { 1479 AlertDialog d = new BaseErrorDialog(mContext); 1480 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1481 d.setCancelable(false); 1482 d.setTitle(mContext.getText(R.string.android_system_label)); 1483 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1484 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1485 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1486 d.show(); 1487 } 1488 } break; 1489 case PROC_START_TIMEOUT_MSG: { 1490 if (mDidDexOpt) { 1491 mDidDexOpt = false; 1492 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1493 nmsg.obj = msg.obj; 1494 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1495 return; 1496 } 1497 ProcessRecord app = (ProcessRecord)msg.obj; 1498 synchronized (ActivityManagerService.this) { 1499 processStartTimedOutLocked(app); 1500 } 1501 } break; 1502 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1503 synchronized (ActivityManagerService.this) { 1504 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1505 } 1506 } break; 1507 case KILL_APPLICATION_MSG: { 1508 synchronized (ActivityManagerService.this) { 1509 int appid = msg.arg1; 1510 boolean restart = (msg.arg2 == 1); 1511 Bundle bundle = (Bundle)msg.obj; 1512 String pkg = bundle.getString("pkg"); 1513 String reason = bundle.getString("reason"); 1514 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1515 false, UserHandle.USER_ALL, reason); 1516 } 1517 } break; 1518 case FINALIZE_PENDING_INTENT_MSG: { 1519 ((PendingIntentRecord)msg.obj).completeFinalize(); 1520 } break; 1521 case POST_HEAVY_NOTIFICATION_MSG: { 1522 INotificationManager inm = NotificationManager.getService(); 1523 if (inm == null) { 1524 return; 1525 } 1526 1527 ActivityRecord root = (ActivityRecord)msg.obj; 1528 ProcessRecord process = root.app; 1529 if (process == null) { 1530 return; 1531 } 1532 1533 try { 1534 Context context = mContext.createPackageContext(process.info.packageName, 0); 1535 String text = mContext.getString(R.string.heavy_weight_notification, 1536 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1537 Notification notification = new Notification(); 1538 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1539 notification.when = 0; 1540 notification.flags = Notification.FLAG_ONGOING_EVENT; 1541 notification.tickerText = text; 1542 notification.defaults = 0; // please be quiet 1543 notification.sound = null; 1544 notification.vibrate = null; 1545 notification.color = mContext.getResources().getColor( 1546 com.android.internal.R.color.system_notification_accent_color); 1547 notification.setLatestEventInfo(context, text, 1548 mContext.getText(R.string.heavy_weight_notification_detail), 1549 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1550 PendingIntent.FLAG_CANCEL_CURRENT, null, 1551 new UserHandle(root.userId))); 1552 1553 try { 1554 int[] outId = new int[1]; 1555 inm.enqueueNotificationWithTag("android", "android", null, 1556 R.string.heavy_weight_notification, 1557 notification, outId, root.userId); 1558 } catch (RuntimeException e) { 1559 Slog.w(ActivityManagerService.TAG, 1560 "Error showing notification for heavy-weight app", e); 1561 } catch (RemoteException e) { 1562 } 1563 } catch (NameNotFoundException e) { 1564 Slog.w(TAG, "Unable to create context for heavy notification", e); 1565 } 1566 } break; 1567 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1568 INotificationManager inm = NotificationManager.getService(); 1569 if (inm == null) { 1570 return; 1571 } 1572 try { 1573 inm.cancelNotificationWithTag("android", null, 1574 R.string.heavy_weight_notification, msg.arg1); 1575 } catch (RuntimeException e) { 1576 Slog.w(ActivityManagerService.TAG, 1577 "Error canceling notification for service", e); 1578 } catch (RemoteException e) { 1579 } 1580 } break; 1581 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1582 synchronized (ActivityManagerService.this) { 1583 checkExcessivePowerUsageLocked(true); 1584 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1585 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1586 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1587 } 1588 } break; 1589 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1590 synchronized (ActivityManagerService.this) { 1591 ActivityRecord ar = (ActivityRecord)msg.obj; 1592 if (mCompatModeDialog != null) { 1593 if (mCompatModeDialog.mAppInfo.packageName.equals( 1594 ar.info.applicationInfo.packageName)) { 1595 return; 1596 } 1597 mCompatModeDialog.dismiss(); 1598 mCompatModeDialog = null; 1599 } 1600 if (ar != null && false) { 1601 if (mCompatModePackages.getPackageAskCompatModeLocked( 1602 ar.packageName)) { 1603 int mode = mCompatModePackages.computeCompatModeLocked( 1604 ar.info.applicationInfo); 1605 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1606 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1607 mCompatModeDialog = new CompatModeDialog( 1608 ActivityManagerService.this, mContext, 1609 ar.info.applicationInfo); 1610 mCompatModeDialog.show(); 1611 } 1612 } 1613 } 1614 } 1615 break; 1616 } 1617 case DISPATCH_PROCESSES_CHANGED: { 1618 dispatchProcessesChanged(); 1619 break; 1620 } 1621 case DISPATCH_PROCESS_DIED: { 1622 final int pid = msg.arg1; 1623 final int uid = msg.arg2; 1624 dispatchProcessDied(pid, uid); 1625 break; 1626 } 1627 case REPORT_MEM_USAGE_MSG: { 1628 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1629 Thread thread = new Thread() { 1630 @Override public void run() { 1631 reportMemUsage(memInfos); 1632 } 1633 }; 1634 thread.start(); 1635 break; 1636 } 1637 case START_USER_SWITCH_MSG: { 1638 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1639 break; 1640 } 1641 case REPORT_USER_SWITCH_MSG: { 1642 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1643 break; 1644 } 1645 case CONTINUE_USER_SWITCH_MSG: { 1646 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1647 break; 1648 } 1649 case USER_SWITCH_TIMEOUT_MSG: { 1650 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1651 break; 1652 } 1653 case IMMERSIVE_MODE_LOCK_MSG: { 1654 final boolean nextState = (msg.arg1 != 0); 1655 if (mUpdateLock.isHeld() != nextState) { 1656 if (DEBUG_IMMERSIVE) { 1657 final ActivityRecord r = (ActivityRecord) msg.obj; 1658 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1659 } 1660 if (nextState) { 1661 mUpdateLock.acquire(); 1662 } else { 1663 mUpdateLock.release(); 1664 } 1665 } 1666 break; 1667 } 1668 case PERSIST_URI_GRANTS_MSG: { 1669 writeGrantedUriPermissions(); 1670 break; 1671 } 1672 case REQUEST_ALL_PSS_MSG: { 1673 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1674 break; 1675 } 1676 case START_PROFILES_MSG: { 1677 synchronized (ActivityManagerService.this) { 1678 startProfilesLocked(); 1679 } 1680 break; 1681 } 1682 case UPDATE_TIME: { 1683 synchronized (ActivityManagerService.this) { 1684 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1685 ProcessRecord r = mLruProcesses.get(i); 1686 if (r.thread != null) { 1687 try { 1688 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1689 } catch (RemoteException ex) { 1690 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1691 } 1692 } 1693 } 1694 } 1695 break; 1696 } 1697 case SYSTEM_USER_START_MSG: { 1698 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1699 Integer.toString(msg.arg1), msg.arg1); 1700 mSystemServiceManager.startUser(msg.arg1); 1701 break; 1702 } 1703 case SYSTEM_USER_CURRENT_MSG: { 1704 mBatteryStatsService.noteEvent( 1705 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1706 Integer.toString(msg.arg2), msg.arg2); 1707 mBatteryStatsService.noteEvent( 1708 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1709 Integer.toString(msg.arg1), msg.arg1); 1710 mSystemServiceManager.switchUser(msg.arg1); 1711 break; 1712 } 1713 case ENTER_ANIMATION_COMPLETE_MSG: { 1714 synchronized (ActivityManagerService.this) { 1715 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1716 if (r != null && r.app != null && r.app.thread != null) { 1717 try { 1718 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1719 } catch (RemoteException e) { 1720 } 1721 } 1722 } 1723 break; 1724 } 1725 case FINISH_BOOTING_MSG: { 1726 if (msg.arg1 != 0) { 1727 finishBooting(); 1728 } 1729 if (msg.arg2 != 0) { 1730 enableScreenAfterBoot(); 1731 } 1732 break; 1733 } 1734 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1735 try { 1736 Locale l = (Locale) msg.obj; 1737 IBinder service = ServiceManager.getService("mount"); 1738 IMountService mountService = IMountService.Stub.asInterface(service); 1739 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1740 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1741 } catch (RemoteException e) { 1742 Log.e(TAG, "Error storing locale for decryption UI", e); 1743 } 1744 break; 1745 } 1746 case DISMISS_DIALOG_MSG: { 1747 final Dialog d = (Dialog) msg.obj; 1748 d.dismiss(); 1749 break; 1750 } 1751 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1752 synchronized (ActivityManagerService.this) { 1753 int i = mTaskStackListeners.beginBroadcast(); 1754 while (i > 0) { 1755 i--; 1756 try { 1757 // Make a one-way callback to the listener 1758 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1759 } catch (RemoteException e){ 1760 // Handled by the RemoteCallbackList 1761 } 1762 } 1763 mTaskStackListeners.finishBroadcast(); 1764 } 1765 break; 1766 } 1767 } 1768 } 1769 }; 1770 1771 static final int COLLECT_PSS_BG_MSG = 1; 1772 1773 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1774 @Override 1775 public void handleMessage(Message msg) { 1776 switch (msg.what) { 1777 case COLLECT_PSS_BG_MSG: { 1778 long start = SystemClock.uptimeMillis(); 1779 MemInfoReader memInfo = null; 1780 synchronized (ActivityManagerService.this) { 1781 if (mFullPssPending) { 1782 mFullPssPending = false; 1783 memInfo = new MemInfoReader(); 1784 } 1785 } 1786 if (memInfo != null) { 1787 updateCpuStatsNow(); 1788 long nativeTotalPss = 0; 1789 synchronized (mProcessCpuTracker) { 1790 final int N = mProcessCpuTracker.countStats(); 1791 for (int j=0; j<N; j++) { 1792 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1793 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1794 // This is definitely an application process; skip it. 1795 continue; 1796 } 1797 synchronized (mPidsSelfLocked) { 1798 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1799 // This is one of our own processes; skip it. 1800 continue; 1801 } 1802 } 1803 nativeTotalPss += Debug.getPss(st.pid, null); 1804 } 1805 } 1806 memInfo.readMemInfo(); 1807 synchronized (ActivityManagerService.this) { 1808 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1809 + (SystemClock.uptimeMillis()-start) + "ms"); 1810 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1811 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1812 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1813 } 1814 } 1815 1816 int i = 0; 1817 int num = 0; 1818 long[] tmp = new long[1]; 1819 do { 1820 ProcessRecord proc; 1821 int procState; 1822 int pid; 1823 synchronized (ActivityManagerService.this) { 1824 if (i >= mPendingPssProcesses.size()) { 1825 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1826 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1827 mPendingPssProcesses.clear(); 1828 return; 1829 } 1830 proc = mPendingPssProcesses.get(i); 1831 procState = proc.pssProcState; 1832 if (proc.thread != null && procState == proc.setProcState) { 1833 pid = proc.pid; 1834 } else { 1835 proc = null; 1836 pid = 0; 1837 } 1838 i++; 1839 } 1840 if (proc != null) { 1841 long pss = Debug.getPss(pid, tmp); 1842 synchronized (ActivityManagerService.this) { 1843 if (proc.thread != null && proc.setProcState == procState 1844 && proc.pid == pid) { 1845 num++; 1846 proc.lastPssTime = SystemClock.uptimeMillis(); 1847 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1848 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1849 + ": " + pss + " lastPss=" + proc.lastPss 1850 + " state=" + ProcessList.makeProcStateString(procState)); 1851 if (proc.initialIdlePss == 0) { 1852 proc.initialIdlePss = pss; 1853 } 1854 proc.lastPss = pss; 1855 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1856 proc.lastCachedPss = pss; 1857 } 1858 } 1859 } 1860 } 1861 } while (true); 1862 } 1863 } 1864 } 1865 }; 1866 1867 public void setSystemProcess() { 1868 try { 1869 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1870 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1871 ServiceManager.addService("meminfo", new MemBinder(this)); 1872 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1873 ServiceManager.addService("dbinfo", new DbBinder(this)); 1874 if (MONITOR_CPU_USAGE) { 1875 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1876 } 1877 ServiceManager.addService("permission", new PermissionController(this)); 1878 1879 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1880 "android", STOCK_PM_FLAGS); 1881 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1882 1883 synchronized (this) { 1884 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1885 app.persistent = true; 1886 app.pid = MY_PID; 1887 app.maxAdj = ProcessList.SYSTEM_ADJ; 1888 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1889 mProcessNames.put(app.processName, app.uid, app); 1890 synchronized (mPidsSelfLocked) { 1891 mPidsSelfLocked.put(app.pid, app); 1892 } 1893 updateLruProcessLocked(app, false, null); 1894 updateOomAdjLocked(); 1895 } 1896 } catch (PackageManager.NameNotFoundException e) { 1897 throw new RuntimeException( 1898 "Unable to find android system package", e); 1899 } 1900 } 1901 1902 public void setWindowManager(WindowManagerService wm) { 1903 mWindowManager = wm; 1904 mStackSupervisor.setWindowManager(wm); 1905 } 1906 1907 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1908 mUsageStatsService = usageStatsManager; 1909 } 1910 1911 public void startObservingNativeCrashes() { 1912 final NativeCrashListener ncl = new NativeCrashListener(this); 1913 ncl.start(); 1914 } 1915 1916 public IAppOpsService getAppOpsService() { 1917 return mAppOpsService; 1918 } 1919 1920 static class MemBinder extends Binder { 1921 ActivityManagerService mActivityManagerService; 1922 MemBinder(ActivityManagerService activityManagerService) { 1923 mActivityManagerService = activityManagerService; 1924 } 1925 1926 @Override 1927 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1928 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1929 != PackageManager.PERMISSION_GRANTED) { 1930 pw.println("Permission Denial: can't dump meminfo from from pid=" 1931 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1932 + " without permission " + android.Manifest.permission.DUMP); 1933 return; 1934 } 1935 1936 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1937 } 1938 } 1939 1940 static class GraphicsBinder extends Binder { 1941 ActivityManagerService mActivityManagerService; 1942 GraphicsBinder(ActivityManagerService activityManagerService) { 1943 mActivityManagerService = activityManagerService; 1944 } 1945 1946 @Override 1947 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1948 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1949 != PackageManager.PERMISSION_GRANTED) { 1950 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1951 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1952 + " without permission " + android.Manifest.permission.DUMP); 1953 return; 1954 } 1955 1956 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1957 } 1958 } 1959 1960 static class DbBinder extends Binder { 1961 ActivityManagerService mActivityManagerService; 1962 DbBinder(ActivityManagerService activityManagerService) { 1963 mActivityManagerService = activityManagerService; 1964 } 1965 1966 @Override 1967 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1968 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1969 != PackageManager.PERMISSION_GRANTED) { 1970 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1971 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1972 + " without permission " + android.Manifest.permission.DUMP); 1973 return; 1974 } 1975 1976 mActivityManagerService.dumpDbInfo(fd, pw, args); 1977 } 1978 } 1979 1980 static class CpuBinder extends Binder { 1981 ActivityManagerService mActivityManagerService; 1982 CpuBinder(ActivityManagerService activityManagerService) { 1983 mActivityManagerService = activityManagerService; 1984 } 1985 1986 @Override 1987 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1988 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1989 != PackageManager.PERMISSION_GRANTED) { 1990 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1991 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1992 + " without permission " + android.Manifest.permission.DUMP); 1993 return; 1994 } 1995 1996 synchronized (mActivityManagerService.mProcessCpuTracker) { 1997 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1998 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1999 SystemClock.uptimeMillis())); 2000 } 2001 } 2002 } 2003 2004 public static final class Lifecycle extends SystemService { 2005 private final ActivityManagerService mService; 2006 2007 public Lifecycle(Context context) { 2008 super(context); 2009 mService = new ActivityManagerService(context); 2010 } 2011 2012 @Override 2013 public void onStart() { 2014 mService.start(); 2015 } 2016 2017 public ActivityManagerService getService() { 2018 return mService; 2019 } 2020 } 2021 2022 // Note: This method is invoked on the main thread but may need to attach various 2023 // handlers to other threads. So take care to be explicit about the looper. 2024 public ActivityManagerService(Context systemContext) { 2025 mContext = systemContext; 2026 mFactoryTest = FactoryTest.getMode(); 2027 mSystemThread = ActivityThread.currentActivityThread(); 2028 2029 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2030 2031 mHandlerThread = new ServiceThread(TAG, 2032 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2033 mHandlerThread.start(); 2034 mHandler = new MainHandler(mHandlerThread.getLooper()); 2035 2036 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2037 "foreground", BROADCAST_FG_TIMEOUT, false); 2038 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2039 "background", BROADCAST_BG_TIMEOUT, true); 2040 mBroadcastQueues[0] = mFgBroadcastQueue; 2041 mBroadcastQueues[1] = mBgBroadcastQueue; 2042 2043 mServices = new ActiveServices(this); 2044 mProviderMap = new ProviderMap(this); 2045 2046 // TODO: Move creation of battery stats service outside of activity manager service. 2047 File dataDir = Environment.getDataDirectory(); 2048 File systemDir = new File(dataDir, "system"); 2049 systemDir.mkdirs(); 2050 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2051 mBatteryStatsService.getActiveStatistics().readLocked(); 2052 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2053 mOnBattery = DEBUG_POWER ? true 2054 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2055 mBatteryStatsService.getActiveStatistics().setCallback(this); 2056 2057 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2058 2059 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2060 2061 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2062 2063 // User 0 is the first and only user that runs at boot. 2064 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2065 mUserLru.add(Integer.valueOf(0)); 2066 updateStartedUserArrayLocked(); 2067 2068 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2069 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2070 2071 mConfiguration.setToDefaults(); 2072 mConfiguration.setLocale(Locale.getDefault()); 2073 2074 mConfigurationSeq = mConfiguration.seq = 1; 2075 mProcessCpuTracker.init(); 2076 2077 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2078 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2079 mStackSupervisor = new ActivityStackSupervisor(this); 2080 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2081 2082 mProcessCpuThread = new Thread("CpuTracker") { 2083 @Override 2084 public void run() { 2085 while (true) { 2086 try { 2087 try { 2088 synchronized(this) { 2089 final long now = SystemClock.uptimeMillis(); 2090 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2091 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2092 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2093 // + ", write delay=" + nextWriteDelay); 2094 if (nextWriteDelay < nextCpuDelay) { 2095 nextCpuDelay = nextWriteDelay; 2096 } 2097 if (nextCpuDelay > 0) { 2098 mProcessCpuMutexFree.set(true); 2099 this.wait(nextCpuDelay); 2100 } 2101 } 2102 } catch (InterruptedException e) { 2103 } 2104 updateCpuStatsNow(); 2105 } catch (Exception e) { 2106 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2107 } 2108 } 2109 } 2110 }; 2111 2112 Watchdog.getInstance().addMonitor(this); 2113 Watchdog.getInstance().addThread(mHandler); 2114 } 2115 2116 public void setSystemServiceManager(SystemServiceManager mgr) { 2117 mSystemServiceManager = mgr; 2118 } 2119 2120 public void setInstaller(Installer installer) { 2121 mInstaller = installer; 2122 } 2123 2124 private void start() { 2125 Process.removeAllProcessGroups(); 2126 mProcessCpuThread.start(); 2127 2128 mBatteryStatsService.publish(mContext); 2129 mAppOpsService.publish(mContext); 2130 Slog.d("AppOps", "AppOpsService published"); 2131 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2132 } 2133 2134 public void initPowerManagement() { 2135 mStackSupervisor.initPowerManagement(); 2136 mBatteryStatsService.initPowerManagement(); 2137 } 2138 2139 @Override 2140 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2141 throws RemoteException { 2142 if (code == SYSPROPS_TRANSACTION) { 2143 // We need to tell all apps about the system property change. 2144 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2145 synchronized(this) { 2146 final int NP = mProcessNames.getMap().size(); 2147 for (int ip=0; ip<NP; ip++) { 2148 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2149 final int NA = apps.size(); 2150 for (int ia=0; ia<NA; ia++) { 2151 ProcessRecord app = apps.valueAt(ia); 2152 if (app.thread != null) { 2153 procs.add(app.thread.asBinder()); 2154 } 2155 } 2156 } 2157 } 2158 2159 int N = procs.size(); 2160 for (int i=0; i<N; i++) { 2161 Parcel data2 = Parcel.obtain(); 2162 try { 2163 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2164 } catch (RemoteException e) { 2165 } 2166 data2.recycle(); 2167 } 2168 } 2169 try { 2170 return super.onTransact(code, data, reply, flags); 2171 } catch (RuntimeException e) { 2172 // The activity manager only throws security exceptions, so let's 2173 // log all others. 2174 if (!(e instanceof SecurityException)) { 2175 Slog.wtf(TAG, "Activity Manager Crash", e); 2176 } 2177 throw e; 2178 } 2179 } 2180 2181 void updateCpuStats() { 2182 final long now = SystemClock.uptimeMillis(); 2183 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2184 return; 2185 } 2186 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2187 synchronized (mProcessCpuThread) { 2188 mProcessCpuThread.notify(); 2189 } 2190 } 2191 } 2192 2193 void updateCpuStatsNow() { 2194 synchronized (mProcessCpuTracker) { 2195 mProcessCpuMutexFree.set(false); 2196 final long now = SystemClock.uptimeMillis(); 2197 boolean haveNewCpuStats = false; 2198 2199 if (MONITOR_CPU_USAGE && 2200 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2201 mLastCpuTime.set(now); 2202 haveNewCpuStats = true; 2203 mProcessCpuTracker.update(); 2204 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2205 //Slog.i(TAG, "Total CPU usage: " 2206 // + mProcessCpu.getTotalCpuPercent() + "%"); 2207 2208 // Slog the cpu usage if the property is set. 2209 if ("true".equals(SystemProperties.get("events.cpu"))) { 2210 int user = mProcessCpuTracker.getLastUserTime(); 2211 int system = mProcessCpuTracker.getLastSystemTime(); 2212 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2213 int irq = mProcessCpuTracker.getLastIrqTime(); 2214 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2215 int idle = mProcessCpuTracker.getLastIdleTime(); 2216 2217 int total = user + system + iowait + irq + softIrq + idle; 2218 if (total == 0) total = 1; 2219 2220 EventLog.writeEvent(EventLogTags.CPU, 2221 ((user+system+iowait+irq+softIrq) * 100) / total, 2222 (user * 100) / total, 2223 (system * 100) / total, 2224 (iowait * 100) / total, 2225 (irq * 100) / total, 2226 (softIrq * 100) / total); 2227 } 2228 } 2229 2230 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2231 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2232 synchronized(bstats) { 2233 synchronized(mPidsSelfLocked) { 2234 if (haveNewCpuStats) { 2235 if (mOnBattery) { 2236 int perc = bstats.startAddingCpuLocked(); 2237 int totalUTime = 0; 2238 int totalSTime = 0; 2239 final int N = mProcessCpuTracker.countStats(); 2240 for (int i=0; i<N; i++) { 2241 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2242 if (!st.working) { 2243 continue; 2244 } 2245 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2246 int otherUTime = (st.rel_utime*perc)/100; 2247 int otherSTime = (st.rel_stime*perc)/100; 2248 totalUTime += otherUTime; 2249 totalSTime += otherSTime; 2250 if (pr != null) { 2251 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2252 if (ps == null || !ps.isActive()) { 2253 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2254 pr.info.uid, pr.processName); 2255 } 2256 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2257 st.rel_stime-otherSTime); 2258 ps.addSpeedStepTimes(cpuSpeedTimes); 2259 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2260 } else { 2261 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2262 if (ps == null || !ps.isActive()) { 2263 st.batteryStats = ps = bstats.getProcessStatsLocked( 2264 bstats.mapUid(st.uid), st.name); 2265 } 2266 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2267 st.rel_stime-otherSTime); 2268 ps.addSpeedStepTimes(cpuSpeedTimes); 2269 } 2270 } 2271 bstats.finishAddingCpuLocked(perc, totalUTime, 2272 totalSTime, cpuSpeedTimes); 2273 } 2274 } 2275 } 2276 2277 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2278 mLastWriteTime = now; 2279 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2280 } 2281 } 2282 } 2283 } 2284 2285 @Override 2286 public void batteryNeedsCpuUpdate() { 2287 updateCpuStatsNow(); 2288 } 2289 2290 @Override 2291 public void batteryPowerChanged(boolean onBattery) { 2292 // When plugging in, update the CPU stats first before changing 2293 // the plug state. 2294 updateCpuStatsNow(); 2295 synchronized (this) { 2296 synchronized(mPidsSelfLocked) { 2297 mOnBattery = DEBUG_POWER ? true : onBattery; 2298 } 2299 } 2300 } 2301 2302 /** 2303 * Initialize the application bind args. These are passed to each 2304 * process when the bindApplication() IPC is sent to the process. They're 2305 * lazily setup to make sure the services are running when they're asked for. 2306 */ 2307 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2308 if (mAppBindArgs == null) { 2309 mAppBindArgs = new HashMap<>(); 2310 2311 // Isolated processes won't get this optimization, so that we don't 2312 // violate the rules about which services they have access to. 2313 if (!isolated) { 2314 // Setup the application init args 2315 mAppBindArgs.put("package", ServiceManager.getService("package")); 2316 mAppBindArgs.put("window", ServiceManager.getService("window")); 2317 mAppBindArgs.put(Context.ALARM_SERVICE, 2318 ServiceManager.getService(Context.ALARM_SERVICE)); 2319 } 2320 } 2321 return mAppBindArgs; 2322 } 2323 2324 final void setFocusedActivityLocked(ActivityRecord r) { 2325 if (mFocusedActivity != r) { 2326 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2327 mFocusedActivity = r; 2328 if (r.task != null && r.task.voiceInteractor != null) { 2329 startRunningVoiceLocked(); 2330 } else { 2331 finishRunningVoiceLocked(); 2332 } 2333 mStackSupervisor.setFocusedStack(r); 2334 if (r != null) { 2335 mWindowManager.setFocusedApp(r.appToken, true); 2336 } 2337 applyUpdateLockStateLocked(r); 2338 } 2339 } 2340 2341 final void clearFocusedActivity(ActivityRecord r) { 2342 if (mFocusedActivity == r) { 2343 mFocusedActivity = null; 2344 } 2345 } 2346 2347 @Override 2348 public void setFocusedStack(int stackId) { 2349 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2350 synchronized (ActivityManagerService.this) { 2351 ActivityStack stack = mStackSupervisor.getStack(stackId); 2352 if (stack != null) { 2353 ActivityRecord r = stack.topRunningActivityLocked(null); 2354 if (r != null) { 2355 setFocusedActivityLocked(r); 2356 } 2357 } 2358 } 2359 } 2360 2361 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2362 @Override 2363 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2364 synchronized (ActivityManagerService.this) { 2365 if (listener != null) { 2366 mTaskStackListeners.register(listener); 2367 } 2368 } 2369 } 2370 2371 @Override 2372 public void notifyActivityDrawn(IBinder token) { 2373 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2374 synchronized (this) { 2375 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2376 if (r != null) { 2377 r.task.stack.notifyActivityDrawnLocked(r); 2378 } 2379 } 2380 } 2381 2382 final void applyUpdateLockStateLocked(ActivityRecord r) { 2383 // Modifications to the UpdateLock state are done on our handler, outside 2384 // the activity manager's locks. The new state is determined based on the 2385 // state *now* of the relevant activity record. The object is passed to 2386 // the handler solely for logging detail, not to be consulted/modified. 2387 final boolean nextState = r != null && r.immersive; 2388 mHandler.sendMessage( 2389 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2390 } 2391 2392 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2393 Message msg = Message.obtain(); 2394 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2395 msg.obj = r.task.askedCompatMode ? null : r; 2396 mHandler.sendMessage(msg); 2397 } 2398 2399 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2400 String what, Object obj, ProcessRecord srcApp) { 2401 app.lastActivityTime = now; 2402 2403 if (app.activities.size() > 0) { 2404 // Don't want to touch dependent processes that are hosting activities. 2405 return index; 2406 } 2407 2408 int lrui = mLruProcesses.lastIndexOf(app); 2409 if (lrui < 0) { 2410 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2411 + what + " " + obj + " from " + srcApp); 2412 return index; 2413 } 2414 2415 if (lrui >= index) { 2416 // Don't want to cause this to move dependent processes *back* in the 2417 // list as if they were less frequently used. 2418 return index; 2419 } 2420 2421 if (lrui >= mLruProcessActivityStart) { 2422 // Don't want to touch dependent processes that are hosting activities. 2423 return index; 2424 } 2425 2426 mLruProcesses.remove(lrui); 2427 if (index > 0) { 2428 index--; 2429 } 2430 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2431 + " in LRU list: " + app); 2432 mLruProcesses.add(index, app); 2433 return index; 2434 } 2435 2436 final void removeLruProcessLocked(ProcessRecord app) { 2437 int lrui = mLruProcesses.lastIndexOf(app); 2438 if (lrui >= 0) { 2439 if (!app.killed) { 2440 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2441 Process.killProcessQuiet(app.pid); 2442 Process.killProcessGroup(app.info.uid, app.pid); 2443 } 2444 if (lrui <= mLruProcessActivityStart) { 2445 mLruProcessActivityStart--; 2446 } 2447 if (lrui <= mLruProcessServiceStart) { 2448 mLruProcessServiceStart--; 2449 } 2450 mLruProcesses.remove(lrui); 2451 } 2452 } 2453 2454 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2455 ProcessRecord client) { 2456 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2457 || app.treatLikeActivity; 2458 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2459 if (!activityChange && hasActivity) { 2460 // The process has activities, so we are only allowing activity-based adjustments 2461 // to move it. It should be kept in the front of the list with other 2462 // processes that have activities, and we don't want those to change their 2463 // order except due to activity operations. 2464 return; 2465 } 2466 2467 mLruSeq++; 2468 final long now = SystemClock.uptimeMillis(); 2469 app.lastActivityTime = now; 2470 2471 // First a quick reject: if the app is already at the position we will 2472 // put it, then there is nothing to do. 2473 if (hasActivity) { 2474 final int N = mLruProcesses.size(); 2475 if (N > 0 && mLruProcesses.get(N-1) == app) { 2476 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2477 return; 2478 } 2479 } else { 2480 if (mLruProcessServiceStart > 0 2481 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2482 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2483 return; 2484 } 2485 } 2486 2487 int lrui = mLruProcesses.lastIndexOf(app); 2488 2489 if (app.persistent && lrui >= 0) { 2490 // We don't care about the position of persistent processes, as long as 2491 // they are in the list. 2492 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2493 return; 2494 } 2495 2496 /* In progress: compute new position first, so we can avoid doing work 2497 if the process is not actually going to move. Not yet working. 2498 int addIndex; 2499 int nextIndex; 2500 boolean inActivity = false, inService = false; 2501 if (hasActivity) { 2502 // Process has activities, put it at the very tipsy-top. 2503 addIndex = mLruProcesses.size(); 2504 nextIndex = mLruProcessServiceStart; 2505 inActivity = true; 2506 } else if (hasService) { 2507 // Process has services, put it at the top of the service list. 2508 addIndex = mLruProcessActivityStart; 2509 nextIndex = mLruProcessServiceStart; 2510 inActivity = true; 2511 inService = true; 2512 } else { 2513 // Process not otherwise of interest, it goes to the top of the non-service area. 2514 addIndex = mLruProcessServiceStart; 2515 if (client != null) { 2516 int clientIndex = mLruProcesses.lastIndexOf(client); 2517 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2518 + app); 2519 if (clientIndex >= 0 && addIndex > clientIndex) { 2520 addIndex = clientIndex; 2521 } 2522 } 2523 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2524 } 2525 2526 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2527 + mLruProcessActivityStart + "): " + app); 2528 */ 2529 2530 if (lrui >= 0) { 2531 if (lrui < mLruProcessActivityStart) { 2532 mLruProcessActivityStart--; 2533 } 2534 if (lrui < mLruProcessServiceStart) { 2535 mLruProcessServiceStart--; 2536 } 2537 /* 2538 if (addIndex > lrui) { 2539 addIndex--; 2540 } 2541 if (nextIndex > lrui) { 2542 nextIndex--; 2543 } 2544 */ 2545 mLruProcesses.remove(lrui); 2546 } 2547 2548 /* 2549 mLruProcesses.add(addIndex, app); 2550 if (inActivity) { 2551 mLruProcessActivityStart++; 2552 } 2553 if (inService) { 2554 mLruProcessActivityStart++; 2555 } 2556 */ 2557 2558 int nextIndex; 2559 if (hasActivity) { 2560 final int N = mLruProcesses.size(); 2561 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2562 // Process doesn't have activities, but has clients with 2563 // activities... move it up, but one below the top (the top 2564 // should always have a real activity). 2565 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2566 mLruProcesses.add(N-1, app); 2567 // To keep it from spamming the LRU list (by making a bunch of clients), 2568 // we will push down any other entries owned by the app. 2569 final int uid = app.info.uid; 2570 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2571 ProcessRecord subProc = mLruProcesses.get(i); 2572 if (subProc.info.uid == uid) { 2573 // We want to push this one down the list. If the process after 2574 // it is for the same uid, however, don't do so, because we don't 2575 // want them internally to be re-ordered. 2576 if (mLruProcesses.get(i-1).info.uid != uid) { 2577 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2578 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2579 ProcessRecord tmp = mLruProcesses.get(i); 2580 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2581 mLruProcesses.set(i-1, tmp); 2582 i--; 2583 } 2584 } else { 2585 // A gap, we can stop here. 2586 break; 2587 } 2588 } 2589 } else { 2590 // Process has activities, put it at the very tipsy-top. 2591 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2592 mLruProcesses.add(app); 2593 } 2594 nextIndex = mLruProcessServiceStart; 2595 } else if (hasService) { 2596 // Process has services, put it at the top of the service list. 2597 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2598 mLruProcesses.add(mLruProcessActivityStart, app); 2599 nextIndex = mLruProcessServiceStart; 2600 mLruProcessActivityStart++; 2601 } else { 2602 // Process not otherwise of interest, it goes to the top of the non-service area. 2603 int index = mLruProcessServiceStart; 2604 if (client != null) { 2605 // If there is a client, don't allow the process to be moved up higher 2606 // in the list than that client. 2607 int clientIndex = mLruProcesses.lastIndexOf(client); 2608 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2609 + " when updating " + app); 2610 if (clientIndex <= lrui) { 2611 // Don't allow the client index restriction to push it down farther in the 2612 // list than it already is. 2613 clientIndex = lrui; 2614 } 2615 if (clientIndex >= 0 && index > clientIndex) { 2616 index = clientIndex; 2617 } 2618 } 2619 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2620 mLruProcesses.add(index, app); 2621 nextIndex = index-1; 2622 mLruProcessActivityStart++; 2623 mLruProcessServiceStart++; 2624 } 2625 2626 // If the app is currently using a content provider or service, 2627 // bump those processes as well. 2628 for (int j=app.connections.size()-1; j>=0; j--) { 2629 ConnectionRecord cr = app.connections.valueAt(j); 2630 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2631 && cr.binding.service.app != null 2632 && cr.binding.service.app.lruSeq != mLruSeq 2633 && !cr.binding.service.app.persistent) { 2634 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2635 "service connection", cr, app); 2636 } 2637 } 2638 for (int j=app.conProviders.size()-1; j>=0; j--) { 2639 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2640 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2641 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2642 "provider reference", cpr, app); 2643 } 2644 } 2645 } 2646 2647 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2648 if (uid == Process.SYSTEM_UID) { 2649 // The system gets to run in any process. If there are multiple 2650 // processes with the same uid, just pick the first (this 2651 // should never happen). 2652 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2653 if (procs == null) return null; 2654 final int N = procs.size(); 2655 for (int i = 0; i < N; i++) { 2656 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2657 } 2658 } 2659 ProcessRecord proc = mProcessNames.get(processName, uid); 2660 if (false && proc != null && !keepIfLarge 2661 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2662 && proc.lastCachedPss >= 4000) { 2663 // Turn this condition on to cause killing to happen regularly, for testing. 2664 if (proc.baseProcessTracker != null) { 2665 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2666 } 2667 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2668 } else if (proc != null && !keepIfLarge 2669 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2670 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2671 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2672 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2673 if (proc.baseProcessTracker != null) { 2674 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2675 } 2676 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2677 } 2678 } 2679 return proc; 2680 } 2681 2682 void ensurePackageDexOpt(String packageName) { 2683 IPackageManager pm = AppGlobals.getPackageManager(); 2684 try { 2685 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2686 mDidDexOpt = true; 2687 } 2688 } catch (RemoteException e) { 2689 } 2690 } 2691 2692 boolean isNextTransitionForward() { 2693 int transit = mWindowManager.getPendingAppTransition(); 2694 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2695 || transit == AppTransition.TRANSIT_TASK_OPEN 2696 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2697 } 2698 2699 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2700 String processName, String abiOverride, int uid, Runnable crashHandler) { 2701 synchronized(this) { 2702 ApplicationInfo info = new ApplicationInfo(); 2703 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2704 // For isolated processes, the former contains the parent's uid and the latter the 2705 // actual uid of the isolated process. 2706 // In the special case introduced by this method (which is, starting an isolated 2707 // process directly from the SystemServer without an actual parent app process) the 2708 // closest thing to a parent's uid is SYSTEM_UID. 2709 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2710 // the |isolated| logic in the ProcessRecord constructor. 2711 info.uid = Process.SYSTEM_UID; 2712 info.processName = processName; 2713 info.className = entryPoint; 2714 info.packageName = "android"; 2715 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2716 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2717 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2718 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2719 crashHandler); 2720 return proc != null ? proc.pid : 0; 2721 } 2722 } 2723 2724 final ProcessRecord startProcessLocked(String processName, 2725 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2726 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2727 boolean isolated, boolean keepIfLarge) { 2728 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2729 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2730 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2731 null /* crashHandler */); 2732 } 2733 2734 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2735 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2736 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2737 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2738 long startTime = SystemClock.elapsedRealtime(); 2739 ProcessRecord app; 2740 if (!isolated) { 2741 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2742 checkTime(startTime, "startProcess: after getProcessRecord"); 2743 } else { 2744 // If this is an isolated process, it can't re-use an existing process. 2745 app = null; 2746 } 2747 // We don't have to do anything more if: 2748 // (1) There is an existing application record; and 2749 // (2) The caller doesn't think it is dead, OR there is no thread 2750 // object attached to it so we know it couldn't have crashed; and 2751 // (3) There is a pid assigned to it, so it is either starting or 2752 // already running. 2753 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2754 + " app=" + app + " knownToBeDead=" + knownToBeDead 2755 + " thread=" + (app != null ? app.thread : null) 2756 + " pid=" + (app != null ? app.pid : -1)); 2757 if (app != null && app.pid > 0) { 2758 if (!knownToBeDead || app.thread == null) { 2759 // We already have the app running, or are waiting for it to 2760 // come up (we have a pid but not yet its thread), so keep it. 2761 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2762 // If this is a new package in the process, add the package to the list 2763 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2764 checkTime(startTime, "startProcess: done, added package to proc"); 2765 return app; 2766 } 2767 2768 // An application record is attached to a previous process, 2769 // clean it up now. 2770 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2771 checkTime(startTime, "startProcess: bad proc running, killing"); 2772 Process.killProcessGroup(app.info.uid, app.pid); 2773 handleAppDiedLocked(app, true, true); 2774 checkTime(startTime, "startProcess: done killing old proc"); 2775 } 2776 2777 String hostingNameStr = hostingName != null 2778 ? hostingName.flattenToShortString() : null; 2779 2780 if (!isolated) { 2781 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2782 // If we are in the background, then check to see if this process 2783 // is bad. If so, we will just silently fail. 2784 if (mBadProcesses.get(info.processName, info.uid) != null) { 2785 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2786 + "/" + info.processName); 2787 return null; 2788 } 2789 } else { 2790 // When the user is explicitly starting a process, then clear its 2791 // crash count so that we won't make it bad until they see at 2792 // least one crash dialog again, and make the process good again 2793 // if it had been bad. 2794 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2795 + "/" + info.processName); 2796 mProcessCrashTimes.remove(info.processName, info.uid); 2797 if (mBadProcesses.get(info.processName, info.uid) != null) { 2798 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2799 UserHandle.getUserId(info.uid), info.uid, 2800 info.processName); 2801 mBadProcesses.remove(info.processName, info.uid); 2802 if (app != null) { 2803 app.bad = false; 2804 } 2805 } 2806 } 2807 } 2808 2809 if (app == null) { 2810 checkTime(startTime, "startProcess: creating new process record"); 2811 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2812 app.crashHandler = crashHandler; 2813 if (app == null) { 2814 Slog.w(TAG, "Failed making new process record for " 2815 + processName + "/" + info.uid + " isolated=" + isolated); 2816 return null; 2817 } 2818 mProcessNames.put(processName, app.uid, app); 2819 if (isolated) { 2820 mIsolatedProcesses.put(app.uid, app); 2821 } 2822 checkTime(startTime, "startProcess: done creating new process record"); 2823 } else { 2824 // If this is a new package in the process, add the package to the list 2825 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2826 checkTime(startTime, "startProcess: added package to existing proc"); 2827 } 2828 2829 // If the system is not ready yet, then hold off on starting this 2830 // process until it is. 2831 if (!mProcessesReady 2832 && !isAllowedWhileBooting(info) 2833 && !allowWhileBooting) { 2834 if (!mProcessesOnHold.contains(app)) { 2835 mProcessesOnHold.add(app); 2836 } 2837 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2838 checkTime(startTime, "startProcess: returning with proc on hold"); 2839 return app; 2840 } 2841 2842 checkTime(startTime, "startProcess: stepping in to startProcess"); 2843 startProcessLocked( 2844 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2845 checkTime(startTime, "startProcess: done starting proc!"); 2846 return (app.pid != 0) ? app : null; 2847 } 2848 2849 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2850 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2851 } 2852 2853 private final void startProcessLocked(ProcessRecord app, 2854 String hostingType, String hostingNameStr) { 2855 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2856 null /* entryPoint */, null /* entryPointArgs */); 2857 } 2858 2859 private final void startProcessLocked(ProcessRecord app, String hostingType, 2860 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2861 long startTime = SystemClock.elapsedRealtime(); 2862 if (app.pid > 0 && app.pid != MY_PID) { 2863 checkTime(startTime, "startProcess: removing from pids map"); 2864 synchronized (mPidsSelfLocked) { 2865 mPidsSelfLocked.remove(app.pid); 2866 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2867 } 2868 checkTime(startTime, "startProcess: done removing from pids map"); 2869 app.setPid(0); 2870 } 2871 2872 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2873 "startProcessLocked removing on hold: " + app); 2874 mProcessesOnHold.remove(app); 2875 2876 checkTime(startTime, "startProcess: starting to update cpu stats"); 2877 updateCpuStats(); 2878 checkTime(startTime, "startProcess: done updating cpu stats"); 2879 2880 try { 2881 int uid = app.uid; 2882 2883 int[] gids = null; 2884 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2885 if (!app.isolated) { 2886 int[] permGids = null; 2887 try { 2888 checkTime(startTime, "startProcess: getting gids from package manager"); 2889 final PackageManager pm = mContext.getPackageManager(); 2890 permGids = pm.getPackageGids(app.info.packageName); 2891 2892 if (Environment.isExternalStorageEmulated()) { 2893 checkTime(startTime, "startProcess: checking external storage perm"); 2894 if (pm.checkPermission( 2895 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2896 app.info.packageName) == PERMISSION_GRANTED) { 2897 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2898 } else { 2899 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2900 } 2901 } 2902 } catch (PackageManager.NameNotFoundException e) { 2903 Slog.w(TAG, "Unable to retrieve gids", e); 2904 } 2905 2906 /* 2907 * Add shared application and profile GIDs so applications can share some 2908 * resources like shared libraries and access user-wide resources 2909 */ 2910 if (permGids == null) { 2911 gids = new int[2]; 2912 } else { 2913 gids = new int[permGids.length + 2]; 2914 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2915 } 2916 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2917 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2918 } 2919 checkTime(startTime, "startProcess: building args"); 2920 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2921 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2922 && mTopComponent != null 2923 && app.processName.equals(mTopComponent.getPackageName())) { 2924 uid = 0; 2925 } 2926 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2927 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2928 uid = 0; 2929 } 2930 } 2931 int debugFlags = 0; 2932 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2933 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2934 // Also turn on CheckJNI for debuggable apps. It's quite 2935 // awkward to turn on otherwise. 2936 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2937 } 2938 // Run the app in safe mode if its manifest requests so or the 2939 // system is booted in safe mode. 2940 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2941 mSafeMode == true) { 2942 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2943 } 2944 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2945 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2946 } 2947 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2948 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2949 } 2950 if ("1".equals(SystemProperties.get("debug.assert"))) { 2951 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2952 } 2953 2954 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2955 if (requiredAbi == null) { 2956 requiredAbi = Build.SUPPORTED_ABIS[0]; 2957 } 2958 2959 String instructionSet = null; 2960 if (app.info.primaryCpuAbi != null) { 2961 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2962 } 2963 2964 // Start the process. It will either succeed and return a result containing 2965 // the PID of the new process, or else throw a RuntimeException. 2966 boolean isActivityProcess = (entryPoint == null); 2967 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2968 checkTime(startTime, "startProcess: asking zygote to start proc"); 2969 Process.ProcessStartResult startResult = Process.start(entryPoint, 2970 app.processName, uid, uid, gids, debugFlags, mountExternal, 2971 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2972 app.info.dataDir, entryPointArgs); 2973 checkTime(startTime, "startProcess: returned from zygote!"); 2974 2975 if (app.isolated) { 2976 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2977 } 2978 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2979 checkTime(startTime, "startProcess: done updating battery stats"); 2980 2981 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2982 UserHandle.getUserId(uid), startResult.pid, uid, 2983 app.processName, hostingType, 2984 hostingNameStr != null ? hostingNameStr : ""); 2985 2986 if (app.persistent) { 2987 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2988 } 2989 2990 checkTime(startTime, "startProcess: building log message"); 2991 StringBuilder buf = mStringBuilder; 2992 buf.setLength(0); 2993 buf.append("Start proc "); 2994 buf.append(app.processName); 2995 if (!isActivityProcess) { 2996 buf.append(" ["); 2997 buf.append(entryPoint); 2998 buf.append("]"); 2999 } 3000 buf.append(" for "); 3001 buf.append(hostingType); 3002 if (hostingNameStr != null) { 3003 buf.append(" "); 3004 buf.append(hostingNameStr); 3005 } 3006 buf.append(": pid="); 3007 buf.append(startResult.pid); 3008 buf.append(" uid="); 3009 buf.append(uid); 3010 buf.append(" gids={"); 3011 if (gids != null) { 3012 for (int gi=0; gi<gids.length; gi++) { 3013 if (gi != 0) buf.append(", "); 3014 buf.append(gids[gi]); 3015 3016 } 3017 } 3018 buf.append("}"); 3019 if (requiredAbi != null) { 3020 buf.append(" abi="); 3021 buf.append(requiredAbi); 3022 } 3023 Slog.i(TAG, buf.toString()); 3024 app.setPid(startResult.pid); 3025 app.usingWrapper = startResult.usingWrapper; 3026 app.removed = false; 3027 app.killed = false; 3028 app.killedByAm = false; 3029 checkTime(startTime, "startProcess: starting to update pids map"); 3030 synchronized (mPidsSelfLocked) { 3031 this.mPidsSelfLocked.put(startResult.pid, app); 3032 if (isActivityProcess) { 3033 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3034 msg.obj = app; 3035 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3036 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3037 } 3038 } 3039 checkTime(startTime, "startProcess: done updating pids map"); 3040 } catch (RuntimeException e) { 3041 // XXX do better error recovery. 3042 app.setPid(0); 3043 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3044 if (app.isolated) { 3045 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3046 } 3047 Slog.e(TAG, "Failure starting process " + app.processName, e); 3048 } 3049 } 3050 3051 void updateUsageStats(ActivityRecord component, boolean resumed) { 3052 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3053 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3054 if (resumed) { 3055 if (mUsageStatsService != null) { 3056 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3057 UsageEvents.Event.MOVE_TO_FOREGROUND); 3058 } 3059 synchronized (stats) { 3060 stats.noteActivityResumedLocked(component.app.uid); 3061 } 3062 } else { 3063 if (mUsageStatsService != null) { 3064 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3065 UsageEvents.Event.MOVE_TO_BACKGROUND); 3066 } 3067 synchronized (stats) { 3068 stats.noteActivityPausedLocked(component.app.uid); 3069 } 3070 } 3071 } 3072 3073 Intent getHomeIntent() { 3074 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3075 intent.setComponent(mTopComponent); 3076 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3077 intent.addCategory(Intent.CATEGORY_HOME); 3078 } 3079 return intent; 3080 } 3081 3082 boolean startHomeActivityLocked(int userId) { 3083 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3084 && mTopAction == null) { 3085 // We are running in factory test mode, but unable to find 3086 // the factory test app, so just sit around displaying the 3087 // error message and don't try to start anything. 3088 return false; 3089 } 3090 Intent intent = getHomeIntent(); 3091 ActivityInfo aInfo = 3092 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3093 if (aInfo != null) { 3094 intent.setComponent(new ComponentName( 3095 aInfo.applicationInfo.packageName, aInfo.name)); 3096 // Don't do this if the home app is currently being 3097 // instrumented. 3098 aInfo = new ActivityInfo(aInfo); 3099 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3100 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3101 aInfo.applicationInfo.uid, true); 3102 if (app == null || app.instrumentationClass == null) { 3103 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3104 mStackSupervisor.startHomeActivity(intent, aInfo); 3105 } 3106 } 3107 3108 return true; 3109 } 3110 3111 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3112 ActivityInfo ai = null; 3113 ComponentName comp = intent.getComponent(); 3114 try { 3115 if (comp != null) { 3116 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3117 } else { 3118 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3119 intent, 3120 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3121 flags, userId); 3122 3123 if (info != null) { 3124 ai = info.activityInfo; 3125 } 3126 } 3127 } catch (RemoteException e) { 3128 // ignore 3129 } 3130 3131 return ai; 3132 } 3133 3134 /** 3135 * Starts the "new version setup screen" if appropriate. 3136 */ 3137 void startSetupActivityLocked() { 3138 // Only do this once per boot. 3139 if (mCheckedForSetup) { 3140 return; 3141 } 3142 3143 // We will show this screen if the current one is a different 3144 // version than the last one shown, and we are not running in 3145 // low-level factory test mode. 3146 final ContentResolver resolver = mContext.getContentResolver(); 3147 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3148 Settings.Global.getInt(resolver, 3149 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3150 mCheckedForSetup = true; 3151 3152 // See if we should be showing the platform update setup UI. 3153 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3154 List<ResolveInfo> ris = mContext.getPackageManager() 3155 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3156 3157 // We don't allow third party apps to replace this. 3158 ResolveInfo ri = null; 3159 for (int i=0; ris != null && i<ris.size(); i++) { 3160 if ((ris.get(i).activityInfo.applicationInfo.flags 3161 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3162 ri = ris.get(i); 3163 break; 3164 } 3165 } 3166 3167 if (ri != null) { 3168 String vers = ri.activityInfo.metaData != null 3169 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3170 : null; 3171 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3172 vers = ri.activityInfo.applicationInfo.metaData.getString( 3173 Intent.METADATA_SETUP_VERSION); 3174 } 3175 String lastVers = Settings.Secure.getString( 3176 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3177 if (vers != null && !vers.equals(lastVers)) { 3178 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3179 intent.setComponent(new ComponentName( 3180 ri.activityInfo.packageName, ri.activityInfo.name)); 3181 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3182 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3183 null); 3184 } 3185 } 3186 } 3187 } 3188 3189 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3190 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3191 } 3192 3193 void enforceNotIsolatedCaller(String caller) { 3194 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3195 throw new SecurityException("Isolated process not allowed to call " + caller); 3196 } 3197 } 3198 3199 void enforceShellRestriction(String restriction, int userHandle) { 3200 if (Binder.getCallingUid() == Process.SHELL_UID) { 3201 if (userHandle < 0 3202 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3203 throw new SecurityException("Shell does not have permission to access user " 3204 + userHandle); 3205 } 3206 } 3207 } 3208 3209 @Override 3210 public int getFrontActivityScreenCompatMode() { 3211 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3212 synchronized (this) { 3213 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3214 } 3215 } 3216 3217 @Override 3218 public void setFrontActivityScreenCompatMode(int mode) { 3219 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3220 "setFrontActivityScreenCompatMode"); 3221 synchronized (this) { 3222 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3223 } 3224 } 3225 3226 @Override 3227 public int getPackageScreenCompatMode(String packageName) { 3228 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3229 synchronized (this) { 3230 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3231 } 3232 } 3233 3234 @Override 3235 public void setPackageScreenCompatMode(String packageName, int mode) { 3236 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3237 "setPackageScreenCompatMode"); 3238 synchronized (this) { 3239 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3240 } 3241 } 3242 3243 @Override 3244 public boolean getPackageAskScreenCompat(String packageName) { 3245 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3246 synchronized (this) { 3247 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3248 } 3249 } 3250 3251 @Override 3252 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3253 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3254 "setPackageAskScreenCompat"); 3255 synchronized (this) { 3256 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3257 } 3258 } 3259 3260 private void dispatchProcessesChanged() { 3261 int N; 3262 synchronized (this) { 3263 N = mPendingProcessChanges.size(); 3264 if (mActiveProcessChanges.length < N) { 3265 mActiveProcessChanges = new ProcessChangeItem[N]; 3266 } 3267 mPendingProcessChanges.toArray(mActiveProcessChanges); 3268 mAvailProcessChanges.addAll(mPendingProcessChanges); 3269 mPendingProcessChanges.clear(); 3270 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3271 } 3272 3273 int i = mProcessObservers.beginBroadcast(); 3274 while (i > 0) { 3275 i--; 3276 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3277 if (observer != null) { 3278 try { 3279 for (int j=0; j<N; j++) { 3280 ProcessChangeItem item = mActiveProcessChanges[j]; 3281 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3282 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3283 + item.pid + " uid=" + item.uid + ": " 3284 + item.foregroundActivities); 3285 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3286 item.foregroundActivities); 3287 } 3288 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3289 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3290 + item.pid + " uid=" + item.uid + ": " + item.processState); 3291 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3292 } 3293 } 3294 } catch (RemoteException e) { 3295 } 3296 } 3297 } 3298 mProcessObservers.finishBroadcast(); 3299 } 3300 3301 private void dispatchProcessDied(int pid, int uid) { 3302 int i = mProcessObservers.beginBroadcast(); 3303 while (i > 0) { 3304 i--; 3305 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3306 if (observer != null) { 3307 try { 3308 observer.onProcessDied(pid, uid); 3309 } catch (RemoteException e) { 3310 } 3311 } 3312 } 3313 mProcessObservers.finishBroadcast(); 3314 } 3315 3316 @Override 3317 public final int startActivity(IApplicationThread caller, String callingPackage, 3318 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3319 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3320 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3321 resultWho, requestCode, startFlags, profilerInfo, options, 3322 UserHandle.getCallingUserId()); 3323 } 3324 3325 @Override 3326 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3327 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3328 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3329 enforceNotIsolatedCaller("startActivity"); 3330 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3331 false, ALLOW_FULL_ONLY, "startActivity", null); 3332 // TODO: Switch to user app stacks here. 3333 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3334 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3335 profilerInfo, null, null, options, userId, null, null); 3336 } 3337 3338 @Override 3339 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3340 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3341 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3342 3343 // This is very dangerous -- it allows you to perform a start activity (including 3344 // permission grants) as any app that may launch one of your own activities. So 3345 // we will only allow this to be done from activities that are part of the core framework, 3346 // and then only when they are running as the system. 3347 final ActivityRecord sourceRecord; 3348 final int targetUid; 3349 final String targetPackage; 3350 synchronized (this) { 3351 if (resultTo == null) { 3352 throw new SecurityException("Must be called from an activity"); 3353 } 3354 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3355 if (sourceRecord == null) { 3356 throw new SecurityException("Called with bad activity token: " + resultTo); 3357 } 3358 if (!sourceRecord.info.packageName.equals("android")) { 3359 throw new SecurityException( 3360 "Must be called from an activity that is declared in the android package"); 3361 } 3362 if (sourceRecord.app == null) { 3363 throw new SecurityException("Called without a process attached to activity"); 3364 } 3365 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3366 // This is still okay, as long as this activity is running under the 3367 // uid of the original calling activity. 3368 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3369 throw new SecurityException( 3370 "Calling activity in uid " + sourceRecord.app.uid 3371 + " must be system uid or original calling uid " 3372 + sourceRecord.launchedFromUid); 3373 } 3374 } 3375 targetUid = sourceRecord.launchedFromUid; 3376 targetPackage = sourceRecord.launchedFromPackage; 3377 } 3378 3379 if (userId == UserHandle.USER_NULL) { 3380 userId = UserHandle.getUserId(sourceRecord.app.uid); 3381 } 3382 3383 // TODO: Switch to user app stacks here. 3384 try { 3385 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3386 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3387 null, null, options, userId, null, null); 3388 return ret; 3389 } catch (SecurityException e) { 3390 // XXX need to figure out how to propagate to original app. 3391 // A SecurityException here is generally actually a fault of the original 3392 // calling activity (such as a fairly granting permissions), so propagate it 3393 // back to them. 3394 /* 3395 StringBuilder msg = new StringBuilder(); 3396 msg.append("While launching"); 3397 msg.append(intent.toString()); 3398 msg.append(": "); 3399 msg.append(e.getMessage()); 3400 */ 3401 throw e; 3402 } 3403 } 3404 3405 @Override 3406 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3407 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3408 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3409 enforceNotIsolatedCaller("startActivityAndWait"); 3410 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3411 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3412 WaitResult res = new WaitResult(); 3413 // TODO: Switch to user app stacks here. 3414 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3415 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3416 options, userId, null, null); 3417 return res; 3418 } 3419 3420 @Override 3421 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3422 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3423 int startFlags, Configuration config, Bundle options, int userId) { 3424 enforceNotIsolatedCaller("startActivityWithConfig"); 3425 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3426 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3427 // TODO: Switch to user app stacks here. 3428 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3429 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3430 null, null, config, options, userId, null, null); 3431 return ret; 3432 } 3433 3434 @Override 3435 public int startActivityIntentSender(IApplicationThread caller, 3436 IntentSender intent, Intent fillInIntent, String resolvedType, 3437 IBinder resultTo, String resultWho, int requestCode, 3438 int flagsMask, int flagsValues, Bundle options) { 3439 enforceNotIsolatedCaller("startActivityIntentSender"); 3440 // Refuse possible leaked file descriptors 3441 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3442 throw new IllegalArgumentException("File descriptors passed in Intent"); 3443 } 3444 3445 IIntentSender sender = intent.getTarget(); 3446 if (!(sender instanceof PendingIntentRecord)) { 3447 throw new IllegalArgumentException("Bad PendingIntent object"); 3448 } 3449 3450 PendingIntentRecord pir = (PendingIntentRecord)sender; 3451 3452 synchronized (this) { 3453 // If this is coming from the currently resumed activity, it is 3454 // effectively saying that app switches are allowed at this point. 3455 final ActivityStack stack = getFocusedStack(); 3456 if (stack.mResumedActivity != null && 3457 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3458 mAppSwitchesAllowedTime = 0; 3459 } 3460 } 3461 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3462 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3463 return ret; 3464 } 3465 3466 @Override 3467 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3468 Intent intent, String resolvedType, IVoiceInteractionSession session, 3469 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3470 Bundle options, int userId) { 3471 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3472 != PackageManager.PERMISSION_GRANTED) { 3473 String msg = "Permission Denial: startVoiceActivity() from pid=" 3474 + Binder.getCallingPid() 3475 + ", uid=" + Binder.getCallingUid() 3476 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3477 Slog.w(TAG, msg); 3478 throw new SecurityException(msg); 3479 } 3480 if (session == null || interactor == null) { 3481 throw new NullPointerException("null session or interactor"); 3482 } 3483 userId = handleIncomingUser(callingPid, callingUid, userId, 3484 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3485 // TODO: Switch to user app stacks here. 3486 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3487 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3488 null, options, userId, null, null); 3489 } 3490 3491 @Override 3492 public boolean startNextMatchingActivity(IBinder callingActivity, 3493 Intent intent, Bundle options) { 3494 // Refuse possible leaked file descriptors 3495 if (intent != null && intent.hasFileDescriptors() == true) { 3496 throw new IllegalArgumentException("File descriptors passed in Intent"); 3497 } 3498 3499 synchronized (this) { 3500 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3501 if (r == null) { 3502 ActivityOptions.abort(options); 3503 return false; 3504 } 3505 if (r.app == null || r.app.thread == null) { 3506 // The caller is not running... d'oh! 3507 ActivityOptions.abort(options); 3508 return false; 3509 } 3510 intent = new Intent(intent); 3511 // The caller is not allowed to change the data. 3512 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3513 // And we are resetting to find the next component... 3514 intent.setComponent(null); 3515 3516 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3517 3518 ActivityInfo aInfo = null; 3519 try { 3520 List<ResolveInfo> resolves = 3521 AppGlobals.getPackageManager().queryIntentActivities( 3522 intent, r.resolvedType, 3523 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3524 UserHandle.getCallingUserId()); 3525 3526 // Look for the original activity in the list... 3527 final int N = resolves != null ? resolves.size() : 0; 3528 for (int i=0; i<N; i++) { 3529 ResolveInfo rInfo = resolves.get(i); 3530 if (rInfo.activityInfo.packageName.equals(r.packageName) 3531 && rInfo.activityInfo.name.equals(r.info.name)) { 3532 // We found the current one... the next matching is 3533 // after it. 3534 i++; 3535 if (i<N) { 3536 aInfo = resolves.get(i).activityInfo; 3537 } 3538 if (debug) { 3539 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3540 + "/" + r.info.name); 3541 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3542 + "/" + aInfo.name); 3543 } 3544 break; 3545 } 3546 } 3547 } catch (RemoteException e) { 3548 } 3549 3550 if (aInfo == null) { 3551 // Nobody who is next! 3552 ActivityOptions.abort(options); 3553 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3554 return false; 3555 } 3556 3557 intent.setComponent(new ComponentName( 3558 aInfo.applicationInfo.packageName, aInfo.name)); 3559 intent.setFlags(intent.getFlags()&~( 3560 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3561 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3562 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3563 Intent.FLAG_ACTIVITY_NEW_TASK)); 3564 3565 // Okay now we need to start the new activity, replacing the 3566 // currently running activity. This is a little tricky because 3567 // we want to start the new one as if the current one is finished, 3568 // but not finish the current one first so that there is no flicker. 3569 // And thus... 3570 final boolean wasFinishing = r.finishing; 3571 r.finishing = true; 3572 3573 // Propagate reply information over to the new activity. 3574 final ActivityRecord resultTo = r.resultTo; 3575 final String resultWho = r.resultWho; 3576 final int requestCode = r.requestCode; 3577 r.resultTo = null; 3578 if (resultTo != null) { 3579 resultTo.removeResultsLocked(r, resultWho, requestCode); 3580 } 3581 3582 final long origId = Binder.clearCallingIdentity(); 3583 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3584 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3585 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3586 -1, r.launchedFromUid, 0, options, false, null, null, null); 3587 Binder.restoreCallingIdentity(origId); 3588 3589 r.finishing = wasFinishing; 3590 if (res != ActivityManager.START_SUCCESS) { 3591 return false; 3592 } 3593 return true; 3594 } 3595 } 3596 3597 @Override 3598 public final int startActivityFromRecents(int taskId, Bundle options) { 3599 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3600 String msg = "Permission Denial: startActivityFromRecents called without " + 3601 START_TASKS_FROM_RECENTS; 3602 Slog.w(TAG, msg); 3603 throw new SecurityException(msg); 3604 } 3605 return startActivityFromRecentsInner(taskId, options); 3606 } 3607 3608 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3609 final TaskRecord task; 3610 final int callingUid; 3611 final String callingPackage; 3612 final Intent intent; 3613 final int userId; 3614 synchronized (this) { 3615 task = recentTaskForIdLocked(taskId); 3616 if (task == null) { 3617 throw new IllegalArgumentException("Task " + taskId + " not found."); 3618 } 3619 callingUid = task.mCallingUid; 3620 callingPackage = task.mCallingPackage; 3621 intent = task.intent; 3622 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3623 userId = task.userId; 3624 } 3625 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3626 options, userId, null, task); 3627 } 3628 3629 final int startActivityInPackage(int uid, String callingPackage, 3630 Intent intent, String resolvedType, IBinder resultTo, 3631 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3632 IActivityContainer container, TaskRecord inTask) { 3633 3634 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3635 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3636 3637 // TODO: Switch to user app stacks here. 3638 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3639 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3640 null, null, null, options, userId, container, inTask); 3641 return ret; 3642 } 3643 3644 @Override 3645 public final int startActivities(IApplicationThread caller, String callingPackage, 3646 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3647 int userId) { 3648 enforceNotIsolatedCaller("startActivities"); 3649 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3650 false, ALLOW_FULL_ONLY, "startActivity", null); 3651 // TODO: Switch to user app stacks here. 3652 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3653 resolvedTypes, resultTo, options, userId); 3654 return ret; 3655 } 3656 3657 final int startActivitiesInPackage(int uid, String callingPackage, 3658 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3659 Bundle options, int userId) { 3660 3661 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3662 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3663 // TODO: Switch to user app stacks here. 3664 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3665 resultTo, options, userId); 3666 return ret; 3667 } 3668 3669 //explicitly remove thd old information in mRecentTasks when removing existing user. 3670 private void removeRecentTasksForUserLocked(int userId) { 3671 if(userId <= 0) { 3672 Slog.i(TAG, "Can't remove recent task on user " + userId); 3673 return; 3674 } 3675 3676 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3677 TaskRecord tr = mRecentTasks.get(i); 3678 if (tr.userId == userId) { 3679 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3680 + " when finishing user" + userId); 3681 mRecentTasks.remove(i); 3682 tr.removedFromRecents(); 3683 } 3684 } 3685 3686 // Remove tasks from persistent storage. 3687 notifyTaskPersisterLocked(null, true); 3688 } 3689 3690 // Sort by taskId 3691 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3692 @Override 3693 public int compare(TaskRecord lhs, TaskRecord rhs) { 3694 return rhs.taskId - lhs.taskId; 3695 } 3696 }; 3697 3698 // Extract the affiliates of the chain containing mRecentTasks[start]. 3699 private int processNextAffiliateChainLocked(int start) { 3700 final TaskRecord startTask = mRecentTasks.get(start); 3701 final int affiliateId = startTask.mAffiliatedTaskId; 3702 3703 // Quick identification of isolated tasks. I.e. those not launched behind. 3704 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3705 startTask.mNextAffiliate == null) { 3706 // There is still a slim chance that there are other tasks that point to this task 3707 // and that the chain is so messed up that this task no longer points to them but 3708 // the gain of this optimization outweighs the risk. 3709 startTask.inRecents = true; 3710 return start + 1; 3711 } 3712 3713 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3714 mTmpRecents.clear(); 3715 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3716 final TaskRecord task = mRecentTasks.get(i); 3717 if (task.mAffiliatedTaskId == affiliateId) { 3718 mRecentTasks.remove(i); 3719 mTmpRecents.add(task); 3720 } 3721 } 3722 3723 // Sort them all by taskId. That is the order they were create in and that order will 3724 // always be correct. 3725 Collections.sort(mTmpRecents, mTaskRecordComparator); 3726 3727 // Go through and fix up the linked list. 3728 // The first one is the end of the chain and has no next. 3729 final TaskRecord first = mTmpRecents.get(0); 3730 first.inRecents = true; 3731 if (first.mNextAffiliate != null) { 3732 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3733 first.setNextAffiliate(null); 3734 notifyTaskPersisterLocked(first, false); 3735 } 3736 // Everything in the middle is doubly linked from next to prev. 3737 final int tmpSize = mTmpRecents.size(); 3738 for (int i = 0; i < tmpSize - 1; ++i) { 3739 final TaskRecord next = mTmpRecents.get(i); 3740 final TaskRecord prev = mTmpRecents.get(i + 1); 3741 if (next.mPrevAffiliate != prev) { 3742 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3743 " setting prev=" + prev); 3744 next.setPrevAffiliate(prev); 3745 notifyTaskPersisterLocked(next, false); 3746 } 3747 if (prev.mNextAffiliate != next) { 3748 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3749 " setting next=" + next); 3750 prev.setNextAffiliate(next); 3751 notifyTaskPersisterLocked(prev, false); 3752 } 3753 prev.inRecents = true; 3754 } 3755 // The last one is the beginning of the list and has no prev. 3756 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3757 if (last.mPrevAffiliate != null) { 3758 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3759 last.setPrevAffiliate(null); 3760 notifyTaskPersisterLocked(last, false); 3761 } 3762 3763 // Insert the group back into mRecentTasks at start. 3764 mRecentTasks.addAll(start, mTmpRecents); 3765 3766 // Let the caller know where we left off. 3767 return start + tmpSize; 3768 } 3769 3770 /** 3771 * Update the recent tasks lists: make sure tasks should still be here (their 3772 * applications / activities still exist), update their availability, fixup ordering 3773 * of affiliations. 3774 */ 3775 void cleanupRecentTasksLocked(int userId) { 3776 if (mRecentTasks == null) { 3777 // Happens when called from the packagemanager broadcast before boot. 3778 return; 3779 } 3780 3781 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3782 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3783 final IPackageManager pm = AppGlobals.getPackageManager(); 3784 final ActivityInfo dummyAct = new ActivityInfo(); 3785 final ApplicationInfo dummyApp = new ApplicationInfo(); 3786 3787 int N = mRecentTasks.size(); 3788 3789 int[] users = userId == UserHandle.USER_ALL 3790 ? getUsersLocked() : new int[] { userId }; 3791 for (int user : users) { 3792 for (int i = 0; i < N; i++) { 3793 TaskRecord task = mRecentTasks.get(i); 3794 if (task.userId != user) { 3795 // Only look at tasks for the user ID of interest. 3796 continue; 3797 } 3798 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3799 // This situation is broken, and we should just get rid of it now. 3800 mRecentTasks.remove(i); 3801 task.removedFromRecents(); 3802 i--; 3803 N--; 3804 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3805 continue; 3806 } 3807 // Check whether this activity is currently available. 3808 if (task.realActivity != null) { 3809 ActivityInfo ai = availActCache.get(task.realActivity); 3810 if (ai == null) { 3811 try { 3812 ai = pm.getActivityInfo(task.realActivity, 3813 PackageManager.GET_UNINSTALLED_PACKAGES 3814 | PackageManager.GET_DISABLED_COMPONENTS, user); 3815 } catch (RemoteException e) { 3816 // Will never happen. 3817 continue; 3818 } 3819 if (ai == null) { 3820 ai = dummyAct; 3821 } 3822 availActCache.put(task.realActivity, ai); 3823 } 3824 if (ai == dummyAct) { 3825 // This could be either because the activity no longer exists, or the 3826 // app is temporarily gone. For the former we want to remove the recents 3827 // entry; for the latter we want to mark it as unavailable. 3828 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3829 if (app == null) { 3830 try { 3831 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3832 PackageManager.GET_UNINSTALLED_PACKAGES 3833 | PackageManager.GET_DISABLED_COMPONENTS, user); 3834 } catch (RemoteException e) { 3835 // Will never happen. 3836 continue; 3837 } 3838 if (app == null) { 3839 app = dummyApp; 3840 } 3841 availAppCache.put(task.realActivity.getPackageName(), app); 3842 } 3843 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3844 // Doesn't exist any more! Good-bye. 3845 mRecentTasks.remove(i); 3846 task.removedFromRecents(); 3847 i--; 3848 N--; 3849 Slog.w(TAG, "Removing no longer valid recent: " + task); 3850 continue; 3851 } else { 3852 // Otherwise just not available for now. 3853 if (task.isAvailable) { 3854 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3855 + task); 3856 } 3857 task.isAvailable = false; 3858 } 3859 } else { 3860 if (!ai.enabled || !ai.applicationInfo.enabled 3861 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3862 if (task.isAvailable) { 3863 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3864 + task + " (enabled=" + ai.enabled + "/" 3865 + ai.applicationInfo.enabled + " flags=" 3866 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3867 } 3868 task.isAvailable = false; 3869 } else { 3870 if (!task.isAvailable) { 3871 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3872 + task); 3873 } 3874 task.isAvailable = true; 3875 } 3876 } 3877 } 3878 } 3879 } 3880 3881 // Verify the affiliate chain for each task. 3882 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3883 } 3884 3885 mTmpRecents.clear(); 3886 // mRecentTasks is now in sorted, affiliated order. 3887 } 3888 3889 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3890 int N = mRecentTasks.size(); 3891 TaskRecord top = task; 3892 int topIndex = taskIndex; 3893 while (top.mNextAffiliate != null && topIndex > 0) { 3894 top = top.mNextAffiliate; 3895 topIndex--; 3896 } 3897 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3898 + topIndex + " from intial " + taskIndex); 3899 // Find the end of the chain, doing a sanity check along the way. 3900 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3901 int endIndex = topIndex; 3902 TaskRecord prev = top; 3903 while (endIndex < N) { 3904 TaskRecord cur = mRecentTasks.get(endIndex); 3905 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3906 + endIndex + " " + cur); 3907 if (cur == top) { 3908 // Verify start of the chain. 3909 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3910 Slog.wtf(TAG, "Bad chain @" + endIndex 3911 + ": first task has next affiliate: " + prev); 3912 sane = false; 3913 break; 3914 } 3915 } else { 3916 // Verify middle of the chain's next points back to the one before. 3917 if (cur.mNextAffiliate != prev 3918 || cur.mNextAffiliateTaskId != prev.taskId) { 3919 Slog.wtf(TAG, "Bad chain @" + endIndex 3920 + ": middle task " + cur + " @" + endIndex 3921 + " has bad next affiliate " 3922 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3923 + ", expected " + prev); 3924 sane = false; 3925 break; 3926 } 3927 } 3928 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3929 // Chain ends here. 3930 if (cur.mPrevAffiliate != null) { 3931 Slog.wtf(TAG, "Bad chain @" + endIndex 3932 + ": last task " + cur + " has previous affiliate " 3933 + cur.mPrevAffiliate); 3934 sane = false; 3935 } 3936 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3937 break; 3938 } else { 3939 // Verify middle of the chain's prev points to a valid item. 3940 if (cur.mPrevAffiliate == null) { 3941 Slog.wtf(TAG, "Bad chain @" + endIndex 3942 + ": task " + cur + " has previous affiliate " 3943 + cur.mPrevAffiliate + " but should be id " 3944 + cur.mPrevAffiliate); 3945 sane = false; 3946 break; 3947 } 3948 } 3949 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3950 Slog.wtf(TAG, "Bad chain @" + endIndex 3951 + ": task " + cur + " has affiliated id " 3952 + cur.mAffiliatedTaskId + " but should be " 3953 + task.mAffiliatedTaskId); 3954 sane = false; 3955 break; 3956 } 3957 prev = cur; 3958 endIndex++; 3959 if (endIndex >= N) { 3960 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3961 + ": last task " + prev); 3962 sane = false; 3963 break; 3964 } 3965 } 3966 if (sane) { 3967 if (endIndex < taskIndex) { 3968 Slog.wtf(TAG, "Bad chain @" + endIndex 3969 + ": did not extend to task " + task + " @" + taskIndex); 3970 sane = false; 3971 } 3972 } 3973 if (sane) { 3974 // All looks good, we can just move all of the affiliated tasks 3975 // to the top. 3976 for (int i=topIndex; i<=endIndex; i++) { 3977 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3978 + " from " + i + " to " + (i-topIndex)); 3979 TaskRecord cur = mRecentTasks.remove(i); 3980 mRecentTasks.add(i-topIndex, cur); 3981 } 3982 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3983 + " to " + endIndex); 3984 return true; 3985 } 3986 3987 // Whoops, couldn't do it. 3988 return false; 3989 } 3990 3991 final void addRecentTaskLocked(TaskRecord task) { 3992 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3993 || task.mNextAffiliateTaskId != INVALID_TASK_ID 3994 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 3995 3996 int N = mRecentTasks.size(); 3997 // Quick case: check if the top-most recent task is the same. 3998 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3999 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4000 return; 4001 } 4002 // Another quick case: check if this is part of a set of affiliated 4003 // tasks that are at the top. 4004 if (isAffiliated && N > 0 && task.inRecents 4005 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4006 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4007 + " at top when adding " + task); 4008 return; 4009 } 4010 // Another quick case: never add voice sessions. 4011 if (task.voiceSession != null) { 4012 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4013 return; 4014 } 4015 4016 boolean needAffiliationFix = false; 4017 4018 // Slightly less quick case: the task is already in recents, so all we need 4019 // to do is move it. 4020 if (task.inRecents) { 4021 int taskIndex = mRecentTasks.indexOf(task); 4022 if (taskIndex >= 0) { 4023 if (!isAffiliated) { 4024 // Simple case: this is not an affiliated task, so we just move it to the front. 4025 mRecentTasks.remove(taskIndex); 4026 mRecentTasks.add(0, task); 4027 notifyTaskPersisterLocked(task, false); 4028 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4029 + " from " + taskIndex); 4030 return; 4031 } else { 4032 // More complicated: need to keep all affiliated tasks together. 4033 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4034 // All went well. 4035 return; 4036 } 4037 4038 // Uh oh... something bad in the affiliation chain, try to rebuild 4039 // everything and then go through our general path of adding a new task. 4040 needAffiliationFix = true; 4041 } 4042 } else { 4043 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4044 needAffiliationFix = true; 4045 } 4046 } 4047 4048 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4049 trimRecentsForTaskLocked(task, true); 4050 4051 N = mRecentTasks.size(); 4052 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4053 final TaskRecord tr = mRecentTasks.remove(N - 1); 4054 tr.removedFromRecents(); 4055 N--; 4056 } 4057 task.inRecents = true; 4058 if (!isAffiliated || needAffiliationFix) { 4059 // If this is a simple non-affiliated task, or we had some failure trying to 4060 // handle it as part of an affilated task, then just place it at the top. 4061 mRecentTasks.add(0, task); 4062 } else if (isAffiliated) { 4063 // If this is a new affiliated task, then move all of the affiliated tasks 4064 // to the front and insert this new one. 4065 TaskRecord other = task.mNextAffiliate; 4066 if (other == null) { 4067 other = task.mPrevAffiliate; 4068 } 4069 if (other != null) { 4070 int otherIndex = mRecentTasks.indexOf(other); 4071 if (otherIndex >= 0) { 4072 // Insert new task at appropriate location. 4073 int taskIndex; 4074 if (other == task.mNextAffiliate) { 4075 // We found the index of our next affiliation, which is who is 4076 // before us in the list, so add after that point. 4077 taskIndex = otherIndex+1; 4078 } else { 4079 // We found the index of our previous affiliation, which is who is 4080 // after us in the list, so add at their position. 4081 taskIndex = otherIndex; 4082 } 4083 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4084 + taskIndex + ": " + task); 4085 mRecentTasks.add(taskIndex, task); 4086 4087 // Now move everything to the front. 4088 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4089 // All went well. 4090 return; 4091 } 4092 4093 // Uh oh... something bad in the affiliation chain, try to rebuild 4094 // everything and then go through our general path of adding a new task. 4095 needAffiliationFix = true; 4096 } else { 4097 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4098 + other); 4099 needAffiliationFix = true; 4100 } 4101 } else { 4102 if (DEBUG_RECENTS) Slog.d(TAG, 4103 "addRecent: adding affiliated task without next/prev:" + task); 4104 needAffiliationFix = true; 4105 } 4106 } 4107 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4108 4109 if (needAffiliationFix) { 4110 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4111 cleanupRecentTasksLocked(task.userId); 4112 } 4113 } 4114 4115 /** 4116 * If needed, remove oldest existing entries in recents that are for the same kind 4117 * of task as the given one. 4118 */ 4119 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4120 int N = mRecentTasks.size(); 4121 final Intent intent = task.intent; 4122 final boolean document = intent != null && intent.isDocument(); 4123 4124 int maxRecents = task.maxRecents - 1; 4125 for (int i=0; i<N; i++) { 4126 final TaskRecord tr = mRecentTasks.get(i); 4127 if (task != tr) { 4128 if (task.userId != tr.userId) { 4129 continue; 4130 } 4131 if (i > MAX_RECENT_BITMAPS) { 4132 tr.freeLastThumbnail(); 4133 } 4134 final Intent trIntent = tr.intent; 4135 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4136 (intent == null || !intent.filterEquals(trIntent))) { 4137 continue; 4138 } 4139 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4140 if (document && trIsDocument) { 4141 // These are the same document activity (not necessarily the same doc). 4142 if (maxRecents > 0) { 4143 --maxRecents; 4144 continue; 4145 } 4146 // Hit the maximum number of documents for this task. Fall through 4147 // and remove this document from recents. 4148 } else if (document || trIsDocument) { 4149 // Only one of these is a document. Not the droid we're looking for. 4150 continue; 4151 } 4152 } 4153 4154 if (!doTrim) { 4155 // If the caller is not actually asking for a trim, just tell them we reached 4156 // a point where the trim would happen. 4157 return i; 4158 } 4159 4160 // Either task and tr are the same or, their affinities match or their intents match 4161 // and neither of them is a document, or they are documents using the same activity 4162 // and their maxRecents has been reached. 4163 tr.disposeThumbnail(); 4164 mRecentTasks.remove(i); 4165 if (task != tr) { 4166 tr.removedFromRecents(); 4167 } 4168 i--; 4169 N--; 4170 if (task.intent == null) { 4171 // If the new recent task we are adding is not fully 4172 // specified, then replace it with the existing recent task. 4173 task = tr; 4174 } 4175 notifyTaskPersisterLocked(tr, false); 4176 } 4177 4178 return -1; 4179 } 4180 4181 @Override 4182 public void reportActivityFullyDrawn(IBinder token) { 4183 synchronized (this) { 4184 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4185 if (r == null) { 4186 return; 4187 } 4188 r.reportFullyDrawnLocked(); 4189 } 4190 } 4191 4192 @Override 4193 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4194 synchronized (this) { 4195 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4196 if (r == null) { 4197 return; 4198 } 4199 final long origId = Binder.clearCallingIdentity(); 4200 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4201 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4202 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4203 if (config != null) { 4204 r.frozenBeforeDestroy = true; 4205 if (!updateConfigurationLocked(config, r, false, false)) { 4206 mStackSupervisor.resumeTopActivitiesLocked(); 4207 } 4208 } 4209 Binder.restoreCallingIdentity(origId); 4210 } 4211 } 4212 4213 @Override 4214 public int getRequestedOrientation(IBinder token) { 4215 synchronized (this) { 4216 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4217 if (r == null) { 4218 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4219 } 4220 return mWindowManager.getAppOrientation(r.appToken); 4221 } 4222 } 4223 4224 /** 4225 * This is the internal entry point for handling Activity.finish(). 4226 * 4227 * @param token The Binder token referencing the Activity we want to finish. 4228 * @param resultCode Result code, if any, from this Activity. 4229 * @param resultData Result data (Intent), if any, from this Activity. 4230 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4231 * the root Activity in the task. 4232 * 4233 * @return Returns true if the activity successfully finished, or false if it is still running. 4234 */ 4235 @Override 4236 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4237 boolean finishTask) { 4238 // Refuse possible leaked file descriptors 4239 if (resultData != null && resultData.hasFileDescriptors() == true) { 4240 throw new IllegalArgumentException("File descriptors passed in Intent"); 4241 } 4242 4243 synchronized(this) { 4244 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4245 if (r == null) { 4246 return true; 4247 } 4248 // Keep track of the root activity of the task before we finish it 4249 TaskRecord tr = r.task; 4250 ActivityRecord rootR = tr.getRootActivity(); 4251 if (rootR == null) { 4252 Slog.w(TAG, "Finishing task with all activities already finished"); 4253 } 4254 // Do not allow task to finish in Lock Task mode. 4255 if (tr == mStackSupervisor.mLockTaskModeTask) { 4256 if (rootR == r) { 4257 Slog.i(TAG, "Not finishing task in lock task mode"); 4258 mStackSupervisor.showLockTaskToast(); 4259 return false; 4260 } 4261 } 4262 if (mController != null) { 4263 // Find the first activity that is not finishing. 4264 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4265 if (next != null) { 4266 // ask watcher if this is allowed 4267 boolean resumeOK = true; 4268 try { 4269 resumeOK = mController.activityResuming(next.packageName); 4270 } catch (RemoteException e) { 4271 mController = null; 4272 Watchdog.getInstance().setActivityController(null); 4273 } 4274 4275 if (!resumeOK) { 4276 Slog.i(TAG, "Not finishing activity because controller resumed"); 4277 return false; 4278 } 4279 } 4280 } 4281 final long origId = Binder.clearCallingIdentity(); 4282 try { 4283 boolean res; 4284 if (finishTask && r == rootR) { 4285 // If requested, remove the task that is associated to this activity only if it 4286 // was the root activity in the task. The result code and data is ignored 4287 // because we don't support returning them across task boundaries. 4288 res = removeTaskByIdLocked(tr.taskId, false); 4289 if (!res) { 4290 Slog.i(TAG, "Removing task failed to finish activity"); 4291 } 4292 } else { 4293 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4294 resultData, "app-request", true); 4295 if (!res) { 4296 Slog.i(TAG, "Failed to finish by app-request"); 4297 } 4298 } 4299 return res; 4300 } finally { 4301 Binder.restoreCallingIdentity(origId); 4302 } 4303 } 4304 } 4305 4306 @Override 4307 public final void finishHeavyWeightApp() { 4308 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4309 != PackageManager.PERMISSION_GRANTED) { 4310 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4311 + Binder.getCallingPid() 4312 + ", uid=" + Binder.getCallingUid() 4313 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4314 Slog.w(TAG, msg); 4315 throw new SecurityException(msg); 4316 } 4317 4318 synchronized(this) { 4319 if (mHeavyWeightProcess == null) { 4320 return; 4321 } 4322 4323 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4324 mHeavyWeightProcess.activities); 4325 for (int i=0; i<activities.size(); i++) { 4326 ActivityRecord r = activities.get(i); 4327 if (!r.finishing) { 4328 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4329 null, "finish-heavy", true); 4330 } 4331 } 4332 4333 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4334 mHeavyWeightProcess.userId, 0)); 4335 mHeavyWeightProcess = null; 4336 } 4337 } 4338 4339 @Override 4340 public void crashApplication(int uid, int initialPid, String packageName, 4341 String message) { 4342 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4343 != PackageManager.PERMISSION_GRANTED) { 4344 String msg = "Permission Denial: crashApplication() from pid=" 4345 + Binder.getCallingPid() 4346 + ", uid=" + Binder.getCallingUid() 4347 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4348 Slog.w(TAG, msg); 4349 throw new SecurityException(msg); 4350 } 4351 4352 synchronized(this) { 4353 ProcessRecord proc = null; 4354 4355 // Figure out which process to kill. We don't trust that initialPid 4356 // still has any relation to current pids, so must scan through the 4357 // list. 4358 synchronized (mPidsSelfLocked) { 4359 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4360 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4361 if (p.uid != uid) { 4362 continue; 4363 } 4364 if (p.pid == initialPid) { 4365 proc = p; 4366 break; 4367 } 4368 if (p.pkgList.containsKey(packageName)) { 4369 proc = p; 4370 } 4371 } 4372 } 4373 4374 if (proc == null) { 4375 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4376 + " initialPid=" + initialPid 4377 + " packageName=" + packageName); 4378 return; 4379 } 4380 4381 if (proc.thread != null) { 4382 if (proc.pid == Process.myPid()) { 4383 Log.w(TAG, "crashApplication: trying to crash self!"); 4384 return; 4385 } 4386 long ident = Binder.clearCallingIdentity(); 4387 try { 4388 proc.thread.scheduleCrash(message); 4389 } catch (RemoteException e) { 4390 } 4391 Binder.restoreCallingIdentity(ident); 4392 } 4393 } 4394 } 4395 4396 @Override 4397 public final void finishSubActivity(IBinder token, String resultWho, 4398 int requestCode) { 4399 synchronized(this) { 4400 final long origId = Binder.clearCallingIdentity(); 4401 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4402 if (r != null) { 4403 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4404 } 4405 Binder.restoreCallingIdentity(origId); 4406 } 4407 } 4408 4409 @Override 4410 public boolean finishActivityAffinity(IBinder token) { 4411 synchronized(this) { 4412 final long origId = Binder.clearCallingIdentity(); 4413 try { 4414 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4415 4416 ActivityRecord rootR = r.task.getRootActivity(); 4417 // Do not allow task to finish in Lock Task mode. 4418 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4419 if (rootR == r) { 4420 mStackSupervisor.showLockTaskToast(); 4421 return false; 4422 } 4423 } 4424 boolean res = false; 4425 if (r != null) { 4426 res = r.task.stack.finishActivityAffinityLocked(r); 4427 } 4428 return res; 4429 } finally { 4430 Binder.restoreCallingIdentity(origId); 4431 } 4432 } 4433 } 4434 4435 @Override 4436 public void finishVoiceTask(IVoiceInteractionSession session) { 4437 synchronized(this) { 4438 final long origId = Binder.clearCallingIdentity(); 4439 try { 4440 mStackSupervisor.finishVoiceTask(session); 4441 } finally { 4442 Binder.restoreCallingIdentity(origId); 4443 } 4444 } 4445 4446 } 4447 4448 @Override 4449 public boolean releaseActivityInstance(IBinder token) { 4450 synchronized(this) { 4451 final long origId = Binder.clearCallingIdentity(); 4452 try { 4453 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4454 if (r.task == null || r.task.stack == null) { 4455 return false; 4456 } 4457 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4458 } finally { 4459 Binder.restoreCallingIdentity(origId); 4460 } 4461 } 4462 } 4463 4464 @Override 4465 public void releaseSomeActivities(IApplicationThread appInt) { 4466 synchronized(this) { 4467 final long origId = Binder.clearCallingIdentity(); 4468 try { 4469 ProcessRecord app = getRecordForAppLocked(appInt); 4470 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4471 } finally { 4472 Binder.restoreCallingIdentity(origId); 4473 } 4474 } 4475 } 4476 4477 @Override 4478 public boolean willActivityBeVisible(IBinder token) { 4479 synchronized(this) { 4480 ActivityStack stack = ActivityRecord.getStackLocked(token); 4481 if (stack != null) { 4482 return stack.willActivityBeVisibleLocked(token); 4483 } 4484 return false; 4485 } 4486 } 4487 4488 @Override 4489 public void overridePendingTransition(IBinder token, String packageName, 4490 int enterAnim, int exitAnim) { 4491 synchronized(this) { 4492 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4493 if (self == null) { 4494 return; 4495 } 4496 4497 final long origId = Binder.clearCallingIdentity(); 4498 4499 if (self.state == ActivityState.RESUMED 4500 || self.state == ActivityState.PAUSING) { 4501 mWindowManager.overridePendingAppTransition(packageName, 4502 enterAnim, exitAnim, null); 4503 } 4504 4505 Binder.restoreCallingIdentity(origId); 4506 } 4507 } 4508 4509 /** 4510 * Main function for removing an existing process from the activity manager 4511 * as a result of that process going away. Clears out all connections 4512 * to the process. 4513 */ 4514 private final void handleAppDiedLocked(ProcessRecord app, 4515 boolean restarting, boolean allowRestart) { 4516 int pid = app.pid; 4517 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4518 if (!kept && !restarting) { 4519 removeLruProcessLocked(app); 4520 if (pid > 0) { 4521 ProcessList.remove(pid); 4522 } 4523 } 4524 4525 if (mProfileProc == app) { 4526 clearProfilerLocked(); 4527 } 4528 4529 // Remove this application's activities from active lists. 4530 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4531 4532 app.activities.clear(); 4533 4534 if (app.instrumentationClass != null) { 4535 Slog.w(TAG, "Crash of app " + app.processName 4536 + " running instrumentation " + app.instrumentationClass); 4537 Bundle info = new Bundle(); 4538 info.putString("shortMsg", "Process crashed."); 4539 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4540 } 4541 4542 if (!restarting) { 4543 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4544 // If there was nothing to resume, and we are not already 4545 // restarting this process, but there is a visible activity that 4546 // is hosted by the process... then make sure all visible 4547 // activities are running, taking care of restarting this 4548 // process. 4549 if (hasVisibleActivities) { 4550 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4551 } 4552 } 4553 } 4554 } 4555 4556 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4557 IBinder threadBinder = thread.asBinder(); 4558 // Find the application record. 4559 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4560 ProcessRecord rec = mLruProcesses.get(i); 4561 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4562 return i; 4563 } 4564 } 4565 return -1; 4566 } 4567 4568 final ProcessRecord getRecordForAppLocked( 4569 IApplicationThread thread) { 4570 if (thread == null) { 4571 return null; 4572 } 4573 4574 int appIndex = getLRURecordIndexForAppLocked(thread); 4575 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4576 } 4577 4578 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4579 // If there are no longer any background processes running, 4580 // and the app that died was not running instrumentation, 4581 // then tell everyone we are now low on memory. 4582 boolean haveBg = false; 4583 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4584 ProcessRecord rec = mLruProcesses.get(i); 4585 if (rec.thread != null 4586 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4587 haveBg = true; 4588 break; 4589 } 4590 } 4591 4592 if (!haveBg) { 4593 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4594 if (doReport) { 4595 long now = SystemClock.uptimeMillis(); 4596 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4597 doReport = false; 4598 } else { 4599 mLastMemUsageReportTime = now; 4600 } 4601 } 4602 final ArrayList<ProcessMemInfo> memInfos 4603 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4604 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4605 long now = SystemClock.uptimeMillis(); 4606 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4607 ProcessRecord rec = mLruProcesses.get(i); 4608 if (rec == dyingProc || rec.thread == null) { 4609 continue; 4610 } 4611 if (doReport) { 4612 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4613 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4614 } 4615 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4616 // The low memory report is overriding any current 4617 // state for a GC request. Make sure to do 4618 // heavy/important/visible/foreground processes first. 4619 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4620 rec.lastRequestedGc = 0; 4621 } else { 4622 rec.lastRequestedGc = rec.lastLowMemory; 4623 } 4624 rec.reportLowMemory = true; 4625 rec.lastLowMemory = now; 4626 mProcessesToGc.remove(rec); 4627 addProcessToGcListLocked(rec); 4628 } 4629 } 4630 if (doReport) { 4631 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4632 mHandler.sendMessage(msg); 4633 } 4634 scheduleAppGcsLocked(); 4635 } 4636 } 4637 4638 final void appDiedLocked(ProcessRecord app) { 4639 appDiedLocked(app, app.pid, app.thread); 4640 } 4641 4642 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4643 // First check if this ProcessRecord is actually active for the pid. 4644 synchronized (mPidsSelfLocked) { 4645 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4646 if (curProc != app) { 4647 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4648 return; 4649 } 4650 } 4651 4652 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4653 synchronized (stats) { 4654 stats.noteProcessDiedLocked(app.info.uid, pid); 4655 } 4656 4657 Process.killProcessQuiet(pid); 4658 Process.killProcessGroup(app.info.uid, pid); 4659 app.killed = true; 4660 4661 // Clean up already done if the process has been re-started. 4662 if (app.pid == pid && app.thread != null && 4663 app.thread.asBinder() == thread.asBinder()) { 4664 boolean doLowMem = app.instrumentationClass == null; 4665 boolean doOomAdj = doLowMem; 4666 if (!app.killedByAm) { 4667 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4668 + ") has died"); 4669 mAllowLowerMemLevel = true; 4670 } else { 4671 // Note that we always want to do oom adj to update our state with the 4672 // new number of procs. 4673 mAllowLowerMemLevel = false; 4674 doLowMem = false; 4675 } 4676 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4677 if (DEBUG_CLEANUP) Slog.v( 4678 TAG, "Dying app: " + app + ", pid: " + pid 4679 + ", thread: " + thread.asBinder()); 4680 handleAppDiedLocked(app, false, true); 4681 4682 if (doOomAdj) { 4683 updateOomAdjLocked(); 4684 } 4685 if (doLowMem) { 4686 doLowMemReportIfNeededLocked(app); 4687 } 4688 } else if (app.pid != pid) { 4689 // A new process has already been started. 4690 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4691 + ") has died and restarted (pid " + app.pid + ")."); 4692 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4693 } else if (DEBUG_PROCESSES) { 4694 Slog.d(TAG, "Received spurious death notification for thread " 4695 + thread.asBinder()); 4696 } 4697 } 4698 4699 /** 4700 * If a stack trace dump file is configured, dump process stack traces. 4701 * @param clearTraces causes the dump file to be erased prior to the new 4702 * traces being written, if true; when false, the new traces will be 4703 * appended to any existing file content. 4704 * @param firstPids of dalvik VM processes to dump stack traces for first 4705 * @param lastPids of dalvik VM processes to dump stack traces for last 4706 * @param nativeProcs optional list of native process names to dump stack crawls 4707 * @return file containing stack traces, or null if no dump file is configured 4708 */ 4709 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4710 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4711 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4712 if (tracesPath == null || tracesPath.length() == 0) { 4713 return null; 4714 } 4715 4716 File tracesFile = new File(tracesPath); 4717 try { 4718 File tracesDir = tracesFile.getParentFile(); 4719 if (!tracesDir.exists()) { 4720 tracesDir.mkdirs(); 4721 if (!SELinux.restorecon(tracesDir)) { 4722 return null; 4723 } 4724 } 4725 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4726 4727 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4728 tracesFile.createNewFile(); 4729 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4730 } catch (IOException e) { 4731 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4732 return null; 4733 } 4734 4735 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4736 return tracesFile; 4737 } 4738 4739 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4740 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4741 // Use a FileObserver to detect when traces finish writing. 4742 // The order of traces is considered important to maintain for legibility. 4743 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4744 @Override 4745 public synchronized void onEvent(int event, String path) { notify(); } 4746 }; 4747 4748 try { 4749 observer.startWatching(); 4750 4751 // First collect all of the stacks of the most important pids. 4752 if (firstPids != null) { 4753 try { 4754 int num = firstPids.size(); 4755 for (int i = 0; i < num; i++) { 4756 synchronized (observer) { 4757 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4758 observer.wait(200); // Wait for write-close, give up after 200msec 4759 } 4760 } 4761 } catch (InterruptedException e) { 4762 Slog.wtf(TAG, e); 4763 } 4764 } 4765 4766 // Next collect the stacks of the native pids 4767 if (nativeProcs != null) { 4768 int[] pids = Process.getPidsForCommands(nativeProcs); 4769 if (pids != null) { 4770 for (int pid : pids) { 4771 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4772 } 4773 } 4774 } 4775 4776 // Lastly, measure CPU usage. 4777 if (processCpuTracker != null) { 4778 processCpuTracker.init(); 4779 System.gc(); 4780 processCpuTracker.update(); 4781 try { 4782 synchronized (processCpuTracker) { 4783 processCpuTracker.wait(500); // measure over 1/2 second. 4784 } 4785 } catch (InterruptedException e) { 4786 } 4787 processCpuTracker.update(); 4788 4789 // We'll take the stack crawls of just the top apps using CPU. 4790 final int N = processCpuTracker.countWorkingStats(); 4791 int numProcs = 0; 4792 for (int i=0; i<N && numProcs<5; i++) { 4793 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4794 if (lastPids.indexOfKey(stats.pid) >= 0) { 4795 numProcs++; 4796 try { 4797 synchronized (observer) { 4798 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4799 observer.wait(200); // Wait for write-close, give up after 200msec 4800 } 4801 } catch (InterruptedException e) { 4802 Slog.wtf(TAG, e); 4803 } 4804 4805 } 4806 } 4807 } 4808 } finally { 4809 observer.stopWatching(); 4810 } 4811 } 4812 4813 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4814 if (true || IS_USER_BUILD) { 4815 return; 4816 } 4817 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4818 if (tracesPath == null || tracesPath.length() == 0) { 4819 return; 4820 } 4821 4822 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4823 StrictMode.allowThreadDiskWrites(); 4824 try { 4825 final File tracesFile = new File(tracesPath); 4826 final File tracesDir = tracesFile.getParentFile(); 4827 final File tracesTmp = new File(tracesDir, "__tmp__"); 4828 try { 4829 if (!tracesDir.exists()) { 4830 tracesDir.mkdirs(); 4831 if (!SELinux.restorecon(tracesDir.getPath())) { 4832 return; 4833 } 4834 } 4835 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4836 4837 if (tracesFile.exists()) { 4838 tracesTmp.delete(); 4839 tracesFile.renameTo(tracesTmp); 4840 } 4841 StringBuilder sb = new StringBuilder(); 4842 Time tobj = new Time(); 4843 tobj.set(System.currentTimeMillis()); 4844 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4845 sb.append(": "); 4846 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4847 sb.append(" since "); 4848 sb.append(msg); 4849 FileOutputStream fos = new FileOutputStream(tracesFile); 4850 fos.write(sb.toString().getBytes()); 4851 if (app == null) { 4852 fos.write("\n*** No application process!".getBytes()); 4853 } 4854 fos.close(); 4855 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4856 } catch (IOException e) { 4857 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4858 return; 4859 } 4860 4861 if (app != null) { 4862 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4863 firstPids.add(app.pid); 4864 dumpStackTraces(tracesPath, firstPids, null, null, null); 4865 } 4866 4867 File lastTracesFile = null; 4868 File curTracesFile = null; 4869 for (int i=9; i>=0; i--) { 4870 String name = String.format(Locale.US, "slow%02d.txt", i); 4871 curTracesFile = new File(tracesDir, name); 4872 if (curTracesFile.exists()) { 4873 if (lastTracesFile != null) { 4874 curTracesFile.renameTo(lastTracesFile); 4875 } else { 4876 curTracesFile.delete(); 4877 } 4878 } 4879 lastTracesFile = curTracesFile; 4880 } 4881 tracesFile.renameTo(curTracesFile); 4882 if (tracesTmp.exists()) { 4883 tracesTmp.renameTo(tracesFile); 4884 } 4885 } finally { 4886 StrictMode.setThreadPolicy(oldPolicy); 4887 } 4888 } 4889 4890 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4891 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4892 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4893 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4894 4895 if (mController != null) { 4896 try { 4897 // 0 == continue, -1 = kill process immediately 4898 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4899 if (res < 0 && app.pid != MY_PID) { 4900 app.kill("anr", true); 4901 } 4902 } catch (RemoteException e) { 4903 mController = null; 4904 Watchdog.getInstance().setActivityController(null); 4905 } 4906 } 4907 4908 long anrTime = SystemClock.uptimeMillis(); 4909 if (MONITOR_CPU_USAGE) { 4910 updateCpuStatsNow(); 4911 } 4912 4913 synchronized (this) { 4914 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4915 if (mShuttingDown) { 4916 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4917 return; 4918 } else if (app.notResponding) { 4919 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4920 return; 4921 } else if (app.crashing) { 4922 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4923 return; 4924 } 4925 4926 // In case we come through here for the same app before completing 4927 // this one, mark as anring now so we will bail out. 4928 app.notResponding = true; 4929 4930 // Log the ANR to the event log. 4931 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4932 app.processName, app.info.flags, annotation); 4933 4934 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4935 firstPids.add(app.pid); 4936 4937 int parentPid = app.pid; 4938 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4939 if (parentPid != app.pid) firstPids.add(parentPid); 4940 4941 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4942 4943 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4944 ProcessRecord r = mLruProcesses.get(i); 4945 if (r != null && r.thread != null) { 4946 int pid = r.pid; 4947 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4948 if (r.persistent) { 4949 firstPids.add(pid); 4950 } else { 4951 lastPids.put(pid, Boolean.TRUE); 4952 } 4953 } 4954 } 4955 } 4956 } 4957 4958 // Log the ANR to the main log. 4959 StringBuilder info = new StringBuilder(); 4960 info.setLength(0); 4961 info.append("ANR in ").append(app.processName); 4962 if (activity != null && activity.shortComponentName != null) { 4963 info.append(" (").append(activity.shortComponentName).append(")"); 4964 } 4965 info.append("\n"); 4966 info.append("PID: ").append(app.pid).append("\n"); 4967 if (annotation != null) { 4968 info.append("Reason: ").append(annotation).append("\n"); 4969 } 4970 if (parent != null && parent != activity) { 4971 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4972 } 4973 4974 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4975 4976 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4977 NATIVE_STACKS_OF_INTEREST); 4978 4979 String cpuInfo = null; 4980 if (MONITOR_CPU_USAGE) { 4981 updateCpuStatsNow(); 4982 synchronized (mProcessCpuTracker) { 4983 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4984 } 4985 info.append(processCpuTracker.printCurrentLoad()); 4986 info.append(cpuInfo); 4987 } 4988 4989 info.append(processCpuTracker.printCurrentState(anrTime)); 4990 4991 Slog.e(TAG, info.toString()); 4992 if (tracesFile == null) { 4993 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4994 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4995 } 4996 4997 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4998 cpuInfo, tracesFile, null); 4999 5000 if (mController != null) { 5001 try { 5002 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5003 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5004 if (res != 0) { 5005 if (res < 0 && app.pid != MY_PID) { 5006 app.kill("anr", true); 5007 } else { 5008 synchronized (this) { 5009 mServices.scheduleServiceTimeoutLocked(app); 5010 } 5011 } 5012 return; 5013 } 5014 } catch (RemoteException e) { 5015 mController = null; 5016 Watchdog.getInstance().setActivityController(null); 5017 } 5018 } 5019 5020 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5021 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5022 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5023 5024 synchronized (this) { 5025 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5026 app.kill("bg anr", true); 5027 return; 5028 } 5029 5030 // Set the app's notResponding state, and look up the errorReportReceiver 5031 makeAppNotRespondingLocked(app, 5032 activity != null ? activity.shortComponentName : null, 5033 annotation != null ? "ANR " + annotation : "ANR", 5034 info.toString()); 5035 5036 // Bring up the infamous App Not Responding dialog 5037 Message msg = Message.obtain(); 5038 HashMap<String, Object> map = new HashMap<String, Object>(); 5039 msg.what = SHOW_NOT_RESPONDING_MSG; 5040 msg.obj = map; 5041 msg.arg1 = aboveSystem ? 1 : 0; 5042 map.put("app", app); 5043 if (activity != null) { 5044 map.put("activity", activity); 5045 } 5046 5047 mHandler.sendMessage(msg); 5048 } 5049 } 5050 5051 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5052 if (!mLaunchWarningShown) { 5053 mLaunchWarningShown = true; 5054 mHandler.post(new Runnable() { 5055 @Override 5056 public void run() { 5057 synchronized (ActivityManagerService.this) { 5058 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5059 d.show(); 5060 mHandler.postDelayed(new Runnable() { 5061 @Override 5062 public void run() { 5063 synchronized (ActivityManagerService.this) { 5064 d.dismiss(); 5065 mLaunchWarningShown = false; 5066 } 5067 } 5068 }, 4000); 5069 } 5070 } 5071 }); 5072 } 5073 } 5074 5075 @Override 5076 public boolean clearApplicationUserData(final String packageName, 5077 final IPackageDataObserver observer, int userId) { 5078 enforceNotIsolatedCaller("clearApplicationUserData"); 5079 int uid = Binder.getCallingUid(); 5080 int pid = Binder.getCallingPid(); 5081 userId = handleIncomingUser(pid, uid, 5082 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5083 long callingId = Binder.clearCallingIdentity(); 5084 try { 5085 IPackageManager pm = AppGlobals.getPackageManager(); 5086 int pkgUid = -1; 5087 synchronized(this) { 5088 try { 5089 pkgUid = pm.getPackageUid(packageName, userId); 5090 } catch (RemoteException e) { 5091 } 5092 if (pkgUid == -1) { 5093 Slog.w(TAG, "Invalid packageName: " + packageName); 5094 if (observer != null) { 5095 try { 5096 observer.onRemoveCompleted(packageName, false); 5097 } catch (RemoteException e) { 5098 Slog.i(TAG, "Observer no longer exists."); 5099 } 5100 } 5101 return false; 5102 } 5103 if (uid == pkgUid || checkComponentPermission( 5104 android.Manifest.permission.CLEAR_APP_USER_DATA, 5105 pid, uid, -1, true) 5106 == PackageManager.PERMISSION_GRANTED) { 5107 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5108 } else { 5109 throw new SecurityException("PID " + pid + " does not have permission " 5110 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5111 + " of package " + packageName); 5112 } 5113 5114 // Remove all tasks match the cleared application package and user 5115 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5116 final TaskRecord tr = mRecentTasks.get(i); 5117 final String taskPackageName = 5118 tr.getBaseIntent().getComponent().getPackageName(); 5119 if (tr.userId != userId) continue; 5120 if (!taskPackageName.equals(packageName)) continue; 5121 removeTaskByIdLocked(tr.taskId, false); 5122 } 5123 } 5124 5125 try { 5126 // Clear application user data 5127 pm.clearApplicationUserData(packageName, observer, userId); 5128 5129 synchronized(this) { 5130 // Remove all permissions granted from/to this package 5131 removeUriPermissionsForPackageLocked(packageName, userId, true); 5132 } 5133 5134 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5135 Uri.fromParts("package", packageName, null)); 5136 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5137 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5138 null, null, 0, null, null, null, false, false, userId); 5139 } catch (RemoteException e) { 5140 } 5141 } finally { 5142 Binder.restoreCallingIdentity(callingId); 5143 } 5144 return true; 5145 } 5146 5147 @Override 5148 public void killBackgroundProcesses(final String packageName, int userId) { 5149 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5150 != PackageManager.PERMISSION_GRANTED && 5151 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5152 != PackageManager.PERMISSION_GRANTED) { 5153 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5154 + Binder.getCallingPid() 5155 + ", uid=" + Binder.getCallingUid() 5156 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5157 Slog.w(TAG, msg); 5158 throw new SecurityException(msg); 5159 } 5160 5161 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5162 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5163 long callingId = Binder.clearCallingIdentity(); 5164 try { 5165 IPackageManager pm = AppGlobals.getPackageManager(); 5166 synchronized(this) { 5167 int appId = -1; 5168 try { 5169 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5170 } catch (RemoteException e) { 5171 } 5172 if (appId == -1) { 5173 Slog.w(TAG, "Invalid packageName: " + packageName); 5174 return; 5175 } 5176 killPackageProcessesLocked(packageName, appId, userId, 5177 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5178 } 5179 } finally { 5180 Binder.restoreCallingIdentity(callingId); 5181 } 5182 } 5183 5184 @Override 5185 public void killAllBackgroundProcesses() { 5186 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5187 != PackageManager.PERMISSION_GRANTED) { 5188 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5189 + Binder.getCallingPid() 5190 + ", uid=" + Binder.getCallingUid() 5191 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5192 Slog.w(TAG, msg); 5193 throw new SecurityException(msg); 5194 } 5195 5196 long callingId = Binder.clearCallingIdentity(); 5197 try { 5198 synchronized(this) { 5199 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5200 final int NP = mProcessNames.getMap().size(); 5201 for (int ip=0; ip<NP; ip++) { 5202 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5203 final int NA = apps.size(); 5204 for (int ia=0; ia<NA; ia++) { 5205 ProcessRecord app = apps.valueAt(ia); 5206 if (app.persistent) { 5207 // we don't kill persistent processes 5208 continue; 5209 } 5210 if (app.removed) { 5211 procs.add(app); 5212 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5213 app.removed = true; 5214 procs.add(app); 5215 } 5216 } 5217 } 5218 5219 int N = procs.size(); 5220 for (int i=0; i<N; i++) { 5221 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5222 } 5223 mAllowLowerMemLevel = true; 5224 updateOomAdjLocked(); 5225 doLowMemReportIfNeededLocked(null); 5226 } 5227 } finally { 5228 Binder.restoreCallingIdentity(callingId); 5229 } 5230 } 5231 5232 @Override 5233 public void forceStopPackage(final String packageName, int userId) { 5234 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5235 != PackageManager.PERMISSION_GRANTED) { 5236 String msg = "Permission Denial: forceStopPackage() from pid=" 5237 + Binder.getCallingPid() 5238 + ", uid=" + Binder.getCallingUid() 5239 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5240 Slog.w(TAG, msg); 5241 throw new SecurityException(msg); 5242 } 5243 final int callingPid = Binder.getCallingPid(); 5244 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5245 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5246 long callingId = Binder.clearCallingIdentity(); 5247 try { 5248 IPackageManager pm = AppGlobals.getPackageManager(); 5249 synchronized(this) { 5250 int[] users = userId == UserHandle.USER_ALL 5251 ? getUsersLocked() : new int[] { userId }; 5252 for (int user : users) { 5253 int pkgUid = -1; 5254 try { 5255 pkgUid = pm.getPackageUid(packageName, user); 5256 } catch (RemoteException e) { 5257 } 5258 if (pkgUid == -1) { 5259 Slog.w(TAG, "Invalid packageName: " + packageName); 5260 continue; 5261 } 5262 try { 5263 pm.setPackageStoppedState(packageName, true, user); 5264 } catch (RemoteException e) { 5265 } catch (IllegalArgumentException e) { 5266 Slog.w(TAG, "Failed trying to unstop package " 5267 + packageName + ": " + e); 5268 } 5269 if (isUserRunningLocked(user, false)) { 5270 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5271 } 5272 } 5273 } 5274 } finally { 5275 Binder.restoreCallingIdentity(callingId); 5276 } 5277 } 5278 5279 @Override 5280 public void addPackageDependency(String packageName) { 5281 synchronized (this) { 5282 int callingPid = Binder.getCallingPid(); 5283 if (callingPid == Process.myPid()) { 5284 // Yeah, um, no. 5285 Slog.w(TAG, "Can't addPackageDependency on system process"); 5286 return; 5287 } 5288 ProcessRecord proc; 5289 synchronized (mPidsSelfLocked) { 5290 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5291 } 5292 if (proc != null) { 5293 if (proc.pkgDeps == null) { 5294 proc.pkgDeps = new ArraySet<String>(1); 5295 } 5296 proc.pkgDeps.add(packageName); 5297 } 5298 } 5299 } 5300 5301 /* 5302 * The pkg name and app id have to be specified. 5303 */ 5304 @Override 5305 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5306 if (pkg == null) { 5307 return; 5308 } 5309 // Make sure the uid is valid. 5310 if (appid < 0) { 5311 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5312 return; 5313 } 5314 int callerUid = Binder.getCallingUid(); 5315 // Only the system server can kill an application 5316 if (callerUid == Process.SYSTEM_UID) { 5317 // Post an aysnc message to kill the application 5318 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5319 msg.arg1 = appid; 5320 msg.arg2 = 0; 5321 Bundle bundle = new Bundle(); 5322 bundle.putString("pkg", pkg); 5323 bundle.putString("reason", reason); 5324 msg.obj = bundle; 5325 mHandler.sendMessage(msg); 5326 } else { 5327 throw new SecurityException(callerUid + " cannot kill pkg: " + 5328 pkg); 5329 } 5330 } 5331 5332 @Override 5333 public void closeSystemDialogs(String reason) { 5334 enforceNotIsolatedCaller("closeSystemDialogs"); 5335 5336 final int pid = Binder.getCallingPid(); 5337 final int uid = Binder.getCallingUid(); 5338 final long origId = Binder.clearCallingIdentity(); 5339 try { 5340 synchronized (this) { 5341 // Only allow this from foreground processes, so that background 5342 // applications can't abuse it to prevent system UI from being shown. 5343 if (uid >= Process.FIRST_APPLICATION_UID) { 5344 ProcessRecord proc; 5345 synchronized (mPidsSelfLocked) { 5346 proc = mPidsSelfLocked.get(pid); 5347 } 5348 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5349 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5350 + " from background process " + proc); 5351 return; 5352 } 5353 } 5354 closeSystemDialogsLocked(reason); 5355 } 5356 } finally { 5357 Binder.restoreCallingIdentity(origId); 5358 } 5359 } 5360 5361 void closeSystemDialogsLocked(String reason) { 5362 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5363 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5364 | Intent.FLAG_RECEIVER_FOREGROUND); 5365 if (reason != null) { 5366 intent.putExtra("reason", reason); 5367 } 5368 mWindowManager.closeSystemDialogs(reason); 5369 5370 mStackSupervisor.closeSystemDialogsLocked(); 5371 5372 broadcastIntentLocked(null, null, intent, null, 5373 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5374 Process.SYSTEM_UID, UserHandle.USER_ALL); 5375 } 5376 5377 @Override 5378 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5379 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5380 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5381 for (int i=pids.length-1; i>=0; i--) { 5382 ProcessRecord proc; 5383 int oomAdj; 5384 synchronized (this) { 5385 synchronized (mPidsSelfLocked) { 5386 proc = mPidsSelfLocked.get(pids[i]); 5387 oomAdj = proc != null ? proc.setAdj : 0; 5388 } 5389 } 5390 infos[i] = new Debug.MemoryInfo(); 5391 Debug.getMemoryInfo(pids[i], infos[i]); 5392 if (proc != null) { 5393 synchronized (this) { 5394 if (proc.thread != null && proc.setAdj == oomAdj) { 5395 // Record this for posterity if the process has been stable. 5396 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5397 infos[i].getTotalUss(), false, proc.pkgList); 5398 } 5399 } 5400 } 5401 } 5402 return infos; 5403 } 5404 5405 @Override 5406 public long[] getProcessPss(int[] pids) { 5407 enforceNotIsolatedCaller("getProcessPss"); 5408 long[] pss = new long[pids.length]; 5409 for (int i=pids.length-1; i>=0; i--) { 5410 ProcessRecord proc; 5411 int oomAdj; 5412 synchronized (this) { 5413 synchronized (mPidsSelfLocked) { 5414 proc = mPidsSelfLocked.get(pids[i]); 5415 oomAdj = proc != null ? proc.setAdj : 0; 5416 } 5417 } 5418 long[] tmpUss = new long[1]; 5419 pss[i] = Debug.getPss(pids[i], tmpUss); 5420 if (proc != null) { 5421 synchronized (this) { 5422 if (proc.thread != null && proc.setAdj == oomAdj) { 5423 // Record this for posterity if the process has been stable. 5424 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5425 } 5426 } 5427 } 5428 } 5429 return pss; 5430 } 5431 5432 @Override 5433 public void killApplicationProcess(String processName, int uid) { 5434 if (processName == null) { 5435 return; 5436 } 5437 5438 int callerUid = Binder.getCallingUid(); 5439 // Only the system server can kill an application 5440 if (callerUid == Process.SYSTEM_UID) { 5441 synchronized (this) { 5442 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5443 if (app != null && app.thread != null) { 5444 try { 5445 app.thread.scheduleSuicide(); 5446 } catch (RemoteException e) { 5447 // If the other end already died, then our work here is done. 5448 } 5449 } else { 5450 Slog.w(TAG, "Process/uid not found attempting kill of " 5451 + processName + " / " + uid); 5452 } 5453 } 5454 } else { 5455 throw new SecurityException(callerUid + " cannot kill app process: " + 5456 processName); 5457 } 5458 } 5459 5460 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5461 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5462 false, true, false, false, UserHandle.getUserId(uid), reason); 5463 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5464 Uri.fromParts("package", packageName, null)); 5465 if (!mProcessesReady) { 5466 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5467 | Intent.FLAG_RECEIVER_FOREGROUND); 5468 } 5469 intent.putExtra(Intent.EXTRA_UID, uid); 5470 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5471 broadcastIntentLocked(null, null, intent, 5472 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5473 false, false, 5474 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5475 } 5476 5477 private void forceStopUserLocked(int userId, String reason) { 5478 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5479 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5480 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5481 | Intent.FLAG_RECEIVER_FOREGROUND); 5482 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5483 broadcastIntentLocked(null, null, intent, 5484 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5485 false, false, 5486 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5487 } 5488 5489 private final boolean killPackageProcessesLocked(String packageName, int appId, 5490 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5491 boolean doit, boolean evenPersistent, String reason) { 5492 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5493 5494 // Remove all processes this package may have touched: all with the 5495 // same UID (except for the system or root user), and all whose name 5496 // matches the package name. 5497 final int NP = mProcessNames.getMap().size(); 5498 for (int ip=0; ip<NP; ip++) { 5499 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5500 final int NA = apps.size(); 5501 for (int ia=0; ia<NA; ia++) { 5502 ProcessRecord app = apps.valueAt(ia); 5503 if (app.persistent && !evenPersistent) { 5504 // we don't kill persistent processes 5505 continue; 5506 } 5507 if (app.removed) { 5508 if (doit) { 5509 procs.add(app); 5510 } 5511 continue; 5512 } 5513 5514 // Skip process if it doesn't meet our oom adj requirement. 5515 if (app.setAdj < minOomAdj) { 5516 continue; 5517 } 5518 5519 // If no package is specified, we call all processes under the 5520 // give user id. 5521 if (packageName == null) { 5522 if (app.userId != userId) { 5523 continue; 5524 } 5525 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5526 continue; 5527 } 5528 // Package has been specified, we want to hit all processes 5529 // that match it. We need to qualify this by the processes 5530 // that are running under the specified app and user ID. 5531 } else { 5532 final boolean isDep = app.pkgDeps != null 5533 && app.pkgDeps.contains(packageName); 5534 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5535 continue; 5536 } 5537 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5538 continue; 5539 } 5540 if (!app.pkgList.containsKey(packageName) && !isDep) { 5541 continue; 5542 } 5543 } 5544 5545 // Process has passed all conditions, kill it! 5546 if (!doit) { 5547 return true; 5548 } 5549 app.removed = true; 5550 procs.add(app); 5551 } 5552 } 5553 5554 int N = procs.size(); 5555 for (int i=0; i<N; i++) { 5556 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5557 } 5558 updateOomAdjLocked(); 5559 return N > 0; 5560 } 5561 5562 private final boolean forceStopPackageLocked(String name, int appId, 5563 boolean callerWillRestart, boolean purgeCache, boolean doit, 5564 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5565 int i; 5566 int N; 5567 5568 if (userId == UserHandle.USER_ALL && name == null) { 5569 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5570 } 5571 5572 if (appId < 0 && name != null) { 5573 try { 5574 appId = UserHandle.getAppId( 5575 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5576 } catch (RemoteException e) { 5577 } 5578 } 5579 5580 if (doit) { 5581 if (name != null) { 5582 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5583 + " user=" + userId + ": " + reason); 5584 } else { 5585 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5586 } 5587 5588 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5589 for (int ip=pmap.size()-1; ip>=0; ip--) { 5590 SparseArray<Long> ba = pmap.valueAt(ip); 5591 for (i=ba.size()-1; i>=0; i--) { 5592 boolean remove = false; 5593 final int entUid = ba.keyAt(i); 5594 if (name != null) { 5595 if (userId == UserHandle.USER_ALL) { 5596 if (UserHandle.getAppId(entUid) == appId) { 5597 remove = true; 5598 } 5599 } else { 5600 if (entUid == UserHandle.getUid(userId, appId)) { 5601 remove = true; 5602 } 5603 } 5604 } else if (UserHandle.getUserId(entUid) == userId) { 5605 remove = true; 5606 } 5607 if (remove) { 5608 ba.removeAt(i); 5609 } 5610 } 5611 if (ba.size() == 0) { 5612 pmap.removeAt(ip); 5613 } 5614 } 5615 } 5616 5617 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5618 -100, callerWillRestart, true, doit, evenPersistent, 5619 name == null ? ("stop user " + userId) : ("stop " + name)); 5620 5621 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5622 if (!doit) { 5623 return true; 5624 } 5625 didSomething = true; 5626 } 5627 5628 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5629 if (!doit) { 5630 return true; 5631 } 5632 didSomething = true; 5633 } 5634 5635 if (name == null) { 5636 // Remove all sticky broadcasts from this user. 5637 mStickyBroadcasts.remove(userId); 5638 } 5639 5640 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5641 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5642 userId, providers)) { 5643 if (!doit) { 5644 return true; 5645 } 5646 didSomething = true; 5647 } 5648 N = providers.size(); 5649 for (i=0; i<N; i++) { 5650 removeDyingProviderLocked(null, providers.get(i), true); 5651 } 5652 5653 // Remove transient permissions granted from/to this package/user 5654 removeUriPermissionsForPackageLocked(name, userId, false); 5655 5656 if (name == null || uninstalling) { 5657 // Remove pending intents. For now we only do this when force 5658 // stopping users, because we have some problems when doing this 5659 // for packages -- app widgets are not currently cleaned up for 5660 // such packages, so they can be left with bad pending intents. 5661 if (mIntentSenderRecords.size() > 0) { 5662 Iterator<WeakReference<PendingIntentRecord>> it 5663 = mIntentSenderRecords.values().iterator(); 5664 while (it.hasNext()) { 5665 WeakReference<PendingIntentRecord> wpir = it.next(); 5666 if (wpir == null) { 5667 it.remove(); 5668 continue; 5669 } 5670 PendingIntentRecord pir = wpir.get(); 5671 if (pir == null) { 5672 it.remove(); 5673 continue; 5674 } 5675 if (name == null) { 5676 // Stopping user, remove all objects for the user. 5677 if (pir.key.userId != userId) { 5678 // Not the same user, skip it. 5679 continue; 5680 } 5681 } else { 5682 if (UserHandle.getAppId(pir.uid) != appId) { 5683 // Different app id, skip it. 5684 continue; 5685 } 5686 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5687 // Different user, skip it. 5688 continue; 5689 } 5690 if (!pir.key.packageName.equals(name)) { 5691 // Different package, skip it. 5692 continue; 5693 } 5694 } 5695 if (!doit) { 5696 return true; 5697 } 5698 didSomething = true; 5699 it.remove(); 5700 pir.canceled = true; 5701 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5702 pir.key.activity.pendingResults.remove(pir.ref); 5703 } 5704 } 5705 } 5706 } 5707 5708 if (doit) { 5709 if (purgeCache && name != null) { 5710 AttributeCache ac = AttributeCache.instance(); 5711 if (ac != null) { 5712 ac.removePackage(name); 5713 } 5714 } 5715 if (mBooted) { 5716 mStackSupervisor.resumeTopActivitiesLocked(); 5717 mStackSupervisor.scheduleIdleLocked(); 5718 } 5719 } 5720 5721 return didSomething; 5722 } 5723 5724 private final boolean removeProcessLocked(ProcessRecord app, 5725 boolean callerWillRestart, boolean allowRestart, String reason) { 5726 final String name = app.processName; 5727 final int uid = app.uid; 5728 if (DEBUG_PROCESSES) Slog.d( 5729 TAG, "Force removing proc " + app.toShortString() + " (" + name 5730 + "/" + uid + ")"); 5731 5732 mProcessNames.remove(name, uid); 5733 mIsolatedProcesses.remove(app.uid); 5734 if (mHeavyWeightProcess == app) { 5735 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5736 mHeavyWeightProcess.userId, 0)); 5737 mHeavyWeightProcess = null; 5738 } 5739 boolean needRestart = false; 5740 if (app.pid > 0 && app.pid != MY_PID) { 5741 int pid = app.pid; 5742 synchronized (mPidsSelfLocked) { 5743 mPidsSelfLocked.remove(pid); 5744 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5745 } 5746 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5747 if (app.isolated) { 5748 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5749 } 5750 app.kill(reason, true); 5751 handleAppDiedLocked(app, true, allowRestart); 5752 removeLruProcessLocked(app); 5753 5754 if (app.persistent && !app.isolated) { 5755 if (!callerWillRestart) { 5756 addAppLocked(app.info, false, null /* ABI override */); 5757 } else { 5758 needRestart = true; 5759 } 5760 } 5761 } else { 5762 mRemovedProcesses.add(app); 5763 } 5764 5765 return needRestart; 5766 } 5767 5768 private final void processStartTimedOutLocked(ProcessRecord app) { 5769 final int pid = app.pid; 5770 boolean gone = false; 5771 synchronized (mPidsSelfLocked) { 5772 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5773 if (knownApp != null && knownApp.thread == null) { 5774 mPidsSelfLocked.remove(pid); 5775 gone = true; 5776 } 5777 } 5778 5779 if (gone) { 5780 Slog.w(TAG, "Process " + app + " failed to attach"); 5781 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5782 pid, app.uid, app.processName); 5783 mProcessNames.remove(app.processName, app.uid); 5784 mIsolatedProcesses.remove(app.uid); 5785 if (mHeavyWeightProcess == app) { 5786 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5787 mHeavyWeightProcess.userId, 0)); 5788 mHeavyWeightProcess = null; 5789 } 5790 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5791 if (app.isolated) { 5792 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5793 } 5794 // Take care of any launching providers waiting for this process. 5795 checkAppInLaunchingProvidersLocked(app, true); 5796 // Take care of any services that are waiting for the process. 5797 mServices.processStartTimedOutLocked(app); 5798 app.kill("start timeout", true); 5799 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5800 Slog.w(TAG, "Unattached app died before backup, skipping"); 5801 try { 5802 IBackupManager bm = IBackupManager.Stub.asInterface( 5803 ServiceManager.getService(Context.BACKUP_SERVICE)); 5804 bm.agentDisconnected(app.info.packageName); 5805 } catch (RemoteException e) { 5806 // Can't happen; the backup manager is local 5807 } 5808 } 5809 if (isPendingBroadcastProcessLocked(pid)) { 5810 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5811 skipPendingBroadcastLocked(pid); 5812 } 5813 } else { 5814 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5815 } 5816 } 5817 5818 private final boolean attachApplicationLocked(IApplicationThread thread, 5819 int pid) { 5820 5821 // Find the application record that is being attached... either via 5822 // the pid if we are running in multiple processes, or just pull the 5823 // next app record if we are emulating process with anonymous threads. 5824 ProcessRecord app; 5825 if (pid != MY_PID && pid >= 0) { 5826 synchronized (mPidsSelfLocked) { 5827 app = mPidsSelfLocked.get(pid); 5828 } 5829 } else { 5830 app = null; 5831 } 5832 5833 if (app == null) { 5834 Slog.w(TAG, "No pending application record for pid " + pid 5835 + " (IApplicationThread " + thread + "); dropping process"); 5836 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5837 if (pid > 0 && pid != MY_PID) { 5838 Process.killProcessQuiet(pid); 5839 //TODO: Process.killProcessGroup(app.info.uid, pid); 5840 } else { 5841 try { 5842 thread.scheduleExit(); 5843 } catch (Exception e) { 5844 // Ignore exceptions. 5845 } 5846 } 5847 return false; 5848 } 5849 5850 // If this application record is still attached to a previous 5851 // process, clean it up now. 5852 if (app.thread != null) { 5853 handleAppDiedLocked(app, true, true); 5854 } 5855 5856 // Tell the process all about itself. 5857 5858 if (localLOGV) Slog.v( 5859 TAG, "Binding process pid " + pid + " to record " + app); 5860 5861 final String processName = app.processName; 5862 try { 5863 AppDeathRecipient adr = new AppDeathRecipient( 5864 app, pid, thread); 5865 thread.asBinder().linkToDeath(adr, 0); 5866 app.deathRecipient = adr; 5867 } catch (RemoteException e) { 5868 app.resetPackageList(mProcessStats); 5869 startProcessLocked(app, "link fail", processName); 5870 return false; 5871 } 5872 5873 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5874 5875 app.makeActive(thread, mProcessStats); 5876 app.curAdj = app.setAdj = -100; 5877 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5878 app.forcingToForeground = null; 5879 updateProcessForegroundLocked(app, false, false); 5880 app.hasShownUi = false; 5881 app.debugging = false; 5882 app.cached = false; 5883 5884 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5885 5886 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5887 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5888 5889 if (!normalMode) { 5890 Slog.i(TAG, "Launching preboot mode app: " + app); 5891 } 5892 5893 if (localLOGV) Slog.v( 5894 TAG, "New app record " + app 5895 + " thread=" + thread.asBinder() + " pid=" + pid); 5896 try { 5897 int testMode = IApplicationThread.DEBUG_OFF; 5898 if (mDebugApp != null && mDebugApp.equals(processName)) { 5899 testMode = mWaitForDebugger 5900 ? IApplicationThread.DEBUG_WAIT 5901 : IApplicationThread.DEBUG_ON; 5902 app.debugging = true; 5903 if (mDebugTransient) { 5904 mDebugApp = mOrigDebugApp; 5905 mWaitForDebugger = mOrigWaitForDebugger; 5906 } 5907 } 5908 String profileFile = app.instrumentationProfileFile; 5909 ParcelFileDescriptor profileFd = null; 5910 int samplingInterval = 0; 5911 boolean profileAutoStop = false; 5912 if (mProfileApp != null && mProfileApp.equals(processName)) { 5913 mProfileProc = app; 5914 profileFile = mProfileFile; 5915 profileFd = mProfileFd; 5916 samplingInterval = mSamplingInterval; 5917 profileAutoStop = mAutoStopProfiler; 5918 } 5919 boolean enableOpenGlTrace = false; 5920 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5921 enableOpenGlTrace = true; 5922 mOpenGlTraceApp = null; 5923 } 5924 5925 // If the app is being launched for restore or full backup, set it up specially 5926 boolean isRestrictedBackupMode = false; 5927 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5928 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5929 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5930 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5931 } 5932 5933 ensurePackageDexOpt(app.instrumentationInfo != null 5934 ? app.instrumentationInfo.packageName 5935 : app.info.packageName); 5936 if (app.instrumentationClass != null) { 5937 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5938 } 5939 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5940 + processName + " with config " + mConfiguration); 5941 ApplicationInfo appInfo = app.instrumentationInfo != null 5942 ? app.instrumentationInfo : app.info; 5943 app.compat = compatibilityInfoForPackageLocked(appInfo); 5944 if (profileFd != null) { 5945 profileFd = profileFd.dup(); 5946 } 5947 ProfilerInfo profilerInfo = profileFile == null ? null 5948 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5949 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5950 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5951 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5952 isRestrictedBackupMode || !normalMode, app.persistent, 5953 new Configuration(mConfiguration), app.compat, 5954 getCommonServicesLocked(app.isolated), 5955 mCoreSettingsObserver.getCoreSettingsLocked()); 5956 updateLruProcessLocked(app, false, null); 5957 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5958 } catch (Exception e) { 5959 // todo: Yikes! What should we do? For now we will try to 5960 // start another process, but that could easily get us in 5961 // an infinite loop of restarting processes... 5962 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5963 5964 app.resetPackageList(mProcessStats); 5965 app.unlinkDeathRecipient(); 5966 startProcessLocked(app, "bind fail", processName); 5967 return false; 5968 } 5969 5970 // Remove this record from the list of starting applications. 5971 mPersistentStartingProcesses.remove(app); 5972 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5973 "Attach application locked removing on hold: " + app); 5974 mProcessesOnHold.remove(app); 5975 5976 boolean badApp = false; 5977 boolean didSomething = false; 5978 5979 // See if the top visible activity is waiting to run in this process... 5980 if (normalMode) { 5981 try { 5982 if (mStackSupervisor.attachApplicationLocked(app)) { 5983 didSomething = true; 5984 } 5985 } catch (Exception e) { 5986 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5987 badApp = true; 5988 } 5989 } 5990 5991 // Find any services that should be running in this process... 5992 if (!badApp) { 5993 try { 5994 didSomething |= mServices.attachApplicationLocked(app, processName); 5995 } catch (Exception e) { 5996 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5997 badApp = true; 5998 } 5999 } 6000 6001 // Check if a next-broadcast receiver is in this process... 6002 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6003 try { 6004 didSomething |= sendPendingBroadcastsLocked(app); 6005 } catch (Exception e) { 6006 // If the app died trying to launch the receiver we declare it 'bad' 6007 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6008 badApp = true; 6009 } 6010 } 6011 6012 // Check whether the next backup agent is in this process... 6013 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6014 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6015 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6016 try { 6017 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6018 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6019 mBackupTarget.backupMode); 6020 } catch (Exception e) { 6021 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6022 badApp = true; 6023 } 6024 } 6025 6026 if (badApp) { 6027 app.kill("error during init", true); 6028 handleAppDiedLocked(app, false, true); 6029 return false; 6030 } 6031 6032 if (!didSomething) { 6033 updateOomAdjLocked(); 6034 } 6035 6036 return true; 6037 } 6038 6039 @Override 6040 public final void attachApplication(IApplicationThread thread) { 6041 synchronized (this) { 6042 int callingPid = Binder.getCallingPid(); 6043 final long origId = Binder.clearCallingIdentity(); 6044 attachApplicationLocked(thread, callingPid); 6045 Binder.restoreCallingIdentity(origId); 6046 } 6047 } 6048 6049 @Override 6050 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6051 final long origId = Binder.clearCallingIdentity(); 6052 synchronized (this) { 6053 ActivityStack stack = ActivityRecord.getStackLocked(token); 6054 if (stack != null) { 6055 ActivityRecord r = 6056 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6057 if (stopProfiling) { 6058 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6059 try { 6060 mProfileFd.close(); 6061 } catch (IOException e) { 6062 } 6063 clearProfilerLocked(); 6064 } 6065 } 6066 } 6067 } 6068 Binder.restoreCallingIdentity(origId); 6069 } 6070 6071 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6072 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6073 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6074 } 6075 6076 void enableScreenAfterBoot() { 6077 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6078 SystemClock.uptimeMillis()); 6079 mWindowManager.enableScreenAfterBoot(); 6080 6081 synchronized (this) { 6082 updateEventDispatchingLocked(); 6083 } 6084 } 6085 6086 @Override 6087 public void showBootMessage(final CharSequence msg, final boolean always) { 6088 enforceNotIsolatedCaller("showBootMessage"); 6089 mWindowManager.showBootMessage(msg, always); 6090 } 6091 6092 @Override 6093 public void keyguardWaitingForActivityDrawn() { 6094 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6095 final long token = Binder.clearCallingIdentity(); 6096 try { 6097 synchronized (this) { 6098 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6099 mWindowManager.keyguardWaitingForActivityDrawn(); 6100 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6101 mLockScreenShown = LOCK_SCREEN_LEAVING; 6102 updateSleepIfNeededLocked(); 6103 } 6104 } 6105 } finally { 6106 Binder.restoreCallingIdentity(token); 6107 } 6108 } 6109 6110 final void finishBooting() { 6111 synchronized (this) { 6112 if (!mBootAnimationComplete) { 6113 mCallFinishBooting = true; 6114 return; 6115 } 6116 mCallFinishBooting = false; 6117 } 6118 6119 ArraySet<String> completedIsas = new ArraySet<String>(); 6120 for (String abi : Build.SUPPORTED_ABIS) { 6121 Process.establishZygoteConnectionForAbi(abi); 6122 final String instructionSet = VMRuntime.getInstructionSet(abi); 6123 if (!completedIsas.contains(instructionSet)) { 6124 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6125 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6126 } 6127 completedIsas.add(instructionSet); 6128 } 6129 } 6130 6131 IntentFilter pkgFilter = new IntentFilter(); 6132 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6133 pkgFilter.addDataScheme("package"); 6134 mContext.registerReceiver(new BroadcastReceiver() { 6135 @Override 6136 public void onReceive(Context context, Intent intent) { 6137 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6138 if (pkgs != null) { 6139 for (String pkg : pkgs) { 6140 synchronized (ActivityManagerService.this) { 6141 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6142 0, "finished booting")) { 6143 setResultCode(Activity.RESULT_OK); 6144 return; 6145 } 6146 } 6147 } 6148 } 6149 } 6150 }, pkgFilter); 6151 6152 // Let system services know. 6153 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6154 6155 synchronized (this) { 6156 // Ensure that any processes we had put on hold are now started 6157 // up. 6158 final int NP = mProcessesOnHold.size(); 6159 if (NP > 0) { 6160 ArrayList<ProcessRecord> procs = 6161 new ArrayList<ProcessRecord>(mProcessesOnHold); 6162 for (int ip=0; ip<NP; ip++) { 6163 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6164 + procs.get(ip)); 6165 startProcessLocked(procs.get(ip), "on-hold", null); 6166 } 6167 } 6168 6169 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6170 // Start looking for apps that are abusing wake locks. 6171 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6172 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6173 // Tell anyone interested that we are done booting! 6174 SystemProperties.set("sys.boot_completed", "1"); 6175 6176 // And trigger dev.bootcomplete if we are not showing encryption progress 6177 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6178 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6179 SystemProperties.set("dev.bootcomplete", "1"); 6180 } 6181 for (int i=0; i<mStartedUsers.size(); i++) { 6182 UserStartedState uss = mStartedUsers.valueAt(i); 6183 if (uss.mState == UserStartedState.STATE_BOOTING) { 6184 uss.mState = UserStartedState.STATE_RUNNING; 6185 final int userId = mStartedUsers.keyAt(i); 6186 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6187 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6188 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6189 broadcastIntentLocked(null, null, intent, null, 6190 new IIntentReceiver.Stub() { 6191 @Override 6192 public void performReceive(Intent intent, int resultCode, 6193 String data, Bundle extras, boolean ordered, 6194 boolean sticky, int sendingUser) { 6195 synchronized (ActivityManagerService.this) { 6196 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6197 true, false); 6198 } 6199 } 6200 }, 6201 0, null, null, 6202 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6203 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6204 userId); 6205 } 6206 } 6207 scheduleStartProfilesLocked(); 6208 } 6209 } 6210 } 6211 6212 @Override 6213 public void bootAnimationComplete() { 6214 final boolean callFinishBooting; 6215 synchronized (this) { 6216 callFinishBooting = mCallFinishBooting; 6217 mBootAnimationComplete = true; 6218 } 6219 if (callFinishBooting) { 6220 finishBooting(); 6221 } 6222 } 6223 6224 @Override 6225 public void systemBackupRestored() { 6226 synchronized (this) { 6227 if (mSystemReady) { 6228 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6229 } else { 6230 Slog.w(TAG, "System backup restored before system is ready"); 6231 } 6232 } 6233 } 6234 6235 final void ensureBootCompleted() { 6236 boolean booting; 6237 boolean enableScreen; 6238 synchronized (this) { 6239 booting = mBooting; 6240 mBooting = false; 6241 enableScreen = !mBooted; 6242 mBooted = true; 6243 } 6244 6245 if (booting) { 6246 finishBooting(); 6247 } 6248 6249 if (enableScreen) { 6250 enableScreenAfterBoot(); 6251 } 6252 } 6253 6254 @Override 6255 public final void activityResumed(IBinder token) { 6256 final long origId = Binder.clearCallingIdentity(); 6257 synchronized(this) { 6258 ActivityStack stack = ActivityRecord.getStackLocked(token); 6259 if (stack != null) { 6260 ActivityRecord.activityResumedLocked(token); 6261 } 6262 } 6263 Binder.restoreCallingIdentity(origId); 6264 } 6265 6266 @Override 6267 public final void activityPaused(IBinder token) { 6268 final long origId = Binder.clearCallingIdentity(); 6269 synchronized(this) { 6270 ActivityStack stack = ActivityRecord.getStackLocked(token); 6271 if (stack != null) { 6272 stack.activityPausedLocked(token, false); 6273 } 6274 } 6275 Binder.restoreCallingIdentity(origId); 6276 } 6277 6278 @Override 6279 public final void activityStopped(IBinder token, Bundle icicle, 6280 PersistableBundle persistentState, CharSequence description) { 6281 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6282 6283 // Refuse possible leaked file descriptors 6284 if (icicle != null && icicle.hasFileDescriptors()) { 6285 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6286 } 6287 6288 final long origId = Binder.clearCallingIdentity(); 6289 6290 synchronized (this) { 6291 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6292 if (r != null) { 6293 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6294 } 6295 } 6296 6297 trimApplications(); 6298 6299 Binder.restoreCallingIdentity(origId); 6300 } 6301 6302 @Override 6303 public final void activityDestroyed(IBinder token) { 6304 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6305 synchronized (this) { 6306 ActivityStack stack = ActivityRecord.getStackLocked(token); 6307 if (stack != null) { 6308 stack.activityDestroyedLocked(token); 6309 } 6310 } 6311 } 6312 6313 @Override 6314 public final void backgroundResourcesReleased(IBinder token) { 6315 final long origId = Binder.clearCallingIdentity(); 6316 try { 6317 synchronized (this) { 6318 ActivityStack stack = ActivityRecord.getStackLocked(token); 6319 if (stack != null) { 6320 stack.backgroundResourcesReleased(); 6321 } 6322 } 6323 } finally { 6324 Binder.restoreCallingIdentity(origId); 6325 } 6326 } 6327 6328 @Override 6329 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6330 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6331 } 6332 6333 @Override 6334 public final void notifyEnterAnimationComplete(IBinder token) { 6335 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6336 } 6337 6338 @Override 6339 public String getCallingPackage(IBinder token) { 6340 synchronized (this) { 6341 ActivityRecord r = getCallingRecordLocked(token); 6342 return r != null ? r.info.packageName : null; 6343 } 6344 } 6345 6346 @Override 6347 public ComponentName getCallingActivity(IBinder token) { 6348 synchronized (this) { 6349 ActivityRecord r = getCallingRecordLocked(token); 6350 return r != null ? r.intent.getComponent() : null; 6351 } 6352 } 6353 6354 private ActivityRecord getCallingRecordLocked(IBinder token) { 6355 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6356 if (r == null) { 6357 return null; 6358 } 6359 return r.resultTo; 6360 } 6361 6362 @Override 6363 public ComponentName getActivityClassForToken(IBinder token) { 6364 synchronized(this) { 6365 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6366 if (r == null) { 6367 return null; 6368 } 6369 return r.intent.getComponent(); 6370 } 6371 } 6372 6373 @Override 6374 public String getPackageForToken(IBinder token) { 6375 synchronized(this) { 6376 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6377 if (r == null) { 6378 return null; 6379 } 6380 return r.packageName; 6381 } 6382 } 6383 6384 @Override 6385 public IIntentSender getIntentSender(int type, 6386 String packageName, IBinder token, String resultWho, 6387 int requestCode, Intent[] intents, String[] resolvedTypes, 6388 int flags, Bundle options, int userId) { 6389 enforceNotIsolatedCaller("getIntentSender"); 6390 // Refuse possible leaked file descriptors 6391 if (intents != null) { 6392 if (intents.length < 1) { 6393 throw new IllegalArgumentException("Intents array length must be >= 1"); 6394 } 6395 for (int i=0; i<intents.length; i++) { 6396 Intent intent = intents[i]; 6397 if (intent != null) { 6398 if (intent.hasFileDescriptors()) { 6399 throw new IllegalArgumentException("File descriptors passed in Intent"); 6400 } 6401 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6402 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6403 throw new IllegalArgumentException( 6404 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6405 } 6406 intents[i] = new Intent(intent); 6407 } 6408 } 6409 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6410 throw new IllegalArgumentException( 6411 "Intent array length does not match resolvedTypes length"); 6412 } 6413 } 6414 if (options != null) { 6415 if (options.hasFileDescriptors()) { 6416 throw new IllegalArgumentException("File descriptors passed in options"); 6417 } 6418 } 6419 6420 synchronized(this) { 6421 int callingUid = Binder.getCallingUid(); 6422 int origUserId = userId; 6423 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6424 type == ActivityManager.INTENT_SENDER_BROADCAST, 6425 ALLOW_NON_FULL, "getIntentSender", null); 6426 if (origUserId == UserHandle.USER_CURRENT) { 6427 // We don't want to evaluate this until the pending intent is 6428 // actually executed. However, we do want to always do the 6429 // security checking for it above. 6430 userId = UserHandle.USER_CURRENT; 6431 } 6432 try { 6433 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6434 int uid = AppGlobals.getPackageManager() 6435 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6436 if (!UserHandle.isSameApp(callingUid, uid)) { 6437 String msg = "Permission Denial: getIntentSender() from pid=" 6438 + Binder.getCallingPid() 6439 + ", uid=" + Binder.getCallingUid() 6440 + ", (need uid=" + uid + ")" 6441 + " is not allowed to send as package " + packageName; 6442 Slog.w(TAG, msg); 6443 throw new SecurityException(msg); 6444 } 6445 } 6446 6447 return getIntentSenderLocked(type, packageName, callingUid, userId, 6448 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6449 6450 } catch (RemoteException e) { 6451 throw new SecurityException(e); 6452 } 6453 } 6454 } 6455 6456 IIntentSender getIntentSenderLocked(int type, String packageName, 6457 int callingUid, int userId, IBinder token, String resultWho, 6458 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6459 Bundle options) { 6460 if (DEBUG_MU) 6461 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6462 ActivityRecord activity = null; 6463 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6464 activity = ActivityRecord.isInStackLocked(token); 6465 if (activity == null) { 6466 return null; 6467 } 6468 if (activity.finishing) { 6469 return null; 6470 } 6471 } 6472 6473 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6474 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6475 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6476 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6477 |PendingIntent.FLAG_UPDATE_CURRENT); 6478 6479 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6480 type, packageName, activity, resultWho, 6481 requestCode, intents, resolvedTypes, flags, options, userId); 6482 WeakReference<PendingIntentRecord> ref; 6483 ref = mIntentSenderRecords.get(key); 6484 PendingIntentRecord rec = ref != null ? ref.get() : null; 6485 if (rec != null) { 6486 if (!cancelCurrent) { 6487 if (updateCurrent) { 6488 if (rec.key.requestIntent != null) { 6489 rec.key.requestIntent.replaceExtras(intents != null ? 6490 intents[intents.length - 1] : null); 6491 } 6492 if (intents != null) { 6493 intents[intents.length-1] = rec.key.requestIntent; 6494 rec.key.allIntents = intents; 6495 rec.key.allResolvedTypes = resolvedTypes; 6496 } else { 6497 rec.key.allIntents = null; 6498 rec.key.allResolvedTypes = null; 6499 } 6500 } 6501 return rec; 6502 } 6503 rec.canceled = true; 6504 mIntentSenderRecords.remove(key); 6505 } 6506 if (noCreate) { 6507 return rec; 6508 } 6509 rec = new PendingIntentRecord(this, key, callingUid); 6510 mIntentSenderRecords.put(key, rec.ref); 6511 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6512 if (activity.pendingResults == null) { 6513 activity.pendingResults 6514 = new HashSet<WeakReference<PendingIntentRecord>>(); 6515 } 6516 activity.pendingResults.add(rec.ref); 6517 } 6518 return rec; 6519 } 6520 6521 @Override 6522 public void cancelIntentSender(IIntentSender sender) { 6523 if (!(sender instanceof PendingIntentRecord)) { 6524 return; 6525 } 6526 synchronized(this) { 6527 PendingIntentRecord rec = (PendingIntentRecord)sender; 6528 try { 6529 int uid = AppGlobals.getPackageManager() 6530 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6531 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6532 String msg = "Permission Denial: cancelIntentSender() from pid=" 6533 + Binder.getCallingPid() 6534 + ", uid=" + Binder.getCallingUid() 6535 + " is not allowed to cancel packges " 6536 + rec.key.packageName; 6537 Slog.w(TAG, msg); 6538 throw new SecurityException(msg); 6539 } 6540 } catch (RemoteException e) { 6541 throw new SecurityException(e); 6542 } 6543 cancelIntentSenderLocked(rec, true); 6544 } 6545 } 6546 6547 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6548 rec.canceled = true; 6549 mIntentSenderRecords.remove(rec.key); 6550 if (cleanActivity && rec.key.activity != null) { 6551 rec.key.activity.pendingResults.remove(rec.ref); 6552 } 6553 } 6554 6555 @Override 6556 public String getPackageForIntentSender(IIntentSender pendingResult) { 6557 if (!(pendingResult instanceof PendingIntentRecord)) { 6558 return null; 6559 } 6560 try { 6561 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6562 return res.key.packageName; 6563 } catch (ClassCastException e) { 6564 } 6565 return null; 6566 } 6567 6568 @Override 6569 public int getUidForIntentSender(IIntentSender sender) { 6570 if (sender instanceof PendingIntentRecord) { 6571 try { 6572 PendingIntentRecord res = (PendingIntentRecord)sender; 6573 return res.uid; 6574 } catch (ClassCastException e) { 6575 } 6576 } 6577 return -1; 6578 } 6579 6580 @Override 6581 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6582 if (!(pendingResult instanceof PendingIntentRecord)) { 6583 return false; 6584 } 6585 try { 6586 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6587 if (res.key.allIntents == null) { 6588 return false; 6589 } 6590 for (int i=0; i<res.key.allIntents.length; i++) { 6591 Intent intent = res.key.allIntents[i]; 6592 if (intent.getPackage() != null && intent.getComponent() != null) { 6593 return false; 6594 } 6595 } 6596 return true; 6597 } catch (ClassCastException e) { 6598 } 6599 return false; 6600 } 6601 6602 @Override 6603 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6604 if (!(pendingResult instanceof PendingIntentRecord)) { 6605 return false; 6606 } 6607 try { 6608 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6609 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6610 return true; 6611 } 6612 return false; 6613 } catch (ClassCastException e) { 6614 } 6615 return false; 6616 } 6617 6618 @Override 6619 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6620 if (!(pendingResult instanceof PendingIntentRecord)) { 6621 return null; 6622 } 6623 try { 6624 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6625 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6626 } catch (ClassCastException e) { 6627 } 6628 return null; 6629 } 6630 6631 @Override 6632 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6633 if (!(pendingResult instanceof PendingIntentRecord)) { 6634 return null; 6635 } 6636 try { 6637 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6638 Intent intent = res.key.requestIntent; 6639 if (intent != null) { 6640 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6641 || res.lastTagPrefix.equals(prefix))) { 6642 return res.lastTag; 6643 } 6644 res.lastTagPrefix = prefix; 6645 StringBuilder sb = new StringBuilder(128); 6646 if (prefix != null) { 6647 sb.append(prefix); 6648 } 6649 if (intent.getAction() != null) { 6650 sb.append(intent.getAction()); 6651 } else if (intent.getComponent() != null) { 6652 intent.getComponent().appendShortString(sb); 6653 } else { 6654 sb.append("?"); 6655 } 6656 return res.lastTag = sb.toString(); 6657 } 6658 } catch (ClassCastException e) { 6659 } 6660 return null; 6661 } 6662 6663 @Override 6664 public void setProcessLimit(int max) { 6665 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6666 "setProcessLimit()"); 6667 synchronized (this) { 6668 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6669 mProcessLimitOverride = max; 6670 } 6671 trimApplications(); 6672 } 6673 6674 @Override 6675 public int getProcessLimit() { 6676 synchronized (this) { 6677 return mProcessLimitOverride; 6678 } 6679 } 6680 6681 void foregroundTokenDied(ForegroundToken token) { 6682 synchronized (ActivityManagerService.this) { 6683 synchronized (mPidsSelfLocked) { 6684 ForegroundToken cur 6685 = mForegroundProcesses.get(token.pid); 6686 if (cur != token) { 6687 return; 6688 } 6689 mForegroundProcesses.remove(token.pid); 6690 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6691 if (pr == null) { 6692 return; 6693 } 6694 pr.forcingToForeground = null; 6695 updateProcessForegroundLocked(pr, false, false); 6696 } 6697 updateOomAdjLocked(); 6698 } 6699 } 6700 6701 @Override 6702 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6703 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6704 "setProcessForeground()"); 6705 synchronized(this) { 6706 boolean changed = false; 6707 6708 synchronized (mPidsSelfLocked) { 6709 ProcessRecord pr = mPidsSelfLocked.get(pid); 6710 if (pr == null && isForeground) { 6711 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6712 return; 6713 } 6714 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6715 if (oldToken != null) { 6716 oldToken.token.unlinkToDeath(oldToken, 0); 6717 mForegroundProcesses.remove(pid); 6718 if (pr != null) { 6719 pr.forcingToForeground = null; 6720 } 6721 changed = true; 6722 } 6723 if (isForeground && token != null) { 6724 ForegroundToken newToken = new ForegroundToken() { 6725 @Override 6726 public void binderDied() { 6727 foregroundTokenDied(this); 6728 } 6729 }; 6730 newToken.pid = pid; 6731 newToken.token = token; 6732 try { 6733 token.linkToDeath(newToken, 0); 6734 mForegroundProcesses.put(pid, newToken); 6735 pr.forcingToForeground = token; 6736 changed = true; 6737 } catch (RemoteException e) { 6738 // If the process died while doing this, we will later 6739 // do the cleanup with the process death link. 6740 } 6741 } 6742 } 6743 6744 if (changed) { 6745 updateOomAdjLocked(); 6746 } 6747 } 6748 } 6749 6750 // ========================================================= 6751 // PERMISSIONS 6752 // ========================================================= 6753 6754 static class PermissionController extends IPermissionController.Stub { 6755 ActivityManagerService mActivityManagerService; 6756 PermissionController(ActivityManagerService activityManagerService) { 6757 mActivityManagerService = activityManagerService; 6758 } 6759 6760 @Override 6761 public boolean checkPermission(String permission, int pid, int uid) { 6762 return mActivityManagerService.checkPermission(permission, pid, 6763 uid) == PackageManager.PERMISSION_GRANTED; 6764 } 6765 } 6766 6767 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6768 @Override 6769 public int checkComponentPermission(String permission, int pid, int uid, 6770 int owningUid, boolean exported) { 6771 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6772 owningUid, exported); 6773 } 6774 6775 @Override 6776 public Object getAMSLock() { 6777 return ActivityManagerService.this; 6778 } 6779 } 6780 6781 /** 6782 * This can be called with or without the global lock held. 6783 */ 6784 int checkComponentPermission(String permission, int pid, int uid, 6785 int owningUid, boolean exported) { 6786 if (pid == MY_PID) { 6787 return PackageManager.PERMISSION_GRANTED; 6788 } 6789 return ActivityManager.checkComponentPermission(permission, uid, 6790 owningUid, exported); 6791 } 6792 6793 /** 6794 * As the only public entry point for permissions checking, this method 6795 * can enforce the semantic that requesting a check on a null global 6796 * permission is automatically denied. (Internally a null permission 6797 * string is used when calling {@link #checkComponentPermission} in cases 6798 * when only uid-based security is needed.) 6799 * 6800 * This can be called with or without the global lock held. 6801 */ 6802 @Override 6803 public int checkPermission(String permission, int pid, int uid) { 6804 if (permission == null) { 6805 return PackageManager.PERMISSION_DENIED; 6806 } 6807 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6808 } 6809 6810 @Override 6811 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6812 if (permission == null) { 6813 return PackageManager.PERMISSION_DENIED; 6814 } 6815 6816 // We might be performing an operation on behalf of an indirect binder 6817 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6818 // client identity accordingly before proceeding. 6819 Identity tlsIdentity = sCallerIdentity.get(); 6820 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6821 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6822 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6823 uid = tlsIdentity.uid; 6824 pid = tlsIdentity.pid; 6825 } 6826 6827 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6828 } 6829 6830 /** 6831 * Binder IPC calls go through the public entry point. 6832 * This can be called with or without the global lock held. 6833 */ 6834 int checkCallingPermission(String permission) { 6835 return checkPermission(permission, 6836 Binder.getCallingPid(), 6837 UserHandle.getAppId(Binder.getCallingUid())); 6838 } 6839 6840 /** 6841 * This can be called with or without the global lock held. 6842 */ 6843 void enforceCallingPermission(String permission, String func) { 6844 if (checkCallingPermission(permission) 6845 == PackageManager.PERMISSION_GRANTED) { 6846 return; 6847 } 6848 6849 String msg = "Permission Denial: " + func + " from pid=" 6850 + Binder.getCallingPid() 6851 + ", uid=" + Binder.getCallingUid() 6852 + " requires " + permission; 6853 Slog.w(TAG, msg); 6854 throw new SecurityException(msg); 6855 } 6856 6857 /** 6858 * Determine if UID is holding permissions required to access {@link Uri} in 6859 * the given {@link ProviderInfo}. Final permission checking is always done 6860 * in {@link ContentProvider}. 6861 */ 6862 private final boolean checkHoldingPermissionsLocked( 6863 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6864 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6865 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6866 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6867 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6868 != PERMISSION_GRANTED) { 6869 return false; 6870 } 6871 } 6872 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6873 } 6874 6875 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6876 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6877 if (pi.applicationInfo.uid == uid) { 6878 return true; 6879 } else if (!pi.exported) { 6880 return false; 6881 } 6882 6883 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6884 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6885 try { 6886 // check if target holds top-level <provider> permissions 6887 if (!readMet && pi.readPermission != null && considerUidPermissions 6888 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6889 readMet = true; 6890 } 6891 if (!writeMet && pi.writePermission != null && considerUidPermissions 6892 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6893 writeMet = true; 6894 } 6895 6896 // track if unprotected read/write is allowed; any denied 6897 // <path-permission> below removes this ability 6898 boolean allowDefaultRead = pi.readPermission == null; 6899 boolean allowDefaultWrite = pi.writePermission == null; 6900 6901 // check if target holds any <path-permission> that match uri 6902 final PathPermission[] pps = pi.pathPermissions; 6903 if (pps != null) { 6904 final String path = grantUri.uri.getPath(); 6905 int i = pps.length; 6906 while (i > 0 && (!readMet || !writeMet)) { 6907 i--; 6908 PathPermission pp = pps[i]; 6909 if (pp.match(path)) { 6910 if (!readMet) { 6911 final String pprperm = pp.getReadPermission(); 6912 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6913 + pprperm + " for " + pp.getPath() 6914 + ": match=" + pp.match(path) 6915 + " check=" + pm.checkUidPermission(pprperm, uid)); 6916 if (pprperm != null) { 6917 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6918 == PERMISSION_GRANTED) { 6919 readMet = true; 6920 } else { 6921 allowDefaultRead = false; 6922 } 6923 } 6924 } 6925 if (!writeMet) { 6926 final String ppwperm = pp.getWritePermission(); 6927 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6928 + ppwperm + " for " + pp.getPath() 6929 + ": match=" + pp.match(path) 6930 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6931 if (ppwperm != null) { 6932 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6933 == PERMISSION_GRANTED) { 6934 writeMet = true; 6935 } else { 6936 allowDefaultWrite = false; 6937 } 6938 } 6939 } 6940 } 6941 } 6942 } 6943 6944 // grant unprotected <provider> read/write, if not blocked by 6945 // <path-permission> above 6946 if (allowDefaultRead) readMet = true; 6947 if (allowDefaultWrite) writeMet = true; 6948 6949 } catch (RemoteException e) { 6950 return false; 6951 } 6952 6953 return readMet && writeMet; 6954 } 6955 6956 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6957 ProviderInfo pi = null; 6958 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6959 if (cpr != null) { 6960 pi = cpr.info; 6961 } else { 6962 try { 6963 pi = AppGlobals.getPackageManager().resolveContentProvider( 6964 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6965 } catch (RemoteException ex) { 6966 } 6967 } 6968 return pi; 6969 } 6970 6971 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6972 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6973 if (targetUris != null) { 6974 return targetUris.get(grantUri); 6975 } 6976 return null; 6977 } 6978 6979 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6980 String targetPkg, int targetUid, GrantUri grantUri) { 6981 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6982 if (targetUris == null) { 6983 targetUris = Maps.newArrayMap(); 6984 mGrantedUriPermissions.put(targetUid, targetUris); 6985 } 6986 6987 UriPermission perm = targetUris.get(grantUri); 6988 if (perm == null) { 6989 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6990 targetUris.put(grantUri, perm); 6991 } 6992 6993 return perm; 6994 } 6995 6996 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6997 final int modeFlags) { 6998 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6999 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7000 : UriPermission.STRENGTH_OWNED; 7001 7002 // Root gets to do everything. 7003 if (uid == 0) { 7004 return true; 7005 } 7006 7007 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7008 if (perms == null) return false; 7009 7010 // First look for exact match 7011 final UriPermission exactPerm = perms.get(grantUri); 7012 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7013 return true; 7014 } 7015 7016 // No exact match, look for prefixes 7017 final int N = perms.size(); 7018 for (int i = 0; i < N; i++) { 7019 final UriPermission perm = perms.valueAt(i); 7020 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7021 && perm.getStrength(modeFlags) >= minStrength) { 7022 return true; 7023 } 7024 } 7025 7026 return false; 7027 } 7028 7029 /** 7030 * @param uri This uri must NOT contain an embedded userId. 7031 * @param userId The userId in which the uri is to be resolved. 7032 */ 7033 @Override 7034 public int checkUriPermission(Uri uri, int pid, int uid, 7035 final int modeFlags, int userId, IBinder callerToken) { 7036 enforceNotIsolatedCaller("checkUriPermission"); 7037 7038 // Another redirected-binder-call permissions check as in 7039 // {@link checkPermissionWithToken}. 7040 Identity tlsIdentity = sCallerIdentity.get(); 7041 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7042 uid = tlsIdentity.uid; 7043 pid = tlsIdentity.pid; 7044 } 7045 7046 // Our own process gets to do everything. 7047 if (pid == MY_PID) { 7048 return PackageManager.PERMISSION_GRANTED; 7049 } 7050 synchronized (this) { 7051 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7052 ? PackageManager.PERMISSION_GRANTED 7053 : PackageManager.PERMISSION_DENIED; 7054 } 7055 } 7056 7057 /** 7058 * Check if the targetPkg can be granted permission to access uri by 7059 * the callingUid using the given modeFlags. Throws a security exception 7060 * if callingUid is not allowed to do this. Returns the uid of the target 7061 * if the URI permission grant should be performed; returns -1 if it is not 7062 * needed (for example targetPkg already has permission to access the URI). 7063 * If you already know the uid of the target, you can supply it in 7064 * lastTargetUid else set that to -1. 7065 */ 7066 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7067 final int modeFlags, int lastTargetUid) { 7068 if (!Intent.isAccessUriMode(modeFlags)) { 7069 return -1; 7070 } 7071 7072 if (targetPkg != null) { 7073 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7074 "Checking grant " + targetPkg + " permission to " + grantUri); 7075 } 7076 7077 final IPackageManager pm = AppGlobals.getPackageManager(); 7078 7079 // If this is not a content: uri, we can't do anything with it. 7080 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7082 "Can't grant URI permission for non-content URI: " + grantUri); 7083 return -1; 7084 } 7085 7086 final String authority = grantUri.uri.getAuthority(); 7087 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7088 if (pi == null) { 7089 Slog.w(TAG, "No content provider found for permission check: " + 7090 grantUri.uri.toSafeString()); 7091 return -1; 7092 } 7093 7094 int targetUid = lastTargetUid; 7095 if (targetUid < 0 && targetPkg != null) { 7096 try { 7097 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7098 if (targetUid < 0) { 7099 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7100 "Can't grant URI permission no uid for: " + targetPkg); 7101 return -1; 7102 } 7103 } catch (RemoteException ex) { 7104 return -1; 7105 } 7106 } 7107 7108 if (targetUid >= 0) { 7109 // First... does the target actually need this permission? 7110 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7111 // No need to grant the target this permission. 7112 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7113 "Target " + targetPkg + " already has full permission to " + grantUri); 7114 return -1; 7115 } 7116 } else { 7117 // First... there is no target package, so can anyone access it? 7118 boolean allowed = pi.exported; 7119 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7120 if (pi.readPermission != null) { 7121 allowed = false; 7122 } 7123 } 7124 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7125 if (pi.writePermission != null) { 7126 allowed = false; 7127 } 7128 } 7129 if (allowed) { 7130 return -1; 7131 } 7132 } 7133 7134 /* There is a special cross user grant if: 7135 * - The target is on another user. 7136 * - Apps on the current user can access the uri without any uid permissions. 7137 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7138 * grant uri permissions. 7139 */ 7140 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7141 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7142 modeFlags, false /*without considering the uid permissions*/); 7143 7144 // Second... is the provider allowing granting of URI permissions? 7145 if (!specialCrossUserGrant) { 7146 if (!pi.grantUriPermissions) { 7147 throw new SecurityException("Provider " + pi.packageName 7148 + "/" + pi.name 7149 + " does not allow granting of Uri permissions (uri " 7150 + grantUri + ")"); 7151 } 7152 if (pi.uriPermissionPatterns != null) { 7153 final int N = pi.uriPermissionPatterns.length; 7154 boolean allowed = false; 7155 for (int i=0; i<N; i++) { 7156 if (pi.uriPermissionPatterns[i] != null 7157 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7158 allowed = true; 7159 break; 7160 } 7161 } 7162 if (!allowed) { 7163 throw new SecurityException("Provider " + pi.packageName 7164 + "/" + pi.name 7165 + " does not allow granting of permission to path of Uri " 7166 + grantUri); 7167 } 7168 } 7169 } 7170 7171 // Third... does the caller itself have permission to access 7172 // this uri? 7173 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7174 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7175 // Require they hold a strong enough Uri permission 7176 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7177 throw new SecurityException("Uid " + callingUid 7178 + " does not have permission to uri " + grantUri); 7179 } 7180 } 7181 } 7182 return targetUid; 7183 } 7184 7185 /** 7186 * @param uri This uri must NOT contain an embedded userId. 7187 * @param userId The userId in which the uri is to be resolved. 7188 */ 7189 @Override 7190 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7191 final int modeFlags, int userId) { 7192 enforceNotIsolatedCaller("checkGrantUriPermission"); 7193 synchronized(this) { 7194 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7195 new GrantUri(userId, uri, false), modeFlags, -1); 7196 } 7197 } 7198 7199 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7200 final int modeFlags, UriPermissionOwner owner) { 7201 if (!Intent.isAccessUriMode(modeFlags)) { 7202 return; 7203 } 7204 7205 // So here we are: the caller has the assumed permission 7206 // to the uri, and the target doesn't. Let's now give this to 7207 // the target. 7208 7209 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7210 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7211 7212 final String authority = grantUri.uri.getAuthority(); 7213 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7214 if (pi == null) { 7215 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7216 return; 7217 } 7218 7219 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7220 grantUri.prefix = true; 7221 } 7222 final UriPermission perm = findOrCreateUriPermissionLocked( 7223 pi.packageName, targetPkg, targetUid, grantUri); 7224 perm.grantModes(modeFlags, owner); 7225 } 7226 7227 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7228 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7229 if (targetPkg == null) { 7230 throw new NullPointerException("targetPkg"); 7231 } 7232 int targetUid; 7233 final IPackageManager pm = AppGlobals.getPackageManager(); 7234 try { 7235 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7236 } catch (RemoteException ex) { 7237 return; 7238 } 7239 7240 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7241 targetUid); 7242 if (targetUid < 0) { 7243 return; 7244 } 7245 7246 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7247 owner); 7248 } 7249 7250 static class NeededUriGrants extends ArrayList<GrantUri> { 7251 final String targetPkg; 7252 final int targetUid; 7253 final int flags; 7254 7255 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7256 this.targetPkg = targetPkg; 7257 this.targetUid = targetUid; 7258 this.flags = flags; 7259 } 7260 } 7261 7262 /** 7263 * Like checkGrantUriPermissionLocked, but takes an Intent. 7264 */ 7265 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7266 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7267 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7268 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7269 + " clip=" + (intent != null ? intent.getClipData() : null) 7270 + " from " + intent + "; flags=0x" 7271 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7272 7273 if (targetPkg == null) { 7274 throw new NullPointerException("targetPkg"); 7275 } 7276 7277 if (intent == null) { 7278 return null; 7279 } 7280 Uri data = intent.getData(); 7281 ClipData clip = intent.getClipData(); 7282 if (data == null && clip == null) { 7283 return null; 7284 } 7285 // Default userId for uris in the intent (if they don't specify it themselves) 7286 int contentUserHint = intent.getContentUserHint(); 7287 if (contentUserHint == UserHandle.USER_CURRENT) { 7288 contentUserHint = UserHandle.getUserId(callingUid); 7289 } 7290 final IPackageManager pm = AppGlobals.getPackageManager(); 7291 int targetUid; 7292 if (needed != null) { 7293 targetUid = needed.targetUid; 7294 } else { 7295 try { 7296 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7297 } catch (RemoteException ex) { 7298 return null; 7299 } 7300 if (targetUid < 0) { 7301 if (DEBUG_URI_PERMISSION) { 7302 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7303 + " on user " + targetUserId); 7304 } 7305 return null; 7306 } 7307 } 7308 if (data != null) { 7309 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7310 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7311 targetUid); 7312 if (targetUid > 0) { 7313 if (needed == null) { 7314 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7315 } 7316 needed.add(grantUri); 7317 } 7318 } 7319 if (clip != null) { 7320 for (int i=0; i<clip.getItemCount(); i++) { 7321 Uri uri = clip.getItemAt(i).getUri(); 7322 if (uri != null) { 7323 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7324 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7325 targetUid); 7326 if (targetUid > 0) { 7327 if (needed == null) { 7328 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7329 } 7330 needed.add(grantUri); 7331 } 7332 } else { 7333 Intent clipIntent = clip.getItemAt(i).getIntent(); 7334 if (clipIntent != null) { 7335 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7336 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7337 if (newNeeded != null) { 7338 needed = newNeeded; 7339 } 7340 } 7341 } 7342 } 7343 } 7344 7345 return needed; 7346 } 7347 7348 /** 7349 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7350 */ 7351 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7352 UriPermissionOwner owner) { 7353 if (needed != null) { 7354 for (int i=0; i<needed.size(); i++) { 7355 GrantUri grantUri = needed.get(i); 7356 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7357 grantUri, needed.flags, owner); 7358 } 7359 } 7360 } 7361 7362 void grantUriPermissionFromIntentLocked(int callingUid, 7363 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7364 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7365 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7366 if (needed == null) { 7367 return; 7368 } 7369 7370 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7371 } 7372 7373 /** 7374 * @param uri This uri must NOT contain an embedded userId. 7375 * @param userId The userId in which the uri is to be resolved. 7376 */ 7377 @Override 7378 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7379 final int modeFlags, int userId) { 7380 enforceNotIsolatedCaller("grantUriPermission"); 7381 GrantUri grantUri = new GrantUri(userId, uri, false); 7382 synchronized(this) { 7383 final ProcessRecord r = getRecordForAppLocked(caller); 7384 if (r == null) { 7385 throw new SecurityException("Unable to find app for caller " 7386 + caller 7387 + " when granting permission to uri " + grantUri); 7388 } 7389 if (targetPkg == null) { 7390 throw new IllegalArgumentException("null target"); 7391 } 7392 if (grantUri == null) { 7393 throw new IllegalArgumentException("null uri"); 7394 } 7395 7396 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7397 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7398 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7399 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7400 7401 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7402 UserHandle.getUserId(r.uid)); 7403 } 7404 } 7405 7406 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7407 if (perm.modeFlags == 0) { 7408 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7409 perm.targetUid); 7410 if (perms != null) { 7411 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7412 "Removing " + perm.targetUid + " permission to " + perm.uri); 7413 7414 perms.remove(perm.uri); 7415 if (perms.isEmpty()) { 7416 mGrantedUriPermissions.remove(perm.targetUid); 7417 } 7418 } 7419 } 7420 } 7421 7422 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7423 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7424 7425 final IPackageManager pm = AppGlobals.getPackageManager(); 7426 final String authority = grantUri.uri.getAuthority(); 7427 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7428 if (pi == null) { 7429 Slog.w(TAG, "No content provider found for permission revoke: " 7430 + grantUri.toSafeString()); 7431 return; 7432 } 7433 7434 // Does the caller have this permission on the URI? 7435 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7436 // If they don't have direct access to the URI, then revoke any 7437 // ownerless URI permissions that have been granted to them. 7438 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7439 if (perms != null) { 7440 boolean persistChanged = false; 7441 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7442 final UriPermission perm = it.next(); 7443 if (perm.uri.sourceUserId == grantUri.sourceUserId 7444 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7445 if (DEBUG_URI_PERMISSION) 7446 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7447 " permission to " + perm.uri); 7448 persistChanged |= perm.revokeModes( 7449 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7450 if (perm.modeFlags == 0) { 7451 it.remove(); 7452 } 7453 } 7454 } 7455 if (perms.isEmpty()) { 7456 mGrantedUriPermissions.remove(callingUid); 7457 } 7458 if (persistChanged) { 7459 schedulePersistUriGrants(); 7460 } 7461 } 7462 return; 7463 } 7464 7465 boolean persistChanged = false; 7466 7467 // Go through all of the permissions and remove any that match. 7468 int N = mGrantedUriPermissions.size(); 7469 for (int i = 0; i < N; i++) { 7470 final int targetUid = mGrantedUriPermissions.keyAt(i); 7471 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7472 7473 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7474 final UriPermission perm = it.next(); 7475 if (perm.uri.sourceUserId == grantUri.sourceUserId 7476 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7477 if (DEBUG_URI_PERMISSION) 7478 Slog.v(TAG, 7479 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7480 persistChanged |= perm.revokeModes( 7481 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7482 if (perm.modeFlags == 0) { 7483 it.remove(); 7484 } 7485 } 7486 } 7487 7488 if (perms.isEmpty()) { 7489 mGrantedUriPermissions.remove(targetUid); 7490 N--; 7491 i--; 7492 } 7493 } 7494 7495 if (persistChanged) { 7496 schedulePersistUriGrants(); 7497 } 7498 } 7499 7500 /** 7501 * @param uri This uri must NOT contain an embedded userId. 7502 * @param userId The userId in which the uri is to be resolved. 7503 */ 7504 @Override 7505 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7506 int userId) { 7507 enforceNotIsolatedCaller("revokeUriPermission"); 7508 synchronized(this) { 7509 final ProcessRecord r = getRecordForAppLocked(caller); 7510 if (r == null) { 7511 throw new SecurityException("Unable to find app for caller " 7512 + caller 7513 + " when revoking permission to uri " + uri); 7514 } 7515 if (uri == null) { 7516 Slog.w(TAG, "revokeUriPermission: null uri"); 7517 return; 7518 } 7519 7520 if (!Intent.isAccessUriMode(modeFlags)) { 7521 return; 7522 } 7523 7524 final IPackageManager pm = AppGlobals.getPackageManager(); 7525 final String authority = uri.getAuthority(); 7526 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7527 if (pi == null) { 7528 Slog.w(TAG, "No content provider found for permission revoke: " 7529 + uri.toSafeString()); 7530 return; 7531 } 7532 7533 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7534 } 7535 } 7536 7537 /** 7538 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7539 * given package. 7540 * 7541 * @param packageName Package name to match, or {@code null} to apply to all 7542 * packages. 7543 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7544 * to all users. 7545 * @param persistable If persistable grants should be removed. 7546 */ 7547 private void removeUriPermissionsForPackageLocked( 7548 String packageName, int userHandle, boolean persistable) { 7549 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7550 throw new IllegalArgumentException("Must narrow by either package or user"); 7551 } 7552 7553 boolean persistChanged = false; 7554 7555 int N = mGrantedUriPermissions.size(); 7556 for (int i = 0; i < N; i++) { 7557 final int targetUid = mGrantedUriPermissions.keyAt(i); 7558 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7559 7560 // Only inspect grants matching user 7561 if (userHandle == UserHandle.USER_ALL 7562 || userHandle == UserHandle.getUserId(targetUid)) { 7563 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7564 final UriPermission perm = it.next(); 7565 7566 // Only inspect grants matching package 7567 if (packageName == null || perm.sourcePkg.equals(packageName) 7568 || perm.targetPkg.equals(packageName)) { 7569 persistChanged |= perm.revokeModes(persistable 7570 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7571 7572 // Only remove when no modes remain; any persisted grants 7573 // will keep this alive. 7574 if (perm.modeFlags == 0) { 7575 it.remove(); 7576 } 7577 } 7578 } 7579 7580 if (perms.isEmpty()) { 7581 mGrantedUriPermissions.remove(targetUid); 7582 N--; 7583 i--; 7584 } 7585 } 7586 } 7587 7588 if (persistChanged) { 7589 schedulePersistUriGrants(); 7590 } 7591 } 7592 7593 @Override 7594 public IBinder newUriPermissionOwner(String name) { 7595 enforceNotIsolatedCaller("newUriPermissionOwner"); 7596 synchronized(this) { 7597 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7598 return owner.getExternalTokenLocked(); 7599 } 7600 } 7601 7602 /** 7603 * @param uri This uri must NOT contain an embedded userId. 7604 * @param sourceUserId The userId in which the uri is to be resolved. 7605 * @param targetUserId The userId of the app that receives the grant. 7606 */ 7607 @Override 7608 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7609 final int modeFlags, int sourceUserId, int targetUserId) { 7610 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7611 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7612 synchronized(this) { 7613 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7614 if (owner == null) { 7615 throw new IllegalArgumentException("Unknown owner: " + token); 7616 } 7617 if (fromUid != Binder.getCallingUid()) { 7618 if (Binder.getCallingUid() != Process.myUid()) { 7619 // Only system code can grant URI permissions on behalf 7620 // of other users. 7621 throw new SecurityException("nice try"); 7622 } 7623 } 7624 if (targetPkg == null) { 7625 throw new IllegalArgumentException("null target"); 7626 } 7627 if (uri == null) { 7628 throw new IllegalArgumentException("null uri"); 7629 } 7630 7631 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7632 modeFlags, owner, targetUserId); 7633 } 7634 } 7635 7636 /** 7637 * @param uri This uri must NOT contain an embedded userId. 7638 * @param userId The userId in which the uri is to be resolved. 7639 */ 7640 @Override 7641 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7642 synchronized(this) { 7643 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7644 if (owner == null) { 7645 throw new IllegalArgumentException("Unknown owner: " + token); 7646 } 7647 7648 if (uri == null) { 7649 owner.removeUriPermissionsLocked(mode); 7650 } else { 7651 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7652 } 7653 } 7654 } 7655 7656 private void schedulePersistUriGrants() { 7657 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7658 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7659 10 * DateUtils.SECOND_IN_MILLIS); 7660 } 7661 } 7662 7663 private void writeGrantedUriPermissions() { 7664 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7665 7666 // Snapshot permissions so we can persist without lock 7667 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7668 synchronized (this) { 7669 final int size = mGrantedUriPermissions.size(); 7670 for (int i = 0; i < size; i++) { 7671 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7672 for (UriPermission perm : perms.values()) { 7673 if (perm.persistedModeFlags != 0) { 7674 persist.add(perm.snapshot()); 7675 } 7676 } 7677 } 7678 } 7679 7680 FileOutputStream fos = null; 7681 try { 7682 fos = mGrantFile.startWrite(); 7683 7684 XmlSerializer out = new FastXmlSerializer(); 7685 out.setOutput(fos, "utf-8"); 7686 out.startDocument(null, true); 7687 out.startTag(null, TAG_URI_GRANTS); 7688 for (UriPermission.Snapshot perm : persist) { 7689 out.startTag(null, TAG_URI_GRANT); 7690 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7691 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7692 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7693 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7694 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7695 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7696 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7697 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7698 out.endTag(null, TAG_URI_GRANT); 7699 } 7700 out.endTag(null, TAG_URI_GRANTS); 7701 out.endDocument(); 7702 7703 mGrantFile.finishWrite(fos); 7704 } catch (IOException e) { 7705 if (fos != null) { 7706 mGrantFile.failWrite(fos); 7707 } 7708 } 7709 } 7710 7711 private void readGrantedUriPermissionsLocked() { 7712 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7713 7714 final long now = System.currentTimeMillis(); 7715 7716 FileInputStream fis = null; 7717 try { 7718 fis = mGrantFile.openRead(); 7719 final XmlPullParser in = Xml.newPullParser(); 7720 in.setInput(fis, null); 7721 7722 int type; 7723 while ((type = in.next()) != END_DOCUMENT) { 7724 final String tag = in.getName(); 7725 if (type == START_TAG) { 7726 if (TAG_URI_GRANT.equals(tag)) { 7727 final int sourceUserId; 7728 final int targetUserId; 7729 final int userHandle = readIntAttribute(in, 7730 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7731 if (userHandle != UserHandle.USER_NULL) { 7732 // For backwards compatibility. 7733 sourceUserId = userHandle; 7734 targetUserId = userHandle; 7735 } else { 7736 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7737 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7738 } 7739 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7740 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7741 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7742 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7743 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7744 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7745 7746 // Sanity check that provider still belongs to source package 7747 final ProviderInfo pi = getProviderInfoLocked( 7748 uri.getAuthority(), sourceUserId); 7749 if (pi != null && sourcePkg.equals(pi.packageName)) { 7750 int targetUid = -1; 7751 try { 7752 targetUid = AppGlobals.getPackageManager() 7753 .getPackageUid(targetPkg, targetUserId); 7754 } catch (RemoteException e) { 7755 } 7756 if (targetUid != -1) { 7757 final UriPermission perm = findOrCreateUriPermissionLocked( 7758 sourcePkg, targetPkg, targetUid, 7759 new GrantUri(sourceUserId, uri, prefix)); 7760 perm.initPersistedModes(modeFlags, createdTime); 7761 } 7762 } else { 7763 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7764 + " but instead found " + pi); 7765 } 7766 } 7767 } 7768 } 7769 } catch (FileNotFoundException e) { 7770 // Missing grants is okay 7771 } catch (IOException e) { 7772 Slog.wtf(TAG, "Failed reading Uri grants", e); 7773 } catch (XmlPullParserException e) { 7774 Slog.wtf(TAG, "Failed reading Uri grants", e); 7775 } finally { 7776 IoUtils.closeQuietly(fis); 7777 } 7778 } 7779 7780 /** 7781 * @param uri This uri must NOT contain an embedded userId. 7782 * @param userId The userId in which the uri is to be resolved. 7783 */ 7784 @Override 7785 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7786 enforceNotIsolatedCaller("takePersistableUriPermission"); 7787 7788 Preconditions.checkFlagsArgument(modeFlags, 7789 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7790 7791 synchronized (this) { 7792 final int callingUid = Binder.getCallingUid(); 7793 boolean persistChanged = false; 7794 GrantUri grantUri = new GrantUri(userId, uri, false); 7795 7796 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7797 new GrantUri(userId, uri, false)); 7798 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7799 new GrantUri(userId, uri, true)); 7800 7801 final boolean exactValid = (exactPerm != null) 7802 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7803 final boolean prefixValid = (prefixPerm != null) 7804 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7805 7806 if (!(exactValid || prefixValid)) { 7807 throw new SecurityException("No persistable permission grants found for UID " 7808 + callingUid + " and Uri " + grantUri.toSafeString()); 7809 } 7810 7811 if (exactValid) { 7812 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7813 } 7814 if (prefixValid) { 7815 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7816 } 7817 7818 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7819 7820 if (persistChanged) { 7821 schedulePersistUriGrants(); 7822 } 7823 } 7824 } 7825 7826 /** 7827 * @param uri This uri must NOT contain an embedded userId. 7828 * @param userId The userId in which the uri is to be resolved. 7829 */ 7830 @Override 7831 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7832 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7833 7834 Preconditions.checkFlagsArgument(modeFlags, 7835 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7836 7837 synchronized (this) { 7838 final int callingUid = Binder.getCallingUid(); 7839 boolean persistChanged = false; 7840 7841 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7842 new GrantUri(userId, uri, false)); 7843 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7844 new GrantUri(userId, uri, true)); 7845 if (exactPerm == null && prefixPerm == null) { 7846 throw new SecurityException("No permission grants found for UID " + callingUid 7847 + " and Uri " + uri.toSafeString()); 7848 } 7849 7850 if (exactPerm != null) { 7851 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7852 removeUriPermissionIfNeededLocked(exactPerm); 7853 } 7854 if (prefixPerm != null) { 7855 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7856 removeUriPermissionIfNeededLocked(prefixPerm); 7857 } 7858 7859 if (persistChanged) { 7860 schedulePersistUriGrants(); 7861 } 7862 } 7863 } 7864 7865 /** 7866 * Prune any older {@link UriPermission} for the given UID until outstanding 7867 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7868 * 7869 * @return if any mutations occured that require persisting. 7870 */ 7871 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7872 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7873 if (perms == null) return false; 7874 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7875 7876 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7877 for (UriPermission perm : perms.values()) { 7878 if (perm.persistedModeFlags != 0) { 7879 persisted.add(perm); 7880 } 7881 } 7882 7883 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7884 if (trimCount <= 0) return false; 7885 7886 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7887 for (int i = 0; i < trimCount; i++) { 7888 final UriPermission perm = persisted.get(i); 7889 7890 if (DEBUG_URI_PERMISSION) { 7891 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7892 } 7893 7894 perm.releasePersistableModes(~0); 7895 removeUriPermissionIfNeededLocked(perm); 7896 } 7897 7898 return true; 7899 } 7900 7901 @Override 7902 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7903 String packageName, boolean incoming) { 7904 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7905 Preconditions.checkNotNull(packageName, "packageName"); 7906 7907 final int callingUid = Binder.getCallingUid(); 7908 final IPackageManager pm = AppGlobals.getPackageManager(); 7909 try { 7910 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7911 if (packageUid != callingUid) { 7912 throw new SecurityException( 7913 "Package " + packageName + " does not belong to calling UID " + callingUid); 7914 } 7915 } catch (RemoteException e) { 7916 throw new SecurityException("Failed to verify package name ownership"); 7917 } 7918 7919 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7920 synchronized (this) { 7921 if (incoming) { 7922 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7923 callingUid); 7924 if (perms == null) { 7925 Slog.w(TAG, "No permission grants found for " + packageName); 7926 } else { 7927 for (UriPermission perm : perms.values()) { 7928 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7929 result.add(perm.buildPersistedPublicApiObject()); 7930 } 7931 } 7932 } 7933 } else { 7934 final int size = mGrantedUriPermissions.size(); 7935 for (int i = 0; i < size; i++) { 7936 final ArrayMap<GrantUri, UriPermission> perms = 7937 mGrantedUriPermissions.valueAt(i); 7938 for (UriPermission perm : perms.values()) { 7939 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7940 result.add(perm.buildPersistedPublicApiObject()); 7941 } 7942 } 7943 } 7944 } 7945 } 7946 return new ParceledListSlice<android.content.UriPermission>(result); 7947 } 7948 7949 @Override 7950 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7951 synchronized (this) { 7952 ProcessRecord app = 7953 who != null ? getRecordForAppLocked(who) : null; 7954 if (app == null) return; 7955 7956 Message msg = Message.obtain(); 7957 msg.what = WAIT_FOR_DEBUGGER_MSG; 7958 msg.obj = app; 7959 msg.arg1 = waiting ? 1 : 0; 7960 mHandler.sendMessage(msg); 7961 } 7962 } 7963 7964 @Override 7965 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7966 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7967 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7968 outInfo.availMem = Process.getFreeMemory(); 7969 outInfo.totalMem = Process.getTotalMemory(); 7970 outInfo.threshold = homeAppMem; 7971 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7972 outInfo.hiddenAppThreshold = cachedAppMem; 7973 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7974 ProcessList.SERVICE_ADJ); 7975 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7976 ProcessList.VISIBLE_APP_ADJ); 7977 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7978 ProcessList.FOREGROUND_APP_ADJ); 7979 } 7980 7981 // ========================================================= 7982 // TASK MANAGEMENT 7983 // ========================================================= 7984 7985 @Override 7986 public List<IAppTask> getAppTasks(String callingPackage) { 7987 int callingUid = Binder.getCallingUid(); 7988 long ident = Binder.clearCallingIdentity(); 7989 7990 synchronized(this) { 7991 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7992 try { 7993 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7994 7995 final int N = mRecentTasks.size(); 7996 for (int i = 0; i < N; i++) { 7997 TaskRecord tr = mRecentTasks.get(i); 7998 // Skip tasks that do not match the caller. We don't need to verify 7999 // callingPackage, because we are also limiting to callingUid and know 8000 // that will limit to the correct security sandbox. 8001 if (tr.effectiveUid != callingUid) { 8002 continue; 8003 } 8004 Intent intent = tr.getBaseIntent(); 8005 if (intent == null || 8006 !callingPackage.equals(intent.getComponent().getPackageName())) { 8007 continue; 8008 } 8009 ActivityManager.RecentTaskInfo taskInfo = 8010 createRecentTaskInfoFromTaskRecord(tr); 8011 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8012 list.add(taskImpl); 8013 } 8014 } finally { 8015 Binder.restoreCallingIdentity(ident); 8016 } 8017 return list; 8018 } 8019 } 8020 8021 @Override 8022 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8023 final int callingUid = Binder.getCallingUid(); 8024 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8025 8026 synchronized(this) { 8027 if (localLOGV) Slog.v( 8028 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8029 8030 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8031 callingUid); 8032 8033 // TODO: Improve with MRU list from all ActivityStacks. 8034 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8035 } 8036 8037 return list; 8038 } 8039 8040 /** 8041 * Creates a new RecentTaskInfo from a TaskRecord. 8042 */ 8043 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8044 // Update the task description to reflect any changes in the task stack 8045 tr.updateTaskDescription(); 8046 8047 // Compose the recent task info 8048 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8049 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8050 rti.persistentId = tr.taskId; 8051 rti.baseIntent = new Intent(tr.getBaseIntent()); 8052 rti.origActivity = tr.origActivity; 8053 rti.description = tr.lastDescription; 8054 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8055 rti.userId = tr.userId; 8056 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8057 rti.firstActiveTime = tr.firstActiveTime; 8058 rti.lastActiveTime = tr.lastActiveTime; 8059 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8060 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8061 return rti; 8062 } 8063 8064 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8065 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8066 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8067 if (!allowed) { 8068 if (checkPermission(android.Manifest.permission.GET_TASKS, 8069 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8070 // Temporary compatibility: some existing apps on the system image may 8071 // still be requesting the old permission and not switched to the new 8072 // one; if so, we'll still allow them full access. This means we need 8073 // to see if they are holding the old permission and are a system app. 8074 try { 8075 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8076 allowed = true; 8077 Slog.w(TAG, caller + ": caller " + callingUid 8078 + " is using old GET_TASKS but privileged; allowing"); 8079 } 8080 } catch (RemoteException e) { 8081 } 8082 } 8083 } 8084 if (!allowed) { 8085 Slog.w(TAG, caller + ": caller " + callingUid 8086 + " does not hold GET_TASKS; limiting output"); 8087 } 8088 return allowed; 8089 } 8090 8091 @Override 8092 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8093 final int callingUid = Binder.getCallingUid(); 8094 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8095 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8096 8097 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8098 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8099 synchronized (this) { 8100 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8101 callingUid); 8102 final boolean detailed = checkCallingPermission( 8103 android.Manifest.permission.GET_DETAILED_TASKS) 8104 == PackageManager.PERMISSION_GRANTED; 8105 8106 final int N = mRecentTasks.size(); 8107 ArrayList<ActivityManager.RecentTaskInfo> res 8108 = new ArrayList<ActivityManager.RecentTaskInfo>( 8109 maxNum < N ? maxNum : N); 8110 8111 final Set<Integer> includedUsers; 8112 if (includeProfiles) { 8113 includedUsers = getProfileIdsLocked(userId); 8114 } else { 8115 includedUsers = new HashSet<Integer>(); 8116 } 8117 includedUsers.add(Integer.valueOf(userId)); 8118 8119 for (int i=0; i<N && maxNum > 0; i++) { 8120 TaskRecord tr = mRecentTasks.get(i); 8121 // Only add calling user or related users recent tasks 8122 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8123 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8124 continue; 8125 } 8126 8127 // Return the entry if desired by the caller. We always return 8128 // the first entry, because callers always expect this to be the 8129 // foreground app. We may filter others if the caller has 8130 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8131 // we should exclude the entry. 8132 8133 if (i == 0 8134 || withExcluded 8135 || (tr.intent == null) 8136 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8137 == 0)) { 8138 if (!allowed) { 8139 // If the caller doesn't have the GET_TASKS permission, then only 8140 // allow them to see a small subset of tasks -- their own and home. 8141 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8142 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8143 continue; 8144 } 8145 } 8146 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8147 if (tr.stack != null && tr.stack.isHomeStack()) { 8148 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8149 continue; 8150 } 8151 } 8152 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8153 // Don't include auto remove tasks that are finished or finishing. 8154 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8155 + tr); 8156 continue; 8157 } 8158 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8159 && !tr.isAvailable) { 8160 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8161 continue; 8162 } 8163 8164 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8165 if (!detailed) { 8166 rti.baseIntent.replaceExtras((Bundle)null); 8167 } 8168 8169 res.add(rti); 8170 maxNum--; 8171 } 8172 } 8173 return res; 8174 } 8175 } 8176 8177 private TaskRecord taskForIdLocked(int id) { 8178 final TaskRecord task = recentTaskForIdLocked(id); 8179 if (task != null) { 8180 return task; 8181 } 8182 8183 // Don't give up. Sometimes it just hasn't made it to recents yet. 8184 return mStackSupervisor.anyTaskForIdLocked(id); 8185 } 8186 8187 private TaskRecord recentTaskForIdLocked(int id) { 8188 final int N = mRecentTasks.size(); 8189 for (int i=0; i<N; i++) { 8190 TaskRecord tr = mRecentTasks.get(i); 8191 if (tr.taskId == id) { 8192 return tr; 8193 } 8194 } 8195 return null; 8196 } 8197 8198 @Override 8199 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8200 synchronized (this) { 8201 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8202 "getTaskThumbnail()"); 8203 TaskRecord tr = recentTaskForIdLocked(id); 8204 if (tr != null) { 8205 return tr.getTaskThumbnailLocked(); 8206 } 8207 } 8208 return null; 8209 } 8210 8211 @Override 8212 public int addAppTask(IBinder activityToken, Intent intent, 8213 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8214 final int callingUid = Binder.getCallingUid(); 8215 final long callingIdent = Binder.clearCallingIdentity(); 8216 8217 try { 8218 synchronized (this) { 8219 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8220 if (r == null) { 8221 throw new IllegalArgumentException("Activity does not exist; token=" 8222 + activityToken); 8223 } 8224 ComponentName comp = intent.getComponent(); 8225 if (comp == null) { 8226 throw new IllegalArgumentException("Intent " + intent 8227 + " must specify explicit component"); 8228 } 8229 if (thumbnail.getWidth() != mThumbnailWidth 8230 || thumbnail.getHeight() != mThumbnailHeight) { 8231 throw new IllegalArgumentException("Bad thumbnail size: got " 8232 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8233 + mThumbnailWidth + "x" + mThumbnailHeight); 8234 } 8235 if (intent.getSelector() != null) { 8236 intent.setSelector(null); 8237 } 8238 if (intent.getSourceBounds() != null) { 8239 intent.setSourceBounds(null); 8240 } 8241 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8242 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8243 // The caller has added this as an auto-remove task... that makes no 8244 // sense, so turn off auto-remove. 8245 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8246 } 8247 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8248 // Must be a new task. 8249 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8250 } 8251 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8252 mLastAddedTaskActivity = null; 8253 } 8254 ActivityInfo ainfo = mLastAddedTaskActivity; 8255 if (ainfo == null) { 8256 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8257 comp, 0, UserHandle.getUserId(callingUid)); 8258 if (ainfo.applicationInfo.uid != callingUid) { 8259 throw new SecurityException( 8260 "Can't add task for another application: target uid=" 8261 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8262 } 8263 } 8264 8265 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8266 intent, description); 8267 8268 int trimIdx = trimRecentsForTaskLocked(task, false); 8269 if (trimIdx >= 0) { 8270 // If this would have caused a trim, then we'll abort because that 8271 // means it would be added at the end of the list but then just removed. 8272 return INVALID_TASK_ID; 8273 } 8274 8275 final int N = mRecentTasks.size(); 8276 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8277 final TaskRecord tr = mRecentTasks.remove(N - 1); 8278 tr.removedFromRecents(); 8279 } 8280 8281 task.inRecents = true; 8282 mRecentTasks.add(task); 8283 r.task.stack.addTask(task, false, false); 8284 8285 task.setLastThumbnail(thumbnail); 8286 task.freeLastThumbnail(); 8287 8288 return task.taskId; 8289 } 8290 } finally { 8291 Binder.restoreCallingIdentity(callingIdent); 8292 } 8293 } 8294 8295 @Override 8296 public Point getAppTaskThumbnailSize() { 8297 synchronized (this) { 8298 return new Point(mThumbnailWidth, mThumbnailHeight); 8299 } 8300 } 8301 8302 @Override 8303 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8304 synchronized (this) { 8305 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8306 if (r != null) { 8307 r.setTaskDescription(td); 8308 r.task.updateTaskDescription(); 8309 } 8310 } 8311 } 8312 8313 @Override 8314 public Bitmap getTaskDescriptionIcon(String filename) { 8315 if (!FileUtils.isValidExtFilename(filename) 8316 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8317 throw new IllegalArgumentException("Bad filename: " + filename); 8318 } 8319 return mTaskPersister.getTaskDescriptionIcon(filename); 8320 } 8321 8322 @Override 8323 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8324 throws RemoteException { 8325 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8326 opts.getCustomInPlaceResId() == 0) { 8327 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8328 "with valid animation"); 8329 } 8330 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8331 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8332 opts.getCustomInPlaceResId()); 8333 mWindowManager.executeAppTransition(); 8334 } 8335 8336 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8337 mRecentTasks.remove(tr); 8338 tr.removedFromRecents(); 8339 ComponentName component = tr.getBaseIntent().getComponent(); 8340 if (component == null) { 8341 Slog.w(TAG, "No component for base intent of task: " + tr); 8342 return; 8343 } 8344 8345 if (!killProcess) { 8346 return; 8347 } 8348 8349 // Determine if the process(es) for this task should be killed. 8350 final String pkg = component.getPackageName(); 8351 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8352 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8353 for (int i = 0; i < pmap.size(); i++) { 8354 8355 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8356 for (int j = 0; j < uids.size(); j++) { 8357 ProcessRecord proc = uids.valueAt(j); 8358 if (proc.userId != tr.userId) { 8359 // Don't kill process for a different user. 8360 continue; 8361 } 8362 if (proc == mHomeProcess) { 8363 // Don't kill the home process along with tasks from the same package. 8364 continue; 8365 } 8366 if (!proc.pkgList.containsKey(pkg)) { 8367 // Don't kill process that is not associated with this task. 8368 continue; 8369 } 8370 8371 for (int k = 0; k < proc.activities.size(); k++) { 8372 TaskRecord otherTask = proc.activities.get(k).task; 8373 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8374 // Don't kill process(es) that has an activity in a different task that is 8375 // also in recents. 8376 return; 8377 } 8378 } 8379 8380 // Add process to kill list. 8381 procsToKill.add(proc); 8382 } 8383 } 8384 8385 // Find any running services associated with this app and stop if needed. 8386 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8387 8388 // Kill the running processes. 8389 for (int i = 0; i < procsToKill.size(); i++) { 8390 ProcessRecord pr = procsToKill.get(i); 8391 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8392 pr.kill("remove task", true); 8393 } else { 8394 pr.waitingToKill = "remove task"; 8395 } 8396 } 8397 } 8398 8399 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8400 // Remove all tasks with activities in the specified package from the list of recent tasks 8401 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8402 TaskRecord tr = mRecentTasks.get(i); 8403 if (tr.userId != userId) continue; 8404 8405 ComponentName cn = tr.intent.getComponent(); 8406 if (cn != null && cn.getPackageName().equals(packageName)) { 8407 // If the package name matches, remove the task. 8408 removeTaskByIdLocked(tr.taskId, true); 8409 } 8410 } 8411 } 8412 8413 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8414 final IPackageManager pm = AppGlobals.getPackageManager(); 8415 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8416 8417 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8418 TaskRecord tr = mRecentTasks.get(i); 8419 if (tr.userId != userId) continue; 8420 8421 ComponentName cn = tr.intent.getComponent(); 8422 if (cn != null && cn.getPackageName().equals(packageName)) { 8423 // Skip if component still exists in the package. 8424 if (componentsKnownToExist.contains(cn)) continue; 8425 8426 try { 8427 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8428 if (info != null) { 8429 componentsKnownToExist.add(cn); 8430 } else { 8431 removeTaskByIdLocked(tr.taskId, false); 8432 } 8433 } catch (RemoteException e) { 8434 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8435 } 8436 } 8437 } 8438 } 8439 8440 /** 8441 * Removes the task with the specified task id. 8442 * 8443 * @param taskId Identifier of the task to be removed. 8444 * @param killProcess Kill any process associated with the task if possible. 8445 * @return Returns true if the given task was found and removed. 8446 */ 8447 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8448 TaskRecord tr = taskForIdLocked(taskId); 8449 if (tr != null) { 8450 tr.removeTaskActivitiesLocked(); 8451 cleanUpRemovedTaskLocked(tr, killProcess); 8452 if (tr.isPersistable) { 8453 notifyTaskPersisterLocked(null, true); 8454 } 8455 return true; 8456 } 8457 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8458 return false; 8459 } 8460 8461 @Override 8462 public boolean removeTask(int taskId) { 8463 synchronized (this) { 8464 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8465 "removeTask()"); 8466 long ident = Binder.clearCallingIdentity(); 8467 try { 8468 return removeTaskByIdLocked(taskId, true); 8469 } finally { 8470 Binder.restoreCallingIdentity(ident); 8471 } 8472 } 8473 } 8474 8475 /** 8476 * TODO: Add mController hook 8477 */ 8478 @Override 8479 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8480 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8481 "moveTaskToFront()"); 8482 8483 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8484 synchronized(this) { 8485 moveTaskToFrontLocked(taskId, flags, options); 8486 } 8487 } 8488 8489 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8490 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8491 Binder.getCallingUid(), -1, -1, "Task to front")) { 8492 ActivityOptions.abort(options); 8493 return; 8494 } 8495 final long origId = Binder.clearCallingIdentity(); 8496 try { 8497 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8498 if (task == null) { 8499 Slog.d(TAG, "Could not find task for id: "+ taskId); 8500 return; 8501 } 8502 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8503 mStackSupervisor.showLockTaskToast(); 8504 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8505 return; 8506 } 8507 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8508 if (prev != null && prev.isRecentsActivity()) { 8509 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8510 } 8511 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8512 } finally { 8513 Binder.restoreCallingIdentity(origId); 8514 } 8515 ActivityOptions.abort(options); 8516 } 8517 8518 @Override 8519 public void moveTaskToBack(int taskId) { 8520 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8521 "moveTaskToBack()"); 8522 8523 synchronized(this) { 8524 TaskRecord tr = taskForIdLocked(taskId); 8525 if (tr != null) { 8526 if (tr == mStackSupervisor.mLockTaskModeTask) { 8527 mStackSupervisor.showLockTaskToast(); 8528 return; 8529 } 8530 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8531 ActivityStack stack = tr.stack; 8532 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8533 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8534 Binder.getCallingUid(), -1, -1, "Task to back")) { 8535 return; 8536 } 8537 } 8538 final long origId = Binder.clearCallingIdentity(); 8539 try { 8540 stack.moveTaskToBackLocked(taskId, null); 8541 } finally { 8542 Binder.restoreCallingIdentity(origId); 8543 } 8544 } 8545 } 8546 } 8547 8548 /** 8549 * Moves an activity, and all of the other activities within the same task, to the bottom 8550 * of the history stack. The activity's order within the task is unchanged. 8551 * 8552 * @param token A reference to the activity we wish to move 8553 * @param nonRoot If false then this only works if the activity is the root 8554 * of a task; if true it will work for any activity in a task. 8555 * @return Returns true if the move completed, false if not. 8556 */ 8557 @Override 8558 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8559 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8560 synchronized(this) { 8561 final long origId = Binder.clearCallingIdentity(); 8562 try { 8563 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8564 if (taskId >= 0) { 8565 if ((mStackSupervisor.mLockTaskModeTask != null) 8566 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8567 mStackSupervisor.showLockTaskToast(); 8568 return false; 8569 } 8570 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8571 } 8572 } finally { 8573 Binder.restoreCallingIdentity(origId); 8574 } 8575 } 8576 return false; 8577 } 8578 8579 @Override 8580 public void moveTaskBackwards(int task) { 8581 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8582 "moveTaskBackwards()"); 8583 8584 synchronized(this) { 8585 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8586 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8587 return; 8588 } 8589 final long origId = Binder.clearCallingIdentity(); 8590 moveTaskBackwardsLocked(task); 8591 Binder.restoreCallingIdentity(origId); 8592 } 8593 } 8594 8595 private final void moveTaskBackwardsLocked(int task) { 8596 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8597 } 8598 8599 @Override 8600 public IBinder getHomeActivityToken() throws RemoteException { 8601 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8602 "getHomeActivityToken()"); 8603 synchronized (this) { 8604 return mStackSupervisor.getHomeActivityToken(); 8605 } 8606 } 8607 8608 @Override 8609 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8610 IActivityContainerCallback callback) throws RemoteException { 8611 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8612 "createActivityContainer()"); 8613 synchronized (this) { 8614 if (parentActivityToken == null) { 8615 throw new IllegalArgumentException("parent token must not be null"); 8616 } 8617 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8618 if (r == null) { 8619 return null; 8620 } 8621 if (callback == null) { 8622 throw new IllegalArgumentException("callback must not be null"); 8623 } 8624 return mStackSupervisor.createActivityContainer(r, callback); 8625 } 8626 } 8627 8628 @Override 8629 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8630 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8631 "deleteActivityContainer()"); 8632 synchronized (this) { 8633 mStackSupervisor.deleteActivityContainer(container); 8634 } 8635 } 8636 8637 @Override 8638 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8639 throws RemoteException { 8640 synchronized (this) { 8641 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8642 if (stack != null) { 8643 return stack.mActivityContainer; 8644 } 8645 return null; 8646 } 8647 } 8648 8649 @Override 8650 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8651 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8652 "moveTaskToStack()"); 8653 if (stackId == HOME_STACK_ID) { 8654 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8655 new RuntimeException("here").fillInStackTrace()); 8656 } 8657 synchronized (this) { 8658 long ident = Binder.clearCallingIdentity(); 8659 try { 8660 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8661 + stackId + " toTop=" + toTop); 8662 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8663 } finally { 8664 Binder.restoreCallingIdentity(ident); 8665 } 8666 } 8667 } 8668 8669 @Override 8670 public void resizeStack(int stackBoxId, Rect bounds) { 8671 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8672 "resizeStackBox()"); 8673 long ident = Binder.clearCallingIdentity(); 8674 try { 8675 mWindowManager.resizeStack(stackBoxId, bounds); 8676 } finally { 8677 Binder.restoreCallingIdentity(ident); 8678 } 8679 } 8680 8681 @Override 8682 public List<StackInfo> getAllStackInfos() { 8683 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8684 "getAllStackInfos()"); 8685 long ident = Binder.clearCallingIdentity(); 8686 try { 8687 synchronized (this) { 8688 return mStackSupervisor.getAllStackInfosLocked(); 8689 } 8690 } finally { 8691 Binder.restoreCallingIdentity(ident); 8692 } 8693 } 8694 8695 @Override 8696 public StackInfo getStackInfo(int stackId) { 8697 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8698 "getStackInfo()"); 8699 long ident = Binder.clearCallingIdentity(); 8700 try { 8701 synchronized (this) { 8702 return mStackSupervisor.getStackInfoLocked(stackId); 8703 } 8704 } finally { 8705 Binder.restoreCallingIdentity(ident); 8706 } 8707 } 8708 8709 @Override 8710 public boolean isInHomeStack(int taskId) { 8711 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8712 "getStackInfo()"); 8713 long ident = Binder.clearCallingIdentity(); 8714 try { 8715 synchronized (this) { 8716 TaskRecord tr = taskForIdLocked(taskId); 8717 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8718 } 8719 } finally { 8720 Binder.restoreCallingIdentity(ident); 8721 } 8722 } 8723 8724 @Override 8725 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8726 synchronized(this) { 8727 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8728 } 8729 } 8730 8731 private boolean isLockTaskAuthorized(String pkg) { 8732 final DevicePolicyManager dpm = (DevicePolicyManager) 8733 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8734 try { 8735 int uid = mContext.getPackageManager().getPackageUid(pkg, 8736 Binder.getCallingUserHandle().getIdentifier()); 8737 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8738 } catch (NameNotFoundException e) { 8739 return false; 8740 } 8741 } 8742 8743 void startLockTaskMode(TaskRecord task) { 8744 final String pkg; 8745 synchronized (this) { 8746 pkg = task.intent.getComponent().getPackageName(); 8747 } 8748 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8749 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8750 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8751 StatusBarManagerInternal.class); 8752 if (statusBarManager != null) { 8753 statusBarManager.showScreenPinningRequest(); 8754 } 8755 return; 8756 } 8757 long ident = Binder.clearCallingIdentity(); 8758 try { 8759 synchronized (this) { 8760 // Since we lost lock on task, make sure it is still there. 8761 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8762 if (task != null) { 8763 if (!isSystemInitiated 8764 && ((mStackSupervisor.getFocusedStack() == null) 8765 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8766 throw new IllegalArgumentException("Invalid task, not in foreground"); 8767 } 8768 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8769 } 8770 } 8771 } finally { 8772 Binder.restoreCallingIdentity(ident); 8773 } 8774 } 8775 8776 @Override 8777 public void startLockTaskMode(int taskId) { 8778 final TaskRecord task; 8779 long ident = Binder.clearCallingIdentity(); 8780 try { 8781 synchronized (this) { 8782 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8783 } 8784 } finally { 8785 Binder.restoreCallingIdentity(ident); 8786 } 8787 if (task != null) { 8788 startLockTaskMode(task); 8789 } 8790 } 8791 8792 @Override 8793 public void startLockTaskMode(IBinder token) { 8794 final TaskRecord task; 8795 long ident = Binder.clearCallingIdentity(); 8796 try { 8797 synchronized (this) { 8798 final ActivityRecord r = ActivityRecord.forToken(token); 8799 if (r == null) { 8800 return; 8801 } 8802 task = r.task; 8803 } 8804 } finally { 8805 Binder.restoreCallingIdentity(ident); 8806 } 8807 if (task != null) { 8808 startLockTaskMode(task); 8809 } 8810 } 8811 8812 @Override 8813 public void startLockTaskModeOnCurrent() throws RemoteException { 8814 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8815 "startLockTaskModeOnCurrent"); 8816 long ident = Binder.clearCallingIdentity(); 8817 try { 8818 ActivityRecord r = null; 8819 synchronized (this) { 8820 r = mStackSupervisor.topRunningActivityLocked(); 8821 } 8822 startLockTaskMode(r.task); 8823 } finally { 8824 Binder.restoreCallingIdentity(ident); 8825 } 8826 } 8827 8828 @Override 8829 public void stopLockTaskMode() { 8830 // Verify that the user matches the package of the intent for the TaskRecord 8831 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8832 // and stopLockTaskMode. 8833 final int callingUid = Binder.getCallingUid(); 8834 if (callingUid != Process.SYSTEM_UID) { 8835 try { 8836 String pkg = 8837 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8838 int uid = mContext.getPackageManager().getPackageUid(pkg, 8839 Binder.getCallingUserHandle().getIdentifier()); 8840 if (uid != callingUid) { 8841 throw new SecurityException("Invalid uid, expected " + uid); 8842 } 8843 } catch (NameNotFoundException e) { 8844 Log.d(TAG, "stopLockTaskMode " + e); 8845 return; 8846 } 8847 } 8848 long ident = Binder.clearCallingIdentity(); 8849 try { 8850 Log.d(TAG, "stopLockTaskMode"); 8851 // Stop lock task 8852 synchronized (this) { 8853 mStackSupervisor.setLockTaskModeLocked(null, false); 8854 } 8855 } finally { 8856 Binder.restoreCallingIdentity(ident); 8857 } 8858 } 8859 8860 @Override 8861 public void stopLockTaskModeOnCurrent() throws RemoteException { 8862 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8863 "stopLockTaskModeOnCurrent"); 8864 long ident = Binder.clearCallingIdentity(); 8865 try { 8866 stopLockTaskMode(); 8867 } finally { 8868 Binder.restoreCallingIdentity(ident); 8869 } 8870 } 8871 8872 @Override 8873 public boolean isInLockTaskMode() { 8874 synchronized (this) { 8875 return mStackSupervisor.isInLockTaskMode(); 8876 } 8877 } 8878 8879 // ========================================================= 8880 // CONTENT PROVIDERS 8881 // ========================================================= 8882 8883 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8884 List<ProviderInfo> providers = null; 8885 try { 8886 providers = AppGlobals.getPackageManager(). 8887 queryContentProviders(app.processName, app.uid, 8888 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8889 } catch (RemoteException ex) { 8890 } 8891 if (DEBUG_MU) 8892 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8893 int userId = app.userId; 8894 if (providers != null) { 8895 int N = providers.size(); 8896 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8897 for (int i=0; i<N; i++) { 8898 ProviderInfo cpi = 8899 (ProviderInfo)providers.get(i); 8900 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8901 cpi.name, cpi.flags); 8902 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8903 // This is a singleton provider, but a user besides the 8904 // default user is asking to initialize a process it runs 8905 // in... well, no, it doesn't actually run in this process, 8906 // it runs in the process of the default user. Get rid of it. 8907 providers.remove(i); 8908 N--; 8909 i--; 8910 continue; 8911 } 8912 8913 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8914 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8915 if (cpr == null) { 8916 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8917 mProviderMap.putProviderByClass(comp, cpr); 8918 } 8919 if (DEBUG_MU) 8920 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8921 app.pubProviders.put(cpi.name, cpr); 8922 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8923 // Don't add this if it is a platform component that is marked 8924 // to run in multiple processes, because this is actually 8925 // part of the framework so doesn't make sense to track as a 8926 // separate apk in the process. 8927 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8928 mProcessStats); 8929 } 8930 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8931 } 8932 } 8933 return providers; 8934 } 8935 8936 /** 8937 * Check if {@link ProcessRecord} has a possible chance at accessing the 8938 * given {@link ProviderInfo}. Final permission checking is always done 8939 * in {@link ContentProvider}. 8940 */ 8941 private final String checkContentProviderPermissionLocked( 8942 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8943 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8944 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8945 boolean checkedGrants = false; 8946 if (checkUser) { 8947 // Looking for cross-user grants before enforcing the typical cross-users permissions 8948 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8949 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8950 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8951 return null; 8952 } 8953 checkedGrants = true; 8954 } 8955 userId = handleIncomingUser(callingPid, callingUid, userId, 8956 false, ALLOW_NON_FULL, 8957 "checkContentProviderPermissionLocked " + cpi.authority, null); 8958 if (userId != tmpTargetUserId) { 8959 // When we actually went to determine the final targer user ID, this ended 8960 // up different than our initial check for the authority. This is because 8961 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8962 // SELF. So we need to re-check the grants again. 8963 checkedGrants = false; 8964 } 8965 } 8966 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8967 cpi.applicationInfo.uid, cpi.exported) 8968 == PackageManager.PERMISSION_GRANTED) { 8969 return null; 8970 } 8971 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8972 cpi.applicationInfo.uid, cpi.exported) 8973 == PackageManager.PERMISSION_GRANTED) { 8974 return null; 8975 } 8976 8977 PathPermission[] pps = cpi.pathPermissions; 8978 if (pps != null) { 8979 int i = pps.length; 8980 while (i > 0) { 8981 i--; 8982 PathPermission pp = pps[i]; 8983 String pprperm = pp.getReadPermission(); 8984 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8985 cpi.applicationInfo.uid, cpi.exported) 8986 == PackageManager.PERMISSION_GRANTED) { 8987 return null; 8988 } 8989 String ppwperm = pp.getWritePermission(); 8990 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8991 cpi.applicationInfo.uid, cpi.exported) 8992 == PackageManager.PERMISSION_GRANTED) { 8993 return null; 8994 } 8995 } 8996 } 8997 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8998 return null; 8999 } 9000 9001 String msg; 9002 if (!cpi.exported) { 9003 msg = "Permission Denial: opening provider " + cpi.name 9004 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9005 + ", uid=" + callingUid + ") that is not exported from uid " 9006 + cpi.applicationInfo.uid; 9007 } else { 9008 msg = "Permission Denial: opening provider " + cpi.name 9009 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9010 + ", uid=" + callingUid + ") requires " 9011 + cpi.readPermission + " or " + cpi.writePermission; 9012 } 9013 Slog.w(TAG, msg); 9014 return msg; 9015 } 9016 9017 /** 9018 * Returns if the ContentProvider has granted a uri to callingUid 9019 */ 9020 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9021 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9022 if (perms != null) { 9023 for (int i=perms.size()-1; i>=0; i--) { 9024 GrantUri grantUri = perms.keyAt(i); 9025 if (grantUri.sourceUserId == userId || !checkUser) { 9026 if (matchesProvider(grantUri.uri, cpi)) { 9027 return true; 9028 } 9029 } 9030 } 9031 } 9032 return false; 9033 } 9034 9035 /** 9036 * Returns true if the uri authority is one of the authorities specified in the provider. 9037 */ 9038 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9039 String uriAuth = uri.getAuthority(); 9040 String cpiAuth = cpi.authority; 9041 if (cpiAuth.indexOf(';') == -1) { 9042 return cpiAuth.equals(uriAuth); 9043 } 9044 String[] cpiAuths = cpiAuth.split(";"); 9045 int length = cpiAuths.length; 9046 for (int i = 0; i < length; i++) { 9047 if (cpiAuths[i].equals(uriAuth)) return true; 9048 } 9049 return false; 9050 } 9051 9052 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9053 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9054 if (r != null) { 9055 for (int i=0; i<r.conProviders.size(); i++) { 9056 ContentProviderConnection conn = r.conProviders.get(i); 9057 if (conn.provider == cpr) { 9058 if (DEBUG_PROVIDER) Slog.v(TAG, 9059 "Adding provider requested by " 9060 + r.processName + " from process " 9061 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9062 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9063 if (stable) { 9064 conn.stableCount++; 9065 conn.numStableIncs++; 9066 } else { 9067 conn.unstableCount++; 9068 conn.numUnstableIncs++; 9069 } 9070 return conn; 9071 } 9072 } 9073 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9074 if (stable) { 9075 conn.stableCount = 1; 9076 conn.numStableIncs = 1; 9077 } else { 9078 conn.unstableCount = 1; 9079 conn.numUnstableIncs = 1; 9080 } 9081 cpr.connections.add(conn); 9082 r.conProviders.add(conn); 9083 return conn; 9084 } 9085 cpr.addExternalProcessHandleLocked(externalProcessToken); 9086 return null; 9087 } 9088 9089 boolean decProviderCountLocked(ContentProviderConnection conn, 9090 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9091 if (conn != null) { 9092 cpr = conn.provider; 9093 if (DEBUG_PROVIDER) Slog.v(TAG, 9094 "Removing provider requested by " 9095 + conn.client.processName + " from process " 9096 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9097 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9098 if (stable) { 9099 conn.stableCount--; 9100 } else { 9101 conn.unstableCount--; 9102 } 9103 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9104 cpr.connections.remove(conn); 9105 conn.client.conProviders.remove(conn); 9106 return true; 9107 } 9108 return false; 9109 } 9110 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9111 return false; 9112 } 9113 9114 private void checkTime(long startTime, String where) { 9115 long now = SystemClock.elapsedRealtime(); 9116 if ((now-startTime) > 1000) { 9117 // If we are taking more than a second, log about it. 9118 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9119 } 9120 } 9121 9122 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9123 String name, IBinder token, boolean stable, int userId) { 9124 ContentProviderRecord cpr; 9125 ContentProviderConnection conn = null; 9126 ProviderInfo cpi = null; 9127 9128 synchronized(this) { 9129 long startTime = SystemClock.elapsedRealtime(); 9130 9131 ProcessRecord r = null; 9132 if (caller != null) { 9133 r = getRecordForAppLocked(caller); 9134 if (r == null) { 9135 throw new SecurityException( 9136 "Unable to find app for caller " + caller 9137 + " (pid=" + Binder.getCallingPid() 9138 + ") when getting content provider " + name); 9139 } 9140 } 9141 9142 boolean checkCrossUser = true; 9143 9144 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9145 9146 // First check if this content provider has been published... 9147 cpr = mProviderMap.getProviderByName(name, userId); 9148 // If that didn't work, check if it exists for user 0 and then 9149 // verify that it's a singleton provider before using it. 9150 if (cpr == null && userId != UserHandle.USER_OWNER) { 9151 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9152 if (cpr != null) { 9153 cpi = cpr.info; 9154 if (isSingleton(cpi.processName, cpi.applicationInfo, 9155 cpi.name, cpi.flags) 9156 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9157 userId = UserHandle.USER_OWNER; 9158 checkCrossUser = false; 9159 } else { 9160 cpr = null; 9161 cpi = null; 9162 } 9163 } 9164 } 9165 9166 boolean providerRunning = cpr != null; 9167 if (providerRunning) { 9168 cpi = cpr.info; 9169 String msg; 9170 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9171 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9172 != null) { 9173 throw new SecurityException(msg); 9174 } 9175 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9176 9177 if (r != null && cpr.canRunHere(r)) { 9178 // This provider has been published or is in the process 9179 // of being published... but it is also allowed to run 9180 // in the caller's process, so don't make a connection 9181 // and just let the caller instantiate its own instance. 9182 ContentProviderHolder holder = cpr.newHolder(null); 9183 // don't give caller the provider object, it needs 9184 // to make its own. 9185 holder.provider = null; 9186 return holder; 9187 } 9188 9189 final long origId = Binder.clearCallingIdentity(); 9190 9191 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9192 9193 // In this case the provider instance already exists, so we can 9194 // return it right away. 9195 conn = incProviderCountLocked(r, cpr, token, stable); 9196 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9197 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9198 // If this is a perceptible app accessing the provider, 9199 // make sure to count it as being accessed and thus 9200 // back up on the LRU list. This is good because 9201 // content providers are often expensive to start. 9202 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9203 updateLruProcessLocked(cpr.proc, false, null); 9204 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9205 } 9206 } 9207 9208 if (cpr.proc != null) { 9209 if (false) { 9210 if (cpr.name.flattenToShortString().equals( 9211 "com.android.providers.calendar/.CalendarProvider2")) { 9212 Slog.v(TAG, "****************** KILLING " 9213 + cpr.name.flattenToShortString()); 9214 Process.killProcess(cpr.proc.pid); 9215 } 9216 } 9217 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9218 boolean success = updateOomAdjLocked(cpr.proc); 9219 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9220 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9221 // NOTE: there is still a race here where a signal could be 9222 // pending on the process even though we managed to update its 9223 // adj level. Not sure what to do about this, but at least 9224 // the race is now smaller. 9225 if (!success) { 9226 // Uh oh... it looks like the provider's process 9227 // has been killed on us. We need to wait for a new 9228 // process to be started, and make sure its death 9229 // doesn't kill our process. 9230 Slog.i(TAG, 9231 "Existing provider " + cpr.name.flattenToShortString() 9232 + " is crashing; detaching " + r); 9233 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9234 checkTime(startTime, "getContentProviderImpl: before appDied"); 9235 appDiedLocked(cpr.proc); 9236 checkTime(startTime, "getContentProviderImpl: after appDied"); 9237 if (!lastRef) { 9238 // This wasn't the last ref our process had on 9239 // the provider... we have now been killed, bail. 9240 return null; 9241 } 9242 providerRunning = false; 9243 conn = null; 9244 } 9245 } 9246 9247 Binder.restoreCallingIdentity(origId); 9248 } 9249 9250 boolean singleton; 9251 if (!providerRunning) { 9252 try { 9253 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9254 cpi = AppGlobals.getPackageManager(). 9255 resolveContentProvider(name, 9256 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9257 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9258 } catch (RemoteException ex) { 9259 } 9260 if (cpi == null) { 9261 return null; 9262 } 9263 // If the provider is a singleton AND 9264 // (it's a call within the same user || the provider is a 9265 // privileged app) 9266 // Then allow connecting to the singleton provider 9267 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9268 cpi.name, cpi.flags) 9269 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9270 if (singleton) { 9271 userId = UserHandle.USER_OWNER; 9272 } 9273 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9274 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9275 9276 String msg; 9277 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9278 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9279 != null) { 9280 throw new SecurityException(msg); 9281 } 9282 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9283 9284 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9285 && !cpi.processName.equals("system")) { 9286 // If this content provider does not run in the system 9287 // process, and the system is not yet ready to run other 9288 // processes, then fail fast instead of hanging. 9289 throw new IllegalArgumentException( 9290 "Attempt to launch content provider before system ready"); 9291 } 9292 9293 // Make sure that the user who owns this provider is started. If not, 9294 // we don't want to allow it to run. 9295 if (mStartedUsers.get(userId) == null) { 9296 Slog.w(TAG, "Unable to launch app " 9297 + cpi.applicationInfo.packageName + "/" 9298 + cpi.applicationInfo.uid + " for provider " 9299 + name + ": user " + userId + " is stopped"); 9300 return null; 9301 } 9302 9303 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9304 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9305 cpr = mProviderMap.getProviderByClass(comp, userId); 9306 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9307 final boolean firstClass = cpr == null; 9308 if (firstClass) { 9309 final long ident = Binder.clearCallingIdentity(); 9310 try { 9311 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9312 ApplicationInfo ai = 9313 AppGlobals.getPackageManager(). 9314 getApplicationInfo( 9315 cpi.applicationInfo.packageName, 9316 STOCK_PM_FLAGS, userId); 9317 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9318 if (ai == null) { 9319 Slog.w(TAG, "No package info for content provider " 9320 + cpi.name); 9321 return null; 9322 } 9323 ai = getAppInfoForUser(ai, userId); 9324 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9325 } catch (RemoteException ex) { 9326 // pm is in same process, this will never happen. 9327 } finally { 9328 Binder.restoreCallingIdentity(ident); 9329 } 9330 } 9331 9332 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9333 9334 if (r != null && cpr.canRunHere(r)) { 9335 // If this is a multiprocess provider, then just return its 9336 // info and allow the caller to instantiate it. Only do 9337 // this if the provider is the same user as the caller's 9338 // process, or can run as root (so can be in any process). 9339 return cpr.newHolder(null); 9340 } 9341 9342 if (DEBUG_PROVIDER) { 9343 RuntimeException e = new RuntimeException("here"); 9344 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9345 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9346 } 9347 9348 // This is single process, and our app is now connecting to it. 9349 // See if we are already in the process of launching this 9350 // provider. 9351 final int N = mLaunchingProviders.size(); 9352 int i; 9353 for (i=0; i<N; i++) { 9354 if (mLaunchingProviders.get(i) == cpr) { 9355 break; 9356 } 9357 } 9358 9359 // If the provider is not already being launched, then get it 9360 // started. 9361 if (i >= N) { 9362 final long origId = Binder.clearCallingIdentity(); 9363 9364 try { 9365 // Content provider is now in use, its package can't be stopped. 9366 try { 9367 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9368 AppGlobals.getPackageManager().setPackageStoppedState( 9369 cpr.appInfo.packageName, false, userId); 9370 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9371 } catch (RemoteException e) { 9372 } catch (IllegalArgumentException e) { 9373 Slog.w(TAG, "Failed trying to unstop package " 9374 + cpr.appInfo.packageName + ": " + e); 9375 } 9376 9377 // Use existing process if already started 9378 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9379 ProcessRecord proc = getProcessRecordLocked( 9380 cpi.processName, cpr.appInfo.uid, false); 9381 if (proc != null && proc.thread != null) { 9382 if (DEBUG_PROVIDER) { 9383 Slog.d(TAG, "Installing in existing process " + proc); 9384 } 9385 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9386 proc.pubProviders.put(cpi.name, cpr); 9387 try { 9388 proc.thread.scheduleInstallProvider(cpi); 9389 } catch (RemoteException e) { 9390 } 9391 } else { 9392 checkTime(startTime, "getContentProviderImpl: before start process"); 9393 proc = startProcessLocked(cpi.processName, 9394 cpr.appInfo, false, 0, "content provider", 9395 new ComponentName(cpi.applicationInfo.packageName, 9396 cpi.name), false, false, false); 9397 checkTime(startTime, "getContentProviderImpl: after start process"); 9398 if (proc == null) { 9399 Slog.w(TAG, "Unable to launch app " 9400 + cpi.applicationInfo.packageName + "/" 9401 + cpi.applicationInfo.uid + " for provider " 9402 + name + ": process is bad"); 9403 return null; 9404 } 9405 } 9406 cpr.launchingApp = proc; 9407 mLaunchingProviders.add(cpr); 9408 } finally { 9409 Binder.restoreCallingIdentity(origId); 9410 } 9411 } 9412 9413 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9414 9415 // Make sure the provider is published (the same provider class 9416 // may be published under multiple names). 9417 if (firstClass) { 9418 mProviderMap.putProviderByClass(comp, cpr); 9419 } 9420 9421 mProviderMap.putProviderByName(name, cpr); 9422 conn = incProviderCountLocked(r, cpr, token, stable); 9423 if (conn != null) { 9424 conn.waiting = true; 9425 } 9426 } 9427 checkTime(startTime, "getContentProviderImpl: done!"); 9428 } 9429 9430 // Wait for the provider to be published... 9431 synchronized (cpr) { 9432 while (cpr.provider == null) { 9433 if (cpr.launchingApp == null) { 9434 Slog.w(TAG, "Unable to launch app " 9435 + cpi.applicationInfo.packageName + "/" 9436 + cpi.applicationInfo.uid + " for provider " 9437 + name + ": launching app became null"); 9438 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9439 UserHandle.getUserId(cpi.applicationInfo.uid), 9440 cpi.applicationInfo.packageName, 9441 cpi.applicationInfo.uid, name); 9442 return null; 9443 } 9444 try { 9445 if (DEBUG_MU) { 9446 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9447 + cpr.launchingApp); 9448 } 9449 if (conn != null) { 9450 conn.waiting = true; 9451 } 9452 cpr.wait(); 9453 } catch (InterruptedException ex) { 9454 } finally { 9455 if (conn != null) { 9456 conn.waiting = false; 9457 } 9458 } 9459 } 9460 } 9461 return cpr != null ? cpr.newHolder(conn) : null; 9462 } 9463 9464 @Override 9465 public final ContentProviderHolder getContentProvider( 9466 IApplicationThread caller, String name, int userId, boolean stable) { 9467 enforceNotIsolatedCaller("getContentProvider"); 9468 if (caller == null) { 9469 String msg = "null IApplicationThread when getting content provider " 9470 + name; 9471 Slog.w(TAG, msg); 9472 throw new SecurityException(msg); 9473 } 9474 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9475 // with cross-user grant. 9476 return getContentProviderImpl(caller, name, null, stable, userId); 9477 } 9478 9479 public ContentProviderHolder getContentProviderExternal( 9480 String name, int userId, IBinder token) { 9481 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9482 "Do not have permission in call getContentProviderExternal()"); 9483 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9484 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9485 return getContentProviderExternalUnchecked(name, token, userId); 9486 } 9487 9488 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9489 IBinder token, int userId) { 9490 return getContentProviderImpl(null, name, token, true, userId); 9491 } 9492 9493 /** 9494 * Drop a content provider from a ProcessRecord's bookkeeping 9495 */ 9496 public void removeContentProvider(IBinder connection, boolean stable) { 9497 enforceNotIsolatedCaller("removeContentProvider"); 9498 long ident = Binder.clearCallingIdentity(); 9499 try { 9500 synchronized (this) { 9501 ContentProviderConnection conn; 9502 try { 9503 conn = (ContentProviderConnection)connection; 9504 } catch (ClassCastException e) { 9505 String msg ="removeContentProvider: " + connection 9506 + " not a ContentProviderConnection"; 9507 Slog.w(TAG, msg); 9508 throw new IllegalArgumentException(msg); 9509 } 9510 if (conn == null) { 9511 throw new NullPointerException("connection is null"); 9512 } 9513 if (decProviderCountLocked(conn, null, null, stable)) { 9514 updateOomAdjLocked(); 9515 } 9516 } 9517 } finally { 9518 Binder.restoreCallingIdentity(ident); 9519 } 9520 } 9521 9522 public void removeContentProviderExternal(String name, IBinder token) { 9523 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9524 "Do not have permission in call removeContentProviderExternal()"); 9525 int userId = UserHandle.getCallingUserId(); 9526 long ident = Binder.clearCallingIdentity(); 9527 try { 9528 removeContentProviderExternalUnchecked(name, token, userId); 9529 } finally { 9530 Binder.restoreCallingIdentity(ident); 9531 } 9532 } 9533 9534 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9535 synchronized (this) { 9536 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9537 if(cpr == null) { 9538 //remove from mProvidersByClass 9539 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9540 return; 9541 } 9542 9543 //update content provider record entry info 9544 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9545 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9546 if (localCpr.hasExternalProcessHandles()) { 9547 if (localCpr.removeExternalProcessHandleLocked(token)) { 9548 updateOomAdjLocked(); 9549 } else { 9550 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9551 + " with no external reference for token: " 9552 + token + "."); 9553 } 9554 } else { 9555 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9556 + " with no external references."); 9557 } 9558 } 9559 } 9560 9561 public final void publishContentProviders(IApplicationThread caller, 9562 List<ContentProviderHolder> providers) { 9563 if (providers == null) { 9564 return; 9565 } 9566 9567 enforceNotIsolatedCaller("publishContentProviders"); 9568 synchronized (this) { 9569 final ProcessRecord r = getRecordForAppLocked(caller); 9570 if (DEBUG_MU) 9571 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9572 if (r == null) { 9573 throw new SecurityException( 9574 "Unable to find app for caller " + caller 9575 + " (pid=" + Binder.getCallingPid() 9576 + ") when publishing content providers"); 9577 } 9578 9579 final long origId = Binder.clearCallingIdentity(); 9580 9581 final int N = providers.size(); 9582 for (int i=0; i<N; i++) { 9583 ContentProviderHolder src = providers.get(i); 9584 if (src == null || src.info == null || src.provider == null) { 9585 continue; 9586 } 9587 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9588 if (DEBUG_MU) 9589 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9590 if (dst != null) { 9591 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9592 mProviderMap.putProviderByClass(comp, dst); 9593 String names[] = dst.info.authority.split(";"); 9594 for (int j = 0; j < names.length; j++) { 9595 mProviderMap.putProviderByName(names[j], dst); 9596 } 9597 9598 int NL = mLaunchingProviders.size(); 9599 int j; 9600 for (j=0; j<NL; j++) { 9601 if (mLaunchingProviders.get(j) == dst) { 9602 mLaunchingProviders.remove(j); 9603 j--; 9604 NL--; 9605 } 9606 } 9607 synchronized (dst) { 9608 dst.provider = src.provider; 9609 dst.proc = r; 9610 dst.notifyAll(); 9611 } 9612 updateOomAdjLocked(r); 9613 } 9614 } 9615 9616 Binder.restoreCallingIdentity(origId); 9617 } 9618 } 9619 9620 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9621 ContentProviderConnection conn; 9622 try { 9623 conn = (ContentProviderConnection)connection; 9624 } catch (ClassCastException e) { 9625 String msg ="refContentProvider: " + connection 9626 + " not a ContentProviderConnection"; 9627 Slog.w(TAG, msg); 9628 throw new IllegalArgumentException(msg); 9629 } 9630 if (conn == null) { 9631 throw new NullPointerException("connection is null"); 9632 } 9633 9634 synchronized (this) { 9635 if (stable > 0) { 9636 conn.numStableIncs += stable; 9637 } 9638 stable = conn.stableCount + stable; 9639 if (stable < 0) { 9640 throw new IllegalStateException("stableCount < 0: " + stable); 9641 } 9642 9643 if (unstable > 0) { 9644 conn.numUnstableIncs += unstable; 9645 } 9646 unstable = conn.unstableCount + unstable; 9647 if (unstable < 0) { 9648 throw new IllegalStateException("unstableCount < 0: " + unstable); 9649 } 9650 9651 if ((stable+unstable) <= 0) { 9652 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9653 + stable + " unstable=" + unstable); 9654 } 9655 conn.stableCount = stable; 9656 conn.unstableCount = unstable; 9657 return !conn.dead; 9658 } 9659 } 9660 9661 public void unstableProviderDied(IBinder connection) { 9662 ContentProviderConnection conn; 9663 try { 9664 conn = (ContentProviderConnection)connection; 9665 } catch (ClassCastException e) { 9666 String msg ="refContentProvider: " + connection 9667 + " not a ContentProviderConnection"; 9668 Slog.w(TAG, msg); 9669 throw new IllegalArgumentException(msg); 9670 } 9671 if (conn == null) { 9672 throw new NullPointerException("connection is null"); 9673 } 9674 9675 // Safely retrieve the content provider associated with the connection. 9676 IContentProvider provider; 9677 synchronized (this) { 9678 provider = conn.provider.provider; 9679 } 9680 9681 if (provider == null) { 9682 // Um, yeah, we're way ahead of you. 9683 return; 9684 } 9685 9686 // Make sure the caller is being honest with us. 9687 if (provider.asBinder().pingBinder()) { 9688 // Er, no, still looks good to us. 9689 synchronized (this) { 9690 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9691 + " says " + conn + " died, but we don't agree"); 9692 return; 9693 } 9694 } 9695 9696 // Well look at that! It's dead! 9697 synchronized (this) { 9698 if (conn.provider.provider != provider) { 9699 // But something changed... good enough. 9700 return; 9701 } 9702 9703 ProcessRecord proc = conn.provider.proc; 9704 if (proc == null || proc.thread == null) { 9705 // Seems like the process is already cleaned up. 9706 return; 9707 } 9708 9709 // As far as we're concerned, this is just like receiving a 9710 // death notification... just a bit prematurely. 9711 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9712 + ") early provider death"); 9713 final long ident = Binder.clearCallingIdentity(); 9714 try { 9715 appDiedLocked(proc); 9716 } finally { 9717 Binder.restoreCallingIdentity(ident); 9718 } 9719 } 9720 } 9721 9722 @Override 9723 public void appNotRespondingViaProvider(IBinder connection) { 9724 enforceCallingPermission( 9725 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9726 9727 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9728 if (conn == null) { 9729 Slog.w(TAG, "ContentProviderConnection is null"); 9730 return; 9731 } 9732 9733 final ProcessRecord host = conn.provider.proc; 9734 if (host == null) { 9735 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9736 return; 9737 } 9738 9739 final long token = Binder.clearCallingIdentity(); 9740 try { 9741 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9742 } finally { 9743 Binder.restoreCallingIdentity(token); 9744 } 9745 } 9746 9747 public final void installSystemProviders() { 9748 List<ProviderInfo> providers; 9749 synchronized (this) { 9750 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9751 providers = generateApplicationProvidersLocked(app); 9752 if (providers != null) { 9753 for (int i=providers.size()-1; i>=0; i--) { 9754 ProviderInfo pi = (ProviderInfo)providers.get(i); 9755 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9756 Slog.w(TAG, "Not installing system proc provider " + pi.name 9757 + ": not system .apk"); 9758 providers.remove(i); 9759 } 9760 } 9761 } 9762 } 9763 if (providers != null) { 9764 mSystemThread.installSystemProviders(providers); 9765 } 9766 9767 mCoreSettingsObserver = new CoreSettingsObserver(this); 9768 9769 //mUsageStatsService.monitorPackages(); 9770 } 9771 9772 /** 9773 * Allows apps to retrieve the MIME type of a URI. 9774 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9775 * users, then it does not need permission to access the ContentProvider. 9776 * Either, it needs cross-user uri grants. 9777 * 9778 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9779 * 9780 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9781 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9782 */ 9783 public String getProviderMimeType(Uri uri, int userId) { 9784 enforceNotIsolatedCaller("getProviderMimeType"); 9785 final String name = uri.getAuthority(); 9786 int callingUid = Binder.getCallingUid(); 9787 int callingPid = Binder.getCallingPid(); 9788 long ident = 0; 9789 boolean clearedIdentity = false; 9790 userId = unsafeConvertIncomingUser(userId); 9791 if (canClearIdentity(callingPid, callingUid, userId)) { 9792 clearedIdentity = true; 9793 ident = Binder.clearCallingIdentity(); 9794 } 9795 ContentProviderHolder holder = null; 9796 try { 9797 holder = getContentProviderExternalUnchecked(name, null, userId); 9798 if (holder != null) { 9799 return holder.provider.getType(uri); 9800 } 9801 } catch (RemoteException e) { 9802 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9803 return null; 9804 } finally { 9805 // We need to clear the identity to call removeContentProviderExternalUnchecked 9806 if (!clearedIdentity) { 9807 ident = Binder.clearCallingIdentity(); 9808 } 9809 try { 9810 if (holder != null) { 9811 removeContentProviderExternalUnchecked(name, null, userId); 9812 } 9813 } finally { 9814 Binder.restoreCallingIdentity(ident); 9815 } 9816 } 9817 9818 return null; 9819 } 9820 9821 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9822 if (UserHandle.getUserId(callingUid) == userId) { 9823 return true; 9824 } 9825 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9826 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9827 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9828 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9829 return true; 9830 } 9831 return false; 9832 } 9833 9834 // ========================================================= 9835 // GLOBAL MANAGEMENT 9836 // ========================================================= 9837 9838 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9839 boolean isolated, int isolatedUid) { 9840 String proc = customProcess != null ? customProcess : info.processName; 9841 BatteryStatsImpl.Uid.Proc ps = null; 9842 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9843 int uid = info.uid; 9844 if (isolated) { 9845 if (isolatedUid == 0) { 9846 int userId = UserHandle.getUserId(uid); 9847 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9848 while (true) { 9849 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9850 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9851 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9852 } 9853 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9854 mNextIsolatedProcessUid++; 9855 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9856 // No process for this uid, use it. 9857 break; 9858 } 9859 stepsLeft--; 9860 if (stepsLeft <= 0) { 9861 return null; 9862 } 9863 } 9864 } else { 9865 // Special case for startIsolatedProcess (internal only), where 9866 // the uid of the isolated process is specified by the caller. 9867 uid = isolatedUid; 9868 } 9869 } 9870 return new ProcessRecord(stats, info, proc, uid); 9871 } 9872 9873 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9874 String abiOverride) { 9875 ProcessRecord app; 9876 if (!isolated) { 9877 app = getProcessRecordLocked(info.processName, info.uid, true); 9878 } else { 9879 app = null; 9880 } 9881 9882 if (app == null) { 9883 app = newProcessRecordLocked(info, null, isolated, 0); 9884 mProcessNames.put(info.processName, app.uid, app); 9885 if (isolated) { 9886 mIsolatedProcesses.put(app.uid, app); 9887 } 9888 updateLruProcessLocked(app, false, null); 9889 updateOomAdjLocked(); 9890 } 9891 9892 // This package really, really can not be stopped. 9893 try { 9894 AppGlobals.getPackageManager().setPackageStoppedState( 9895 info.packageName, false, UserHandle.getUserId(app.uid)); 9896 } catch (RemoteException e) { 9897 } catch (IllegalArgumentException e) { 9898 Slog.w(TAG, "Failed trying to unstop package " 9899 + info.packageName + ": " + e); 9900 } 9901 9902 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9903 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9904 app.persistent = true; 9905 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9906 } 9907 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9908 mPersistentStartingProcesses.add(app); 9909 startProcessLocked(app, "added application", app.processName, abiOverride, 9910 null /* entryPoint */, null /* entryPointArgs */); 9911 } 9912 9913 return app; 9914 } 9915 9916 public void unhandledBack() { 9917 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9918 "unhandledBack()"); 9919 9920 synchronized(this) { 9921 final long origId = Binder.clearCallingIdentity(); 9922 try { 9923 getFocusedStack().unhandledBackLocked(); 9924 } finally { 9925 Binder.restoreCallingIdentity(origId); 9926 } 9927 } 9928 } 9929 9930 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9931 enforceNotIsolatedCaller("openContentUri"); 9932 final int userId = UserHandle.getCallingUserId(); 9933 String name = uri.getAuthority(); 9934 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9935 ParcelFileDescriptor pfd = null; 9936 if (cph != null) { 9937 // We record the binder invoker's uid in thread-local storage before 9938 // going to the content provider to open the file. Later, in the code 9939 // that handles all permissions checks, we look for this uid and use 9940 // that rather than the Activity Manager's own uid. The effect is that 9941 // we do the check against the caller's permissions even though it looks 9942 // to the content provider like the Activity Manager itself is making 9943 // the request. 9944 Binder token = new Binder(); 9945 sCallerIdentity.set(new Identity( 9946 token, Binder.getCallingPid(), Binder.getCallingUid())); 9947 try { 9948 pfd = cph.provider.openFile(null, uri, "r", null, token); 9949 } catch (FileNotFoundException e) { 9950 // do nothing; pfd will be returned null 9951 } finally { 9952 // Ensure that whatever happens, we clean up the identity state 9953 sCallerIdentity.remove(); 9954 } 9955 9956 // We've got the fd now, so we're done with the provider. 9957 removeContentProviderExternalUnchecked(name, null, userId); 9958 } else { 9959 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9960 } 9961 return pfd; 9962 } 9963 9964 // Actually is sleeping or shutting down or whatever else in the future 9965 // is an inactive state. 9966 public boolean isSleepingOrShuttingDown() { 9967 return isSleeping() || mShuttingDown; 9968 } 9969 9970 public boolean isSleeping() { 9971 return mSleeping; 9972 } 9973 9974 void onWakefulnessChanged(int wakefulness) { 9975 synchronized(this) { 9976 mWakefulness = wakefulness; 9977 updateSleepIfNeededLocked(); 9978 } 9979 } 9980 9981 void finishRunningVoiceLocked() { 9982 if (mRunningVoice) { 9983 mRunningVoice = false; 9984 updateSleepIfNeededLocked(); 9985 } 9986 } 9987 9988 void updateSleepIfNeededLocked() { 9989 if (mSleeping && !shouldSleepLocked()) { 9990 mSleeping = false; 9991 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9992 } else if (!mSleeping && shouldSleepLocked()) { 9993 mSleeping = true; 9994 mStackSupervisor.goingToSleepLocked(); 9995 9996 // Initialize the wake times of all processes. 9997 checkExcessivePowerUsageLocked(false); 9998 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9999 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10000 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10001 } 10002 } 10003 10004 private boolean shouldSleepLocked() { 10005 // Resume applications while running a voice interactor. 10006 if (mRunningVoice) { 10007 return false; 10008 } 10009 10010 switch (mWakefulness) { 10011 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10012 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10013 // If we're interactive but applications are already paused then defer 10014 // resuming them until the lock screen is hidden. 10015 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10016 case PowerManagerInternal.WAKEFULNESS_DOZING: 10017 // If we're dozing then pause applications whenever the lock screen is shown. 10018 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10019 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10020 default: 10021 // If we're asleep then pause applications unconditionally. 10022 return true; 10023 } 10024 } 10025 10026 /** Pokes the task persister. */ 10027 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10028 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10029 // Never persist the home stack. 10030 return; 10031 } 10032 mTaskPersister.wakeup(task, flush); 10033 } 10034 10035 /** Notifies all listeners when the task stack has changed. */ 10036 void notifyTaskStackChangedLocked() { 10037 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10038 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10039 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10040 } 10041 10042 @Override 10043 public boolean shutdown(int timeout) { 10044 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10045 != PackageManager.PERMISSION_GRANTED) { 10046 throw new SecurityException("Requires permission " 10047 + android.Manifest.permission.SHUTDOWN); 10048 } 10049 10050 boolean timedout = false; 10051 10052 synchronized(this) { 10053 mShuttingDown = true; 10054 updateEventDispatchingLocked(); 10055 timedout = mStackSupervisor.shutdownLocked(timeout); 10056 } 10057 10058 mAppOpsService.shutdown(); 10059 if (mUsageStatsService != null) { 10060 mUsageStatsService.prepareShutdown(); 10061 } 10062 mBatteryStatsService.shutdown(); 10063 synchronized (this) { 10064 mProcessStats.shutdownLocked(); 10065 notifyTaskPersisterLocked(null, true); 10066 } 10067 10068 return timedout; 10069 } 10070 10071 public final void activitySlept(IBinder token) { 10072 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10073 10074 final long origId = Binder.clearCallingIdentity(); 10075 10076 synchronized (this) { 10077 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10078 if (r != null) { 10079 mStackSupervisor.activitySleptLocked(r); 10080 } 10081 } 10082 10083 Binder.restoreCallingIdentity(origId); 10084 } 10085 10086 private String lockScreenShownToString() { 10087 switch (mLockScreenShown) { 10088 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10089 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10090 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10091 default: return "Unknown=" + mLockScreenShown; 10092 } 10093 } 10094 10095 void logLockScreen(String msg) { 10096 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10097 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10098 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10099 + " mSleeping=" + mSleeping); 10100 } 10101 10102 void startRunningVoiceLocked() { 10103 if (!mRunningVoice) { 10104 mRunningVoice = true; 10105 updateSleepIfNeededLocked(); 10106 } 10107 } 10108 10109 private void updateEventDispatchingLocked() { 10110 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10111 } 10112 10113 public void setLockScreenShown(boolean shown) { 10114 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10115 != PackageManager.PERMISSION_GRANTED) { 10116 throw new SecurityException("Requires permission " 10117 + android.Manifest.permission.DEVICE_POWER); 10118 } 10119 10120 synchronized(this) { 10121 long ident = Binder.clearCallingIdentity(); 10122 try { 10123 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10124 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10125 updateSleepIfNeededLocked(); 10126 } finally { 10127 Binder.restoreCallingIdentity(ident); 10128 } 10129 } 10130 } 10131 10132 @Override 10133 public void stopAppSwitches() { 10134 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10135 != PackageManager.PERMISSION_GRANTED) { 10136 throw new SecurityException("Requires permission " 10137 + android.Manifest.permission.STOP_APP_SWITCHES); 10138 } 10139 10140 synchronized(this) { 10141 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10142 + APP_SWITCH_DELAY_TIME; 10143 mDidAppSwitch = false; 10144 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10145 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10146 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10147 } 10148 } 10149 10150 public void resumeAppSwitches() { 10151 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10152 != PackageManager.PERMISSION_GRANTED) { 10153 throw new SecurityException("Requires permission " 10154 + android.Manifest.permission.STOP_APP_SWITCHES); 10155 } 10156 10157 synchronized(this) { 10158 // Note that we don't execute any pending app switches... we will 10159 // let those wait until either the timeout, or the next start 10160 // activity request. 10161 mAppSwitchesAllowedTime = 0; 10162 } 10163 } 10164 10165 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10166 int callingPid, int callingUid, String name) { 10167 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10168 return true; 10169 } 10170 10171 int perm = checkComponentPermission( 10172 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10173 sourceUid, -1, true); 10174 if (perm == PackageManager.PERMISSION_GRANTED) { 10175 return true; 10176 } 10177 10178 // If the actual IPC caller is different from the logical source, then 10179 // also see if they are allowed to control app switches. 10180 if (callingUid != -1 && callingUid != sourceUid) { 10181 perm = checkComponentPermission( 10182 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10183 callingUid, -1, true); 10184 if (perm == PackageManager.PERMISSION_GRANTED) { 10185 return true; 10186 } 10187 } 10188 10189 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10190 return false; 10191 } 10192 10193 public void setDebugApp(String packageName, boolean waitForDebugger, 10194 boolean persistent) { 10195 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10196 "setDebugApp()"); 10197 10198 long ident = Binder.clearCallingIdentity(); 10199 try { 10200 // Note that this is not really thread safe if there are multiple 10201 // callers into it at the same time, but that's not a situation we 10202 // care about. 10203 if (persistent) { 10204 final ContentResolver resolver = mContext.getContentResolver(); 10205 Settings.Global.putString( 10206 resolver, Settings.Global.DEBUG_APP, 10207 packageName); 10208 Settings.Global.putInt( 10209 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10210 waitForDebugger ? 1 : 0); 10211 } 10212 10213 synchronized (this) { 10214 if (!persistent) { 10215 mOrigDebugApp = mDebugApp; 10216 mOrigWaitForDebugger = mWaitForDebugger; 10217 } 10218 mDebugApp = packageName; 10219 mWaitForDebugger = waitForDebugger; 10220 mDebugTransient = !persistent; 10221 if (packageName != null) { 10222 forceStopPackageLocked(packageName, -1, false, false, true, true, 10223 false, UserHandle.USER_ALL, "set debug app"); 10224 } 10225 } 10226 } finally { 10227 Binder.restoreCallingIdentity(ident); 10228 } 10229 } 10230 10231 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10232 synchronized (this) { 10233 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10234 if (!isDebuggable) { 10235 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10236 throw new SecurityException("Process not debuggable: " + app.packageName); 10237 } 10238 } 10239 10240 mOpenGlTraceApp = processName; 10241 } 10242 } 10243 10244 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10245 synchronized (this) { 10246 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10247 if (!isDebuggable) { 10248 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10249 throw new SecurityException("Process not debuggable: " + app.packageName); 10250 } 10251 } 10252 mProfileApp = processName; 10253 mProfileFile = profilerInfo.profileFile; 10254 if (mProfileFd != null) { 10255 try { 10256 mProfileFd.close(); 10257 } catch (IOException e) { 10258 } 10259 mProfileFd = null; 10260 } 10261 mProfileFd = profilerInfo.profileFd; 10262 mSamplingInterval = profilerInfo.samplingInterval; 10263 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10264 mProfileType = 0; 10265 } 10266 } 10267 10268 @Override 10269 public void setAlwaysFinish(boolean enabled) { 10270 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10271 "setAlwaysFinish()"); 10272 10273 Settings.Global.putInt( 10274 mContext.getContentResolver(), 10275 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10276 10277 synchronized (this) { 10278 mAlwaysFinishActivities = enabled; 10279 } 10280 } 10281 10282 @Override 10283 public void setActivityController(IActivityController controller) { 10284 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10285 "setActivityController()"); 10286 synchronized (this) { 10287 mController = controller; 10288 Watchdog.getInstance().setActivityController(controller); 10289 } 10290 } 10291 10292 @Override 10293 public void setUserIsMonkey(boolean userIsMonkey) { 10294 synchronized (this) { 10295 synchronized (mPidsSelfLocked) { 10296 final int callingPid = Binder.getCallingPid(); 10297 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10298 if (precessRecord == null) { 10299 throw new SecurityException("Unknown process: " + callingPid); 10300 } 10301 if (precessRecord.instrumentationUiAutomationConnection == null) { 10302 throw new SecurityException("Only an instrumentation process " 10303 + "with a UiAutomation can call setUserIsMonkey"); 10304 } 10305 } 10306 mUserIsMonkey = userIsMonkey; 10307 } 10308 } 10309 10310 @Override 10311 public boolean isUserAMonkey() { 10312 synchronized (this) { 10313 // If there is a controller also implies the user is a monkey. 10314 return (mUserIsMonkey || mController != null); 10315 } 10316 } 10317 10318 public void requestBugReport() { 10319 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10320 SystemProperties.set("ctl.start", "bugreport"); 10321 } 10322 10323 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10324 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10325 } 10326 10327 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10328 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10329 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10330 } 10331 return KEY_DISPATCHING_TIMEOUT; 10332 } 10333 10334 @Override 10335 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10336 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10337 != PackageManager.PERMISSION_GRANTED) { 10338 throw new SecurityException("Requires permission " 10339 + android.Manifest.permission.FILTER_EVENTS); 10340 } 10341 ProcessRecord proc; 10342 long timeout; 10343 synchronized (this) { 10344 synchronized (mPidsSelfLocked) { 10345 proc = mPidsSelfLocked.get(pid); 10346 } 10347 timeout = getInputDispatchingTimeoutLocked(proc); 10348 } 10349 10350 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10351 return -1; 10352 } 10353 10354 return timeout; 10355 } 10356 10357 /** 10358 * Handle input dispatching timeouts. 10359 * Returns whether input dispatching should be aborted or not. 10360 */ 10361 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10362 final ActivityRecord activity, final ActivityRecord parent, 10363 final boolean aboveSystem, String reason) { 10364 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10365 != PackageManager.PERMISSION_GRANTED) { 10366 throw new SecurityException("Requires permission " 10367 + android.Manifest.permission.FILTER_EVENTS); 10368 } 10369 10370 final String annotation; 10371 if (reason == null) { 10372 annotation = "Input dispatching timed out"; 10373 } else { 10374 annotation = "Input dispatching timed out (" + reason + ")"; 10375 } 10376 10377 if (proc != null) { 10378 synchronized (this) { 10379 if (proc.debugging) { 10380 return false; 10381 } 10382 10383 if (mDidDexOpt) { 10384 // Give more time since we were dexopting. 10385 mDidDexOpt = false; 10386 return false; 10387 } 10388 10389 if (proc.instrumentationClass != null) { 10390 Bundle info = new Bundle(); 10391 info.putString("shortMsg", "keyDispatchingTimedOut"); 10392 info.putString("longMsg", annotation); 10393 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10394 return true; 10395 } 10396 } 10397 mHandler.post(new Runnable() { 10398 @Override 10399 public void run() { 10400 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10401 } 10402 }); 10403 } 10404 10405 return true; 10406 } 10407 10408 public Bundle getAssistContextExtras(int requestType) { 10409 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10410 UserHandle.getCallingUserId()); 10411 if (pae == null) { 10412 return null; 10413 } 10414 synchronized (pae) { 10415 while (!pae.haveResult) { 10416 try { 10417 pae.wait(); 10418 } catch (InterruptedException e) { 10419 } 10420 } 10421 if (pae.result != null) { 10422 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10423 } 10424 } 10425 synchronized (this) { 10426 mPendingAssistExtras.remove(pae); 10427 mHandler.removeCallbacks(pae); 10428 } 10429 return pae.extras; 10430 } 10431 10432 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10433 int userHandle) { 10434 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10435 "getAssistContextExtras()"); 10436 PendingAssistExtras pae; 10437 Bundle extras = new Bundle(); 10438 synchronized (this) { 10439 ActivityRecord activity = getFocusedStack().mResumedActivity; 10440 if (activity == null) { 10441 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10442 return null; 10443 } 10444 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10445 if (activity.app == null || activity.app.thread == null) { 10446 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10447 return null; 10448 } 10449 if (activity.app.pid == Binder.getCallingPid()) { 10450 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10451 return null; 10452 } 10453 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10454 try { 10455 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10456 requestType); 10457 mPendingAssistExtras.add(pae); 10458 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10459 } catch (RemoteException e) { 10460 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10461 return null; 10462 } 10463 return pae; 10464 } 10465 } 10466 10467 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10468 PendingAssistExtras pae = (PendingAssistExtras)token; 10469 synchronized (pae) { 10470 pae.result = extras; 10471 pae.haveResult = true; 10472 pae.notifyAll(); 10473 if (pae.intent == null) { 10474 // Caller is just waiting for the result. 10475 return; 10476 } 10477 } 10478 10479 // We are now ready to launch the assist activity. 10480 synchronized (this) { 10481 boolean exists = mPendingAssistExtras.remove(pae); 10482 mHandler.removeCallbacks(pae); 10483 if (!exists) { 10484 // Timed out. 10485 return; 10486 } 10487 } 10488 pae.intent.replaceExtras(extras); 10489 if (pae.hint != null) { 10490 pae.intent.putExtra(pae.hint, true); 10491 } 10492 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10493 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10494 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10495 closeSystemDialogs("assist"); 10496 try { 10497 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10498 } catch (ActivityNotFoundException e) { 10499 Slog.w(TAG, "No activity to handle assist action.", e); 10500 } 10501 } 10502 10503 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10504 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10505 } 10506 10507 public void registerProcessObserver(IProcessObserver observer) { 10508 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10509 "registerProcessObserver()"); 10510 synchronized (this) { 10511 mProcessObservers.register(observer); 10512 } 10513 } 10514 10515 @Override 10516 public void unregisterProcessObserver(IProcessObserver observer) { 10517 synchronized (this) { 10518 mProcessObservers.unregister(observer); 10519 } 10520 } 10521 10522 @Override 10523 public boolean convertFromTranslucent(IBinder token) { 10524 final long origId = Binder.clearCallingIdentity(); 10525 try { 10526 synchronized (this) { 10527 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10528 if (r == null) { 10529 return false; 10530 } 10531 final boolean translucentChanged = r.changeWindowTranslucency(true); 10532 if (translucentChanged) { 10533 r.task.stack.releaseBackgroundResources(); 10534 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10535 } 10536 mWindowManager.setAppFullscreen(token, true); 10537 return translucentChanged; 10538 } 10539 } finally { 10540 Binder.restoreCallingIdentity(origId); 10541 } 10542 } 10543 10544 @Override 10545 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10546 final long origId = Binder.clearCallingIdentity(); 10547 try { 10548 synchronized (this) { 10549 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10550 if (r == null) { 10551 return false; 10552 } 10553 int index = r.task.mActivities.lastIndexOf(r); 10554 if (index > 0) { 10555 ActivityRecord under = r.task.mActivities.get(index - 1); 10556 under.returningOptions = options; 10557 } 10558 final boolean translucentChanged = r.changeWindowTranslucency(false); 10559 if (translucentChanged) { 10560 r.task.stack.convertToTranslucent(r); 10561 } 10562 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10563 mWindowManager.setAppFullscreen(token, false); 10564 return translucentChanged; 10565 } 10566 } finally { 10567 Binder.restoreCallingIdentity(origId); 10568 } 10569 } 10570 10571 @Override 10572 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10573 final long origId = Binder.clearCallingIdentity(); 10574 try { 10575 synchronized (this) { 10576 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10577 if (r != null) { 10578 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10579 } 10580 } 10581 return false; 10582 } finally { 10583 Binder.restoreCallingIdentity(origId); 10584 } 10585 } 10586 10587 @Override 10588 public boolean isBackgroundVisibleBehind(IBinder token) { 10589 final long origId = Binder.clearCallingIdentity(); 10590 try { 10591 synchronized (this) { 10592 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10593 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10594 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10595 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10596 return visible; 10597 } 10598 } finally { 10599 Binder.restoreCallingIdentity(origId); 10600 } 10601 } 10602 10603 @Override 10604 public ActivityOptions getActivityOptions(IBinder token) { 10605 final long origId = Binder.clearCallingIdentity(); 10606 try { 10607 synchronized (this) { 10608 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10609 if (r != null) { 10610 final ActivityOptions activityOptions = r.pendingOptions; 10611 r.pendingOptions = null; 10612 return activityOptions; 10613 } 10614 return null; 10615 } 10616 } finally { 10617 Binder.restoreCallingIdentity(origId); 10618 } 10619 } 10620 10621 @Override 10622 public void setImmersive(IBinder token, boolean immersive) { 10623 synchronized(this) { 10624 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10625 if (r == null) { 10626 throw new IllegalArgumentException(); 10627 } 10628 r.immersive = immersive; 10629 10630 // update associated state if we're frontmost 10631 if (r == mFocusedActivity) { 10632 if (DEBUG_IMMERSIVE) { 10633 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10634 } 10635 applyUpdateLockStateLocked(r); 10636 } 10637 } 10638 } 10639 10640 @Override 10641 public boolean isImmersive(IBinder token) { 10642 synchronized (this) { 10643 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10644 if (r == null) { 10645 throw new IllegalArgumentException(); 10646 } 10647 return r.immersive; 10648 } 10649 } 10650 10651 public boolean isTopActivityImmersive() { 10652 enforceNotIsolatedCaller("startActivity"); 10653 synchronized (this) { 10654 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10655 return (r != null) ? r.immersive : false; 10656 } 10657 } 10658 10659 @Override 10660 public boolean isTopOfTask(IBinder token) { 10661 synchronized (this) { 10662 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10663 if (r == null) { 10664 throw new IllegalArgumentException(); 10665 } 10666 return r.task.getTopActivity() == r; 10667 } 10668 } 10669 10670 public final void enterSafeMode() { 10671 synchronized(this) { 10672 // It only makes sense to do this before the system is ready 10673 // and started launching other packages. 10674 if (!mSystemReady) { 10675 try { 10676 AppGlobals.getPackageManager().enterSafeMode(); 10677 } catch (RemoteException e) { 10678 } 10679 } 10680 10681 mSafeMode = true; 10682 } 10683 } 10684 10685 public final void showSafeModeOverlay() { 10686 View v = LayoutInflater.from(mContext).inflate( 10687 com.android.internal.R.layout.safe_mode, null); 10688 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10689 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10690 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10691 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10692 lp.gravity = Gravity.BOTTOM | Gravity.START; 10693 lp.format = v.getBackground().getOpacity(); 10694 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10695 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10696 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10697 ((WindowManager)mContext.getSystemService( 10698 Context.WINDOW_SERVICE)).addView(v, lp); 10699 } 10700 10701 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10702 if (!(sender instanceof PendingIntentRecord)) { 10703 return; 10704 } 10705 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10706 synchronized (stats) { 10707 if (mBatteryStatsService.isOnBattery()) { 10708 mBatteryStatsService.enforceCallingPermission(); 10709 PendingIntentRecord rec = (PendingIntentRecord)sender; 10710 int MY_UID = Binder.getCallingUid(); 10711 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10712 BatteryStatsImpl.Uid.Pkg pkg = 10713 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10714 sourcePkg != null ? sourcePkg : rec.key.packageName); 10715 pkg.incWakeupsLocked(); 10716 } 10717 } 10718 } 10719 10720 public boolean killPids(int[] pids, String pReason, boolean secure) { 10721 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10722 throw new SecurityException("killPids only available to the system"); 10723 } 10724 String reason = (pReason == null) ? "Unknown" : pReason; 10725 // XXX Note: don't acquire main activity lock here, because the window 10726 // manager calls in with its locks held. 10727 10728 boolean killed = false; 10729 synchronized (mPidsSelfLocked) { 10730 int[] types = new int[pids.length]; 10731 int worstType = 0; 10732 for (int i=0; i<pids.length; i++) { 10733 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10734 if (proc != null) { 10735 int type = proc.setAdj; 10736 types[i] = type; 10737 if (type > worstType) { 10738 worstType = type; 10739 } 10740 } 10741 } 10742 10743 // If the worst oom_adj is somewhere in the cached proc LRU range, 10744 // then constrain it so we will kill all cached procs. 10745 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10746 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10747 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10748 } 10749 10750 // If this is not a secure call, don't let it kill processes that 10751 // are important. 10752 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10753 worstType = ProcessList.SERVICE_ADJ; 10754 } 10755 10756 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10757 for (int i=0; i<pids.length; i++) { 10758 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10759 if (proc == null) { 10760 continue; 10761 } 10762 int adj = proc.setAdj; 10763 if (adj >= worstType && !proc.killedByAm) { 10764 proc.kill(reason, true); 10765 killed = true; 10766 } 10767 } 10768 } 10769 return killed; 10770 } 10771 10772 @Override 10773 public void killUid(int uid, String reason) { 10774 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10775 throw new SecurityException("killUid only available to the system"); 10776 } 10777 synchronized (this) { 10778 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10779 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10780 reason != null ? reason : "kill uid"); 10781 } 10782 } 10783 10784 @Override 10785 public boolean killProcessesBelowForeground(String reason) { 10786 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10787 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10788 } 10789 10790 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10791 } 10792 10793 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10794 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10795 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10796 } 10797 10798 boolean killed = false; 10799 synchronized (mPidsSelfLocked) { 10800 final int size = mPidsSelfLocked.size(); 10801 for (int i = 0; i < size; i++) { 10802 final int pid = mPidsSelfLocked.keyAt(i); 10803 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10804 if (proc == null) continue; 10805 10806 final int adj = proc.setAdj; 10807 if (adj > belowAdj && !proc.killedByAm) { 10808 proc.kill(reason, true); 10809 killed = true; 10810 } 10811 } 10812 } 10813 return killed; 10814 } 10815 10816 @Override 10817 public void hang(final IBinder who, boolean allowRestart) { 10818 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10819 != PackageManager.PERMISSION_GRANTED) { 10820 throw new SecurityException("Requires permission " 10821 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10822 } 10823 10824 final IBinder.DeathRecipient death = new DeathRecipient() { 10825 @Override 10826 public void binderDied() { 10827 synchronized (this) { 10828 notifyAll(); 10829 } 10830 } 10831 }; 10832 10833 try { 10834 who.linkToDeath(death, 0); 10835 } catch (RemoteException e) { 10836 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10837 return; 10838 } 10839 10840 synchronized (this) { 10841 Watchdog.getInstance().setAllowRestart(allowRestart); 10842 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10843 synchronized (death) { 10844 while (who.isBinderAlive()) { 10845 try { 10846 death.wait(); 10847 } catch (InterruptedException e) { 10848 } 10849 } 10850 } 10851 Watchdog.getInstance().setAllowRestart(true); 10852 } 10853 } 10854 10855 @Override 10856 public void restart() { 10857 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10858 != PackageManager.PERMISSION_GRANTED) { 10859 throw new SecurityException("Requires permission " 10860 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10861 } 10862 10863 Log.i(TAG, "Sending shutdown broadcast..."); 10864 10865 BroadcastReceiver br = new BroadcastReceiver() { 10866 @Override public void onReceive(Context context, Intent intent) { 10867 // Now the broadcast is done, finish up the low-level shutdown. 10868 Log.i(TAG, "Shutting down activity manager..."); 10869 shutdown(10000); 10870 Log.i(TAG, "Shutdown complete, restarting!"); 10871 Process.killProcess(Process.myPid()); 10872 System.exit(10); 10873 } 10874 }; 10875 10876 // First send the high-level shut down broadcast. 10877 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10878 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10879 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10880 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10881 mContext.sendOrderedBroadcastAsUser(intent, 10882 UserHandle.ALL, null, br, mHandler, 0, null, null); 10883 */ 10884 br.onReceive(mContext, intent); 10885 } 10886 10887 private long getLowRamTimeSinceIdle(long now) { 10888 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10889 } 10890 10891 @Override 10892 public void performIdleMaintenance() { 10893 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10894 != PackageManager.PERMISSION_GRANTED) { 10895 throw new SecurityException("Requires permission " 10896 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10897 } 10898 10899 synchronized (this) { 10900 final long now = SystemClock.uptimeMillis(); 10901 final long timeSinceLastIdle = now - mLastIdleTime; 10902 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10903 mLastIdleTime = now; 10904 mLowRamTimeSinceLastIdle = 0; 10905 if (mLowRamStartTime != 0) { 10906 mLowRamStartTime = now; 10907 } 10908 10909 StringBuilder sb = new StringBuilder(128); 10910 sb.append("Idle maintenance over "); 10911 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10912 sb.append(" low RAM for "); 10913 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10914 Slog.i(TAG, sb.toString()); 10915 10916 // If at least 1/3 of our time since the last idle period has been spent 10917 // with RAM low, then we want to kill processes. 10918 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10919 10920 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10921 ProcessRecord proc = mLruProcesses.get(i); 10922 if (proc.notCachedSinceIdle) { 10923 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10924 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10925 if (doKilling && proc.initialIdlePss != 0 10926 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10927 proc.kill("idle maint (pss " + proc.lastPss 10928 + " from " + proc.initialIdlePss + ")", true); 10929 } 10930 } 10931 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10932 proc.notCachedSinceIdle = true; 10933 proc.initialIdlePss = 0; 10934 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10935 isSleeping(), now); 10936 } 10937 } 10938 10939 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10940 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10941 } 10942 } 10943 10944 private void retrieveSettings() { 10945 final ContentResolver resolver = mContext.getContentResolver(); 10946 String debugApp = Settings.Global.getString( 10947 resolver, Settings.Global.DEBUG_APP); 10948 boolean waitForDebugger = Settings.Global.getInt( 10949 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10950 boolean alwaysFinishActivities = Settings.Global.getInt( 10951 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10952 boolean forceRtl = Settings.Global.getInt( 10953 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10954 // Transfer any global setting for forcing RTL layout, into a System Property 10955 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10956 10957 Configuration configuration = new Configuration(); 10958 Settings.System.getConfiguration(resolver, configuration); 10959 if (forceRtl) { 10960 // This will take care of setting the correct layout direction flags 10961 configuration.setLayoutDirection(configuration.locale); 10962 } 10963 10964 synchronized (this) { 10965 mDebugApp = mOrigDebugApp = debugApp; 10966 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10967 mAlwaysFinishActivities = alwaysFinishActivities; 10968 // This happens before any activities are started, so we can 10969 // change mConfiguration in-place. 10970 updateConfigurationLocked(configuration, null, false, true); 10971 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10972 } 10973 } 10974 10975 /** Loads resources after the current configuration has been set. */ 10976 private void loadResourcesOnSystemReady() { 10977 final Resources res = mContext.getResources(); 10978 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10979 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10980 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10981 } 10982 10983 public boolean testIsSystemReady() { 10984 // no need to synchronize(this) just to read & return the value 10985 return mSystemReady; 10986 } 10987 10988 private static File getCalledPreBootReceiversFile() { 10989 File dataDir = Environment.getDataDirectory(); 10990 File systemDir = new File(dataDir, "system"); 10991 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10992 return fname; 10993 } 10994 10995 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10996 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10997 File file = getCalledPreBootReceiversFile(); 10998 FileInputStream fis = null; 10999 try { 11000 fis = new FileInputStream(file); 11001 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11002 int fvers = dis.readInt(); 11003 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11004 String vers = dis.readUTF(); 11005 String codename = dis.readUTF(); 11006 String build = dis.readUTF(); 11007 if (android.os.Build.VERSION.RELEASE.equals(vers) 11008 && android.os.Build.VERSION.CODENAME.equals(codename) 11009 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11010 int num = dis.readInt(); 11011 while (num > 0) { 11012 num--; 11013 String pkg = dis.readUTF(); 11014 String cls = dis.readUTF(); 11015 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11016 } 11017 } 11018 } 11019 } catch (FileNotFoundException e) { 11020 } catch (IOException e) { 11021 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11022 } finally { 11023 if (fis != null) { 11024 try { 11025 fis.close(); 11026 } catch (IOException e) { 11027 } 11028 } 11029 } 11030 return lastDoneReceivers; 11031 } 11032 11033 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11034 File file = getCalledPreBootReceiversFile(); 11035 FileOutputStream fos = null; 11036 DataOutputStream dos = null; 11037 try { 11038 fos = new FileOutputStream(file); 11039 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11040 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11041 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11042 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11043 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11044 dos.writeInt(list.size()); 11045 for (int i=0; i<list.size(); i++) { 11046 dos.writeUTF(list.get(i).getPackageName()); 11047 dos.writeUTF(list.get(i).getClassName()); 11048 } 11049 } catch (IOException e) { 11050 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11051 file.delete(); 11052 } finally { 11053 FileUtils.sync(fos); 11054 if (dos != null) { 11055 try { 11056 dos.close(); 11057 } catch (IOException e) { 11058 // TODO Auto-generated catch block 11059 e.printStackTrace(); 11060 } 11061 } 11062 } 11063 } 11064 11065 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11066 ArrayList<ComponentName> doneReceivers, int userId) { 11067 boolean waitingUpdate = false; 11068 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11069 List<ResolveInfo> ris = null; 11070 try { 11071 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11072 intent, null, 0, userId); 11073 } catch (RemoteException e) { 11074 } 11075 if (ris != null) { 11076 for (int i=ris.size()-1; i>=0; i--) { 11077 if ((ris.get(i).activityInfo.applicationInfo.flags 11078 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11079 ris.remove(i); 11080 } 11081 } 11082 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11083 11084 // For User 0, load the version number. When delivering to a new user, deliver 11085 // to all receivers. 11086 if (userId == UserHandle.USER_OWNER) { 11087 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11088 for (int i=0; i<ris.size(); i++) { 11089 ActivityInfo ai = ris.get(i).activityInfo; 11090 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11091 if (lastDoneReceivers.contains(comp)) { 11092 // We already did the pre boot receiver for this app with the current 11093 // platform version, so don't do it again... 11094 ris.remove(i); 11095 i--; 11096 // ...however, do keep it as one that has been done, so we don't 11097 // forget about it when rewriting the file of last done receivers. 11098 doneReceivers.add(comp); 11099 } 11100 } 11101 } 11102 11103 // If primary user, send broadcast to all available users, else just to userId 11104 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11105 : new int[] { userId }; 11106 for (int i = 0; i < ris.size(); i++) { 11107 ActivityInfo ai = ris.get(i).activityInfo; 11108 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11109 doneReceivers.add(comp); 11110 intent.setComponent(comp); 11111 for (int j=0; j<users.length; j++) { 11112 IIntentReceiver finisher = null; 11113 // On last receiver and user, set up a completion callback 11114 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11115 finisher = new IIntentReceiver.Stub() { 11116 public void performReceive(Intent intent, int resultCode, 11117 String data, Bundle extras, boolean ordered, 11118 boolean sticky, int sendingUser) { 11119 // The raw IIntentReceiver interface is called 11120 // with the AM lock held, so redispatch to 11121 // execute our code without the lock. 11122 mHandler.post(onFinishCallback); 11123 } 11124 }; 11125 } 11126 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11127 + " for user " + users[j]); 11128 broadcastIntentLocked(null, null, intent, null, finisher, 11129 0, null, null, null, AppOpsManager.OP_NONE, 11130 true, false, MY_PID, Process.SYSTEM_UID, 11131 users[j]); 11132 if (finisher != null) { 11133 waitingUpdate = true; 11134 } 11135 } 11136 } 11137 } 11138 11139 return waitingUpdate; 11140 } 11141 11142 public void systemReady(final Runnable goingCallback) { 11143 synchronized(this) { 11144 if (mSystemReady) { 11145 // If we're done calling all the receivers, run the next "boot phase" passed in 11146 // by the SystemServer 11147 if (goingCallback != null) { 11148 goingCallback.run(); 11149 } 11150 return; 11151 } 11152 11153 // Make sure we have the current profile info, since it is needed for 11154 // security checks. 11155 updateCurrentProfileIdsLocked(); 11156 11157 if (mRecentTasks == null) { 11158 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11159 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11160 if (!mRecentTasks.isEmpty()) { 11161 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11162 } 11163 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11164 mTaskPersister.startPersisting(); 11165 } 11166 11167 // Check to see if there are any update receivers to run. 11168 if (!mDidUpdate) { 11169 if (mWaitingUpdate) { 11170 return; 11171 } 11172 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11173 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11174 public void run() { 11175 synchronized (ActivityManagerService.this) { 11176 mDidUpdate = true; 11177 } 11178 writeLastDonePreBootReceivers(doneReceivers); 11179 showBootMessage(mContext.getText( 11180 R.string.android_upgrading_complete), 11181 false); 11182 systemReady(goingCallback); 11183 } 11184 }, doneReceivers, UserHandle.USER_OWNER); 11185 11186 if (mWaitingUpdate) { 11187 return; 11188 } 11189 mDidUpdate = true; 11190 } 11191 11192 mAppOpsService.systemReady(); 11193 mSystemReady = true; 11194 } 11195 11196 ArrayList<ProcessRecord> procsToKill = null; 11197 synchronized(mPidsSelfLocked) { 11198 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11199 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11200 if (!isAllowedWhileBooting(proc.info)){ 11201 if (procsToKill == null) { 11202 procsToKill = new ArrayList<ProcessRecord>(); 11203 } 11204 procsToKill.add(proc); 11205 } 11206 } 11207 } 11208 11209 synchronized(this) { 11210 if (procsToKill != null) { 11211 for (int i=procsToKill.size()-1; i>=0; i--) { 11212 ProcessRecord proc = procsToKill.get(i); 11213 Slog.i(TAG, "Removing system update proc: " + proc); 11214 removeProcessLocked(proc, true, false, "system update done"); 11215 } 11216 } 11217 11218 // Now that we have cleaned up any update processes, we 11219 // are ready to start launching real processes and know that 11220 // we won't trample on them any more. 11221 mProcessesReady = true; 11222 } 11223 11224 Slog.i(TAG, "System now ready"); 11225 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11226 SystemClock.uptimeMillis()); 11227 11228 synchronized(this) { 11229 // Make sure we have no pre-ready processes sitting around. 11230 11231 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11232 ResolveInfo ri = mContext.getPackageManager() 11233 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11234 STOCK_PM_FLAGS); 11235 CharSequence errorMsg = null; 11236 if (ri != null) { 11237 ActivityInfo ai = ri.activityInfo; 11238 ApplicationInfo app = ai.applicationInfo; 11239 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11240 mTopAction = Intent.ACTION_FACTORY_TEST; 11241 mTopData = null; 11242 mTopComponent = new ComponentName(app.packageName, 11243 ai.name); 11244 } else { 11245 errorMsg = mContext.getResources().getText( 11246 com.android.internal.R.string.factorytest_not_system); 11247 } 11248 } else { 11249 errorMsg = mContext.getResources().getText( 11250 com.android.internal.R.string.factorytest_no_action); 11251 } 11252 if (errorMsg != null) { 11253 mTopAction = null; 11254 mTopData = null; 11255 mTopComponent = null; 11256 Message msg = Message.obtain(); 11257 msg.what = SHOW_FACTORY_ERROR_MSG; 11258 msg.getData().putCharSequence("msg", errorMsg); 11259 mHandler.sendMessage(msg); 11260 } 11261 } 11262 } 11263 11264 retrieveSettings(); 11265 loadResourcesOnSystemReady(); 11266 11267 synchronized (this) { 11268 readGrantedUriPermissionsLocked(); 11269 } 11270 11271 if (goingCallback != null) goingCallback.run(); 11272 11273 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11274 Integer.toString(mCurrentUserId), mCurrentUserId); 11275 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11276 Integer.toString(mCurrentUserId), mCurrentUserId); 11277 mSystemServiceManager.startUser(mCurrentUserId); 11278 11279 synchronized (this) { 11280 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11281 try { 11282 List apps = AppGlobals.getPackageManager(). 11283 getPersistentApplications(STOCK_PM_FLAGS); 11284 if (apps != null) { 11285 int N = apps.size(); 11286 int i; 11287 for (i=0; i<N; i++) { 11288 ApplicationInfo info 11289 = (ApplicationInfo)apps.get(i); 11290 if (info != null && 11291 !info.packageName.equals("android")) { 11292 addAppLocked(info, false, null /* ABI override */); 11293 } 11294 } 11295 } 11296 } catch (RemoteException ex) { 11297 // pm is in same process, this will never happen. 11298 } 11299 } 11300 11301 // Start up initial activity. 11302 mBooting = true; 11303 startHomeActivityLocked(mCurrentUserId); 11304 11305 try { 11306 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11307 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11308 + " data partition or your device will be unstable."); 11309 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11310 } 11311 } catch (RemoteException e) { 11312 } 11313 11314 if (!Build.isFingerprintConsistent()) { 11315 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11316 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11317 } 11318 11319 long ident = Binder.clearCallingIdentity(); 11320 try { 11321 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11322 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11323 | Intent.FLAG_RECEIVER_FOREGROUND); 11324 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11325 broadcastIntentLocked(null, null, intent, 11326 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11327 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11328 intent = new Intent(Intent.ACTION_USER_STARTING); 11329 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11330 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11331 broadcastIntentLocked(null, null, intent, 11332 null, new IIntentReceiver.Stub() { 11333 @Override 11334 public void performReceive(Intent intent, int resultCode, String data, 11335 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11336 throws RemoteException { 11337 } 11338 }, 0, null, null, 11339 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11340 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11341 } catch (Throwable t) { 11342 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11343 } finally { 11344 Binder.restoreCallingIdentity(ident); 11345 } 11346 mStackSupervisor.resumeTopActivitiesLocked(); 11347 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11348 } 11349 } 11350 11351 private boolean makeAppCrashingLocked(ProcessRecord app, 11352 String shortMsg, String longMsg, String stackTrace) { 11353 app.crashing = true; 11354 app.crashingReport = generateProcessError(app, 11355 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11356 startAppProblemLocked(app); 11357 app.stopFreezingAllLocked(); 11358 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11359 } 11360 11361 private void makeAppNotRespondingLocked(ProcessRecord app, 11362 String activity, String shortMsg, String longMsg) { 11363 app.notResponding = true; 11364 app.notRespondingReport = generateProcessError(app, 11365 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11366 activity, shortMsg, longMsg, null); 11367 startAppProblemLocked(app); 11368 app.stopFreezingAllLocked(); 11369 } 11370 11371 /** 11372 * Generate a process error record, suitable for attachment to a ProcessRecord. 11373 * 11374 * @param app The ProcessRecord in which the error occurred. 11375 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11376 * ActivityManager.AppErrorStateInfo 11377 * @param activity The activity associated with the crash, if known. 11378 * @param shortMsg Short message describing the crash. 11379 * @param longMsg Long message describing the crash. 11380 * @param stackTrace Full crash stack trace, may be null. 11381 * 11382 * @return Returns a fully-formed AppErrorStateInfo record. 11383 */ 11384 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11385 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11386 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11387 11388 report.condition = condition; 11389 report.processName = app.processName; 11390 report.pid = app.pid; 11391 report.uid = app.info.uid; 11392 report.tag = activity; 11393 report.shortMsg = shortMsg; 11394 report.longMsg = longMsg; 11395 report.stackTrace = stackTrace; 11396 11397 return report; 11398 } 11399 11400 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11401 synchronized (this) { 11402 app.crashing = false; 11403 app.crashingReport = null; 11404 app.notResponding = false; 11405 app.notRespondingReport = null; 11406 if (app.anrDialog == fromDialog) { 11407 app.anrDialog = null; 11408 } 11409 if (app.waitDialog == fromDialog) { 11410 app.waitDialog = null; 11411 } 11412 if (app.pid > 0 && app.pid != MY_PID) { 11413 handleAppCrashLocked(app, null, null, null); 11414 app.kill("user request after error", true); 11415 } 11416 } 11417 } 11418 11419 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11420 String stackTrace) { 11421 long now = SystemClock.uptimeMillis(); 11422 11423 Long crashTime; 11424 if (!app.isolated) { 11425 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11426 } else { 11427 crashTime = null; 11428 } 11429 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11430 // This process loses! 11431 Slog.w(TAG, "Process " + app.info.processName 11432 + " has crashed too many times: killing!"); 11433 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11434 app.userId, app.info.processName, app.uid); 11435 mStackSupervisor.handleAppCrashLocked(app); 11436 if (!app.persistent) { 11437 // We don't want to start this process again until the user 11438 // explicitly does so... but for persistent process, we really 11439 // need to keep it running. If a persistent process is actually 11440 // repeatedly crashing, then badness for everyone. 11441 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11442 app.info.processName); 11443 if (!app.isolated) { 11444 // XXX We don't have a way to mark isolated processes 11445 // as bad, since they don't have a peristent identity. 11446 mBadProcesses.put(app.info.processName, app.uid, 11447 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11448 mProcessCrashTimes.remove(app.info.processName, app.uid); 11449 } 11450 app.bad = true; 11451 app.removed = true; 11452 // Don't let services in this process be restarted and potentially 11453 // annoy the user repeatedly. Unless it is persistent, since those 11454 // processes run critical code. 11455 removeProcessLocked(app, false, false, "crash"); 11456 mStackSupervisor.resumeTopActivitiesLocked(); 11457 return false; 11458 } 11459 mStackSupervisor.resumeTopActivitiesLocked(); 11460 } else { 11461 mStackSupervisor.finishTopRunningActivityLocked(app); 11462 } 11463 11464 // Bump up the crash count of any services currently running in the proc. 11465 for (int i=app.services.size()-1; i>=0; i--) { 11466 // Any services running in the application need to be placed 11467 // back in the pending list. 11468 ServiceRecord sr = app.services.valueAt(i); 11469 sr.crashCount++; 11470 } 11471 11472 // If the crashing process is what we consider to be the "home process" and it has been 11473 // replaced by a third-party app, clear the package preferred activities from packages 11474 // with a home activity running in the process to prevent a repeatedly crashing app 11475 // from blocking the user to manually clear the list. 11476 final ArrayList<ActivityRecord> activities = app.activities; 11477 if (app == mHomeProcess && activities.size() > 0 11478 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11479 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11480 final ActivityRecord r = activities.get(activityNdx); 11481 if (r.isHomeActivity()) { 11482 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11483 try { 11484 ActivityThread.getPackageManager() 11485 .clearPackagePreferredActivities(r.packageName); 11486 } catch (RemoteException c) { 11487 // pm is in same process, this will never happen. 11488 } 11489 } 11490 } 11491 } 11492 11493 if (!app.isolated) { 11494 // XXX Can't keep track of crash times for isolated processes, 11495 // because they don't have a perisistent identity. 11496 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11497 } 11498 11499 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11500 return true; 11501 } 11502 11503 void startAppProblemLocked(ProcessRecord app) { 11504 // If this app is not running under the current user, then we 11505 // can't give it a report button because that would require 11506 // launching the report UI under a different user. 11507 app.errorReportReceiver = null; 11508 11509 for (int userId : mCurrentProfileIds) { 11510 if (app.userId == userId) { 11511 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11512 mContext, app.info.packageName, app.info.flags); 11513 } 11514 } 11515 skipCurrentReceiverLocked(app); 11516 } 11517 11518 void skipCurrentReceiverLocked(ProcessRecord app) { 11519 for (BroadcastQueue queue : mBroadcastQueues) { 11520 queue.skipCurrentReceiverLocked(app); 11521 } 11522 } 11523 11524 /** 11525 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11526 * The application process will exit immediately after this call returns. 11527 * @param app object of the crashing app, null for the system server 11528 * @param crashInfo describing the exception 11529 */ 11530 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11531 ProcessRecord r = findAppProcess(app, "Crash"); 11532 final String processName = app == null ? "system_server" 11533 : (r == null ? "unknown" : r.processName); 11534 11535 handleApplicationCrashInner("crash", r, processName, crashInfo); 11536 } 11537 11538 /* Native crash reporting uses this inner version because it needs to be somewhat 11539 * decoupled from the AM-managed cleanup lifecycle 11540 */ 11541 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11542 ApplicationErrorReport.CrashInfo crashInfo) { 11543 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11544 UserHandle.getUserId(Binder.getCallingUid()), processName, 11545 r == null ? -1 : r.info.flags, 11546 crashInfo.exceptionClassName, 11547 crashInfo.exceptionMessage, 11548 crashInfo.throwFileName, 11549 crashInfo.throwLineNumber); 11550 11551 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11552 11553 crashApplication(r, crashInfo); 11554 } 11555 11556 public void handleApplicationStrictModeViolation( 11557 IBinder app, 11558 int violationMask, 11559 StrictMode.ViolationInfo info) { 11560 ProcessRecord r = findAppProcess(app, "StrictMode"); 11561 if (r == null) { 11562 return; 11563 } 11564 11565 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11566 Integer stackFingerprint = info.hashCode(); 11567 boolean logIt = true; 11568 synchronized (mAlreadyLoggedViolatedStacks) { 11569 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11570 logIt = false; 11571 // TODO: sub-sample into EventLog for these, with 11572 // the info.durationMillis? Then we'd get 11573 // the relative pain numbers, without logging all 11574 // the stack traces repeatedly. We'd want to do 11575 // likewise in the client code, which also does 11576 // dup suppression, before the Binder call. 11577 } else { 11578 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11579 mAlreadyLoggedViolatedStacks.clear(); 11580 } 11581 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11582 } 11583 } 11584 if (logIt) { 11585 logStrictModeViolationToDropBox(r, info); 11586 } 11587 } 11588 11589 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11590 AppErrorResult result = new AppErrorResult(); 11591 synchronized (this) { 11592 final long origId = Binder.clearCallingIdentity(); 11593 11594 Message msg = Message.obtain(); 11595 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11596 HashMap<String, Object> data = new HashMap<String, Object>(); 11597 data.put("result", result); 11598 data.put("app", r); 11599 data.put("violationMask", violationMask); 11600 data.put("info", info); 11601 msg.obj = data; 11602 mHandler.sendMessage(msg); 11603 11604 Binder.restoreCallingIdentity(origId); 11605 } 11606 int res = result.get(); 11607 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11608 } 11609 } 11610 11611 // Depending on the policy in effect, there could be a bunch of 11612 // these in quick succession so we try to batch these together to 11613 // minimize disk writes, number of dropbox entries, and maximize 11614 // compression, by having more fewer, larger records. 11615 private void logStrictModeViolationToDropBox( 11616 ProcessRecord process, 11617 StrictMode.ViolationInfo info) { 11618 if (info == null) { 11619 return; 11620 } 11621 final boolean isSystemApp = process == null || 11622 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11623 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11624 final String processName = process == null ? "unknown" : process.processName; 11625 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11626 final DropBoxManager dbox = (DropBoxManager) 11627 mContext.getSystemService(Context.DROPBOX_SERVICE); 11628 11629 // Exit early if the dropbox isn't configured to accept this report type. 11630 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11631 11632 boolean bufferWasEmpty; 11633 boolean needsFlush; 11634 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11635 synchronized (sb) { 11636 bufferWasEmpty = sb.length() == 0; 11637 appendDropBoxProcessHeaders(process, processName, sb); 11638 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11639 sb.append("System-App: ").append(isSystemApp).append("\n"); 11640 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11641 if (info.violationNumThisLoop != 0) { 11642 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11643 } 11644 if (info.numAnimationsRunning != 0) { 11645 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11646 } 11647 if (info.broadcastIntentAction != null) { 11648 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11649 } 11650 if (info.durationMillis != -1) { 11651 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11652 } 11653 if (info.numInstances != -1) { 11654 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11655 } 11656 if (info.tags != null) { 11657 for (String tag : info.tags) { 11658 sb.append("Span-Tag: ").append(tag).append("\n"); 11659 } 11660 } 11661 sb.append("\n"); 11662 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11663 sb.append(info.crashInfo.stackTrace); 11664 } 11665 sb.append("\n"); 11666 11667 // Only buffer up to ~64k. Various logging bits truncate 11668 // things at 128k. 11669 needsFlush = (sb.length() > 64 * 1024); 11670 } 11671 11672 // Flush immediately if the buffer's grown too large, or this 11673 // is a non-system app. Non-system apps are isolated with a 11674 // different tag & policy and not batched. 11675 // 11676 // Batching is useful during internal testing with 11677 // StrictMode settings turned up high. Without batching, 11678 // thousands of separate files could be created on boot. 11679 if (!isSystemApp || needsFlush) { 11680 new Thread("Error dump: " + dropboxTag) { 11681 @Override 11682 public void run() { 11683 String report; 11684 synchronized (sb) { 11685 report = sb.toString(); 11686 sb.delete(0, sb.length()); 11687 sb.trimToSize(); 11688 } 11689 if (report.length() != 0) { 11690 dbox.addText(dropboxTag, report); 11691 } 11692 } 11693 }.start(); 11694 return; 11695 } 11696 11697 // System app batching: 11698 if (!bufferWasEmpty) { 11699 // An existing dropbox-writing thread is outstanding, so 11700 // we don't need to start it up. The existing thread will 11701 // catch the buffer appends we just did. 11702 return; 11703 } 11704 11705 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11706 // (After this point, we shouldn't access AMS internal data structures.) 11707 new Thread("Error dump: " + dropboxTag) { 11708 @Override 11709 public void run() { 11710 // 5 second sleep to let stacks arrive and be batched together 11711 try { 11712 Thread.sleep(5000); // 5 seconds 11713 } catch (InterruptedException e) {} 11714 11715 String errorReport; 11716 synchronized (mStrictModeBuffer) { 11717 errorReport = mStrictModeBuffer.toString(); 11718 if (errorReport.length() == 0) { 11719 return; 11720 } 11721 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11722 mStrictModeBuffer.trimToSize(); 11723 } 11724 dbox.addText(dropboxTag, errorReport); 11725 } 11726 }.start(); 11727 } 11728 11729 /** 11730 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11731 * @param app object of the crashing app, null for the system server 11732 * @param tag reported by the caller 11733 * @param system whether this wtf is coming from the system 11734 * @param crashInfo describing the context of the error 11735 * @return true if the process should exit immediately (WTF is fatal) 11736 */ 11737 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11738 final ApplicationErrorReport.CrashInfo crashInfo) { 11739 final int callingUid = Binder.getCallingUid(); 11740 final int callingPid = Binder.getCallingPid(); 11741 11742 if (system) { 11743 // If this is coming from the system, we could very well have low-level 11744 // system locks held, so we want to do this all asynchronously. And we 11745 // never want this to become fatal, so there is that too. 11746 mHandler.post(new Runnable() { 11747 @Override public void run() { 11748 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11749 } 11750 }); 11751 return false; 11752 } 11753 11754 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11755 crashInfo); 11756 11757 if (r != null && r.pid != Process.myPid() && 11758 Settings.Global.getInt(mContext.getContentResolver(), 11759 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11760 crashApplication(r, crashInfo); 11761 return true; 11762 } else { 11763 return false; 11764 } 11765 } 11766 11767 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11768 final ApplicationErrorReport.CrashInfo crashInfo) { 11769 final ProcessRecord r = findAppProcess(app, "WTF"); 11770 final String processName = app == null ? "system_server" 11771 : (r == null ? "unknown" : r.processName); 11772 11773 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11774 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11775 11776 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11777 11778 return r; 11779 } 11780 11781 /** 11782 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11783 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11784 */ 11785 private ProcessRecord findAppProcess(IBinder app, String reason) { 11786 if (app == null) { 11787 return null; 11788 } 11789 11790 synchronized (this) { 11791 final int NP = mProcessNames.getMap().size(); 11792 for (int ip=0; ip<NP; ip++) { 11793 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11794 final int NA = apps.size(); 11795 for (int ia=0; ia<NA; ia++) { 11796 ProcessRecord p = apps.valueAt(ia); 11797 if (p.thread != null && p.thread.asBinder() == app) { 11798 return p; 11799 } 11800 } 11801 } 11802 11803 Slog.w(TAG, "Can't find mystery application for " + reason 11804 + " from pid=" + Binder.getCallingPid() 11805 + " uid=" + Binder.getCallingUid() + ": " + app); 11806 return null; 11807 } 11808 } 11809 11810 /** 11811 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11812 * to append various headers to the dropbox log text. 11813 */ 11814 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11815 StringBuilder sb) { 11816 // Watchdog thread ends up invoking this function (with 11817 // a null ProcessRecord) to add the stack file to dropbox. 11818 // Do not acquire a lock on this (am) in such cases, as it 11819 // could cause a potential deadlock, if and when watchdog 11820 // is invoked due to unavailability of lock on am and it 11821 // would prevent watchdog from killing system_server. 11822 if (process == null) { 11823 sb.append("Process: ").append(processName).append("\n"); 11824 return; 11825 } 11826 // Note: ProcessRecord 'process' is guarded by the service 11827 // instance. (notably process.pkgList, which could otherwise change 11828 // concurrently during execution of this method) 11829 synchronized (this) { 11830 sb.append("Process: ").append(processName).append("\n"); 11831 int flags = process.info.flags; 11832 IPackageManager pm = AppGlobals.getPackageManager(); 11833 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11834 for (int ip=0; ip<process.pkgList.size(); ip++) { 11835 String pkg = process.pkgList.keyAt(ip); 11836 sb.append("Package: ").append(pkg); 11837 try { 11838 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11839 if (pi != null) { 11840 sb.append(" v").append(pi.versionCode); 11841 if (pi.versionName != null) { 11842 sb.append(" (").append(pi.versionName).append(")"); 11843 } 11844 } 11845 } catch (RemoteException e) { 11846 Slog.e(TAG, "Error getting package info: " + pkg, e); 11847 } 11848 sb.append("\n"); 11849 } 11850 } 11851 } 11852 11853 private static String processClass(ProcessRecord process) { 11854 if (process == null || process.pid == MY_PID) { 11855 return "system_server"; 11856 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11857 return "system_app"; 11858 } else { 11859 return "data_app"; 11860 } 11861 } 11862 11863 /** 11864 * Write a description of an error (crash, WTF, ANR) to the drop box. 11865 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11866 * @param process which caused the error, null means the system server 11867 * @param activity which triggered the error, null if unknown 11868 * @param parent activity related to the error, null if unknown 11869 * @param subject line related to the error, null if absent 11870 * @param report in long form describing the error, null if absent 11871 * @param logFile to include in the report, null if none 11872 * @param crashInfo giving an application stack trace, null if absent 11873 */ 11874 public void addErrorToDropBox(String eventType, 11875 ProcessRecord process, String processName, ActivityRecord activity, 11876 ActivityRecord parent, String subject, 11877 final String report, final File logFile, 11878 final ApplicationErrorReport.CrashInfo crashInfo) { 11879 // NOTE -- this must never acquire the ActivityManagerService lock, 11880 // otherwise the watchdog may be prevented from resetting the system. 11881 11882 final String dropboxTag = processClass(process) + "_" + eventType; 11883 final DropBoxManager dbox = (DropBoxManager) 11884 mContext.getSystemService(Context.DROPBOX_SERVICE); 11885 11886 // Exit early if the dropbox isn't configured to accept this report type. 11887 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11888 11889 final StringBuilder sb = new StringBuilder(1024); 11890 appendDropBoxProcessHeaders(process, processName, sb); 11891 if (activity != null) { 11892 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11893 } 11894 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11895 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11896 } 11897 if (parent != null && parent != activity) { 11898 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11899 } 11900 if (subject != null) { 11901 sb.append("Subject: ").append(subject).append("\n"); 11902 } 11903 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11904 if (Debug.isDebuggerConnected()) { 11905 sb.append("Debugger: Connected\n"); 11906 } 11907 sb.append("\n"); 11908 11909 // Do the rest in a worker thread to avoid blocking the caller on I/O 11910 // (After this point, we shouldn't access AMS internal data structures.) 11911 Thread worker = new Thread("Error dump: " + dropboxTag) { 11912 @Override 11913 public void run() { 11914 if (report != null) { 11915 sb.append(report); 11916 } 11917 if (logFile != null) { 11918 try { 11919 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11920 "\n\n[[TRUNCATED]]")); 11921 } catch (IOException e) { 11922 Slog.e(TAG, "Error reading " + logFile, e); 11923 } 11924 } 11925 if (crashInfo != null && crashInfo.stackTrace != null) { 11926 sb.append(crashInfo.stackTrace); 11927 } 11928 11929 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11930 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11931 if (lines > 0) { 11932 sb.append("\n"); 11933 11934 // Merge several logcat streams, and take the last N lines 11935 InputStreamReader input = null; 11936 try { 11937 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11938 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11939 "-b", "crash", 11940 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11941 11942 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11943 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11944 input = new InputStreamReader(logcat.getInputStream()); 11945 11946 int num; 11947 char[] buf = new char[8192]; 11948 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11949 } catch (IOException e) { 11950 Slog.e(TAG, "Error running logcat", e); 11951 } finally { 11952 if (input != null) try { input.close(); } catch (IOException e) {} 11953 } 11954 } 11955 11956 dbox.addText(dropboxTag, sb.toString()); 11957 } 11958 }; 11959 11960 if (process == null) { 11961 // If process is null, we are being called from some internal code 11962 // and may be about to die -- run this synchronously. 11963 worker.run(); 11964 } else { 11965 worker.start(); 11966 } 11967 } 11968 11969 /** 11970 * Bring up the "unexpected error" dialog box for a crashing app. 11971 * Deal with edge cases (intercepts from instrumented applications, 11972 * ActivityController, error intent receivers, that sort of thing). 11973 * @param r the application crashing 11974 * @param crashInfo describing the failure 11975 */ 11976 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11977 long timeMillis = System.currentTimeMillis(); 11978 String shortMsg = crashInfo.exceptionClassName; 11979 String longMsg = crashInfo.exceptionMessage; 11980 String stackTrace = crashInfo.stackTrace; 11981 if (shortMsg != null && longMsg != null) { 11982 longMsg = shortMsg + ": " + longMsg; 11983 } else if (shortMsg != null) { 11984 longMsg = shortMsg; 11985 } 11986 11987 AppErrorResult result = new AppErrorResult(); 11988 synchronized (this) { 11989 if (mController != null) { 11990 try { 11991 String name = r != null ? r.processName : null; 11992 int pid = r != null ? r.pid : Binder.getCallingPid(); 11993 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11994 if (!mController.appCrashed(name, pid, 11995 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11996 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11997 && "Native crash".equals(crashInfo.exceptionClassName)) { 11998 Slog.w(TAG, "Skip killing native crashed app " + name 11999 + "(" + pid + ") during testing"); 12000 } else { 12001 Slog.w(TAG, "Force-killing crashed app " + name 12002 + " at watcher's request"); 12003 if (r != null) { 12004 r.kill("crash", true); 12005 } else { 12006 // Huh. 12007 Process.killProcess(pid); 12008 Process.killProcessGroup(uid, pid); 12009 } 12010 } 12011 return; 12012 } 12013 } catch (RemoteException e) { 12014 mController = null; 12015 Watchdog.getInstance().setActivityController(null); 12016 } 12017 } 12018 12019 final long origId = Binder.clearCallingIdentity(); 12020 12021 // If this process is running instrumentation, finish it. 12022 if (r != null && r.instrumentationClass != null) { 12023 Slog.w(TAG, "Error in app " + r.processName 12024 + " running instrumentation " + r.instrumentationClass + ":"); 12025 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12026 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12027 Bundle info = new Bundle(); 12028 info.putString("shortMsg", shortMsg); 12029 info.putString("longMsg", longMsg); 12030 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12031 Binder.restoreCallingIdentity(origId); 12032 return; 12033 } 12034 12035 // If we can't identify the process or it's already exceeded its crash quota, 12036 // quit right away without showing a crash dialog. 12037 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12038 Binder.restoreCallingIdentity(origId); 12039 return; 12040 } 12041 12042 Message msg = Message.obtain(); 12043 msg.what = SHOW_ERROR_MSG; 12044 HashMap data = new HashMap(); 12045 data.put("result", result); 12046 data.put("app", r); 12047 msg.obj = data; 12048 mHandler.sendMessage(msg); 12049 12050 Binder.restoreCallingIdentity(origId); 12051 } 12052 12053 int res = result.get(); 12054 12055 Intent appErrorIntent = null; 12056 synchronized (this) { 12057 if (r != null && !r.isolated) { 12058 // XXX Can't keep track of crash time for isolated processes, 12059 // since they don't have a persistent identity. 12060 mProcessCrashTimes.put(r.info.processName, r.uid, 12061 SystemClock.uptimeMillis()); 12062 } 12063 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12064 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12065 } 12066 } 12067 12068 if (appErrorIntent != null) { 12069 try { 12070 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12071 } catch (ActivityNotFoundException e) { 12072 Slog.w(TAG, "bug report receiver dissappeared", e); 12073 } 12074 } 12075 } 12076 12077 Intent createAppErrorIntentLocked(ProcessRecord r, 12078 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12079 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12080 if (report == null) { 12081 return null; 12082 } 12083 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12084 result.setComponent(r.errorReportReceiver); 12085 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12086 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12087 return result; 12088 } 12089 12090 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12091 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12092 if (r.errorReportReceiver == null) { 12093 return null; 12094 } 12095 12096 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12097 return null; 12098 } 12099 12100 ApplicationErrorReport report = new ApplicationErrorReport(); 12101 report.packageName = r.info.packageName; 12102 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12103 report.processName = r.processName; 12104 report.time = timeMillis; 12105 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12106 12107 if (r.crashing || r.forceCrashReport) { 12108 report.type = ApplicationErrorReport.TYPE_CRASH; 12109 report.crashInfo = crashInfo; 12110 } else if (r.notResponding) { 12111 report.type = ApplicationErrorReport.TYPE_ANR; 12112 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12113 12114 report.anrInfo.activity = r.notRespondingReport.tag; 12115 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12116 report.anrInfo.info = r.notRespondingReport.longMsg; 12117 } 12118 12119 return report; 12120 } 12121 12122 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12123 enforceNotIsolatedCaller("getProcessesInErrorState"); 12124 // assume our apps are happy - lazy create the list 12125 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12126 12127 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12128 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12129 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12130 12131 synchronized (this) { 12132 12133 // iterate across all processes 12134 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12135 ProcessRecord app = mLruProcesses.get(i); 12136 if (!allUsers && app.userId != userId) { 12137 continue; 12138 } 12139 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12140 // This one's in trouble, so we'll generate a report for it 12141 // crashes are higher priority (in case there's a crash *and* an anr) 12142 ActivityManager.ProcessErrorStateInfo report = null; 12143 if (app.crashing) { 12144 report = app.crashingReport; 12145 } else if (app.notResponding) { 12146 report = app.notRespondingReport; 12147 } 12148 12149 if (report != null) { 12150 if (errList == null) { 12151 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12152 } 12153 errList.add(report); 12154 } else { 12155 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12156 " crashing = " + app.crashing + 12157 " notResponding = " + app.notResponding); 12158 } 12159 } 12160 } 12161 } 12162 12163 return errList; 12164 } 12165 12166 static int procStateToImportance(int procState, int memAdj, 12167 ActivityManager.RunningAppProcessInfo currApp) { 12168 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12169 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12170 currApp.lru = memAdj; 12171 } else { 12172 currApp.lru = 0; 12173 } 12174 return imp; 12175 } 12176 12177 private void fillInProcMemInfo(ProcessRecord app, 12178 ActivityManager.RunningAppProcessInfo outInfo) { 12179 outInfo.pid = app.pid; 12180 outInfo.uid = app.info.uid; 12181 if (mHeavyWeightProcess == app) { 12182 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12183 } 12184 if (app.persistent) { 12185 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12186 } 12187 if (app.activities.size() > 0) { 12188 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12189 } 12190 outInfo.lastTrimLevel = app.trimMemoryLevel; 12191 int adj = app.curAdj; 12192 int procState = app.curProcState; 12193 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12194 outInfo.importanceReasonCode = app.adjTypeCode; 12195 outInfo.processState = app.curProcState; 12196 } 12197 12198 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12199 enforceNotIsolatedCaller("getRunningAppProcesses"); 12200 // Lazy instantiation of list 12201 List<ActivityManager.RunningAppProcessInfo> runList = null; 12202 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12203 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12204 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12205 synchronized (this) { 12206 // Iterate across all processes 12207 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12208 ProcessRecord app = mLruProcesses.get(i); 12209 if (!allUsers && app.userId != userId) { 12210 continue; 12211 } 12212 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12213 // Generate process state info for running application 12214 ActivityManager.RunningAppProcessInfo currApp = 12215 new ActivityManager.RunningAppProcessInfo(app.processName, 12216 app.pid, app.getPackageList()); 12217 fillInProcMemInfo(app, currApp); 12218 if (app.adjSource instanceof ProcessRecord) { 12219 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12220 currApp.importanceReasonImportance = 12221 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12222 app.adjSourceProcState); 12223 } else if (app.adjSource instanceof ActivityRecord) { 12224 ActivityRecord r = (ActivityRecord)app.adjSource; 12225 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12226 } 12227 if (app.adjTarget instanceof ComponentName) { 12228 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12229 } 12230 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12231 // + " lru=" + currApp.lru); 12232 if (runList == null) { 12233 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12234 } 12235 runList.add(currApp); 12236 } 12237 } 12238 } 12239 return runList; 12240 } 12241 12242 public List<ApplicationInfo> getRunningExternalApplications() { 12243 enforceNotIsolatedCaller("getRunningExternalApplications"); 12244 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12245 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12246 if (runningApps != null && runningApps.size() > 0) { 12247 Set<String> extList = new HashSet<String>(); 12248 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12249 if (app.pkgList != null) { 12250 for (String pkg : app.pkgList) { 12251 extList.add(pkg); 12252 } 12253 } 12254 } 12255 IPackageManager pm = AppGlobals.getPackageManager(); 12256 for (String pkg : extList) { 12257 try { 12258 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12259 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12260 retList.add(info); 12261 } 12262 } catch (RemoteException e) { 12263 } 12264 } 12265 } 12266 return retList; 12267 } 12268 12269 @Override 12270 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12271 enforceNotIsolatedCaller("getMyMemoryState"); 12272 synchronized (this) { 12273 ProcessRecord proc; 12274 synchronized (mPidsSelfLocked) { 12275 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12276 } 12277 fillInProcMemInfo(proc, outInfo); 12278 } 12279 } 12280 12281 @Override 12282 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12283 if (checkCallingPermission(android.Manifest.permission.DUMP) 12284 != PackageManager.PERMISSION_GRANTED) { 12285 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12286 + Binder.getCallingPid() 12287 + ", uid=" + Binder.getCallingUid() 12288 + " without permission " 12289 + android.Manifest.permission.DUMP); 12290 return; 12291 } 12292 12293 boolean dumpAll = false; 12294 boolean dumpClient = false; 12295 String dumpPackage = null; 12296 12297 int opti = 0; 12298 while (opti < args.length) { 12299 String opt = args[opti]; 12300 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12301 break; 12302 } 12303 opti++; 12304 if ("-a".equals(opt)) { 12305 dumpAll = true; 12306 } else if ("-c".equals(opt)) { 12307 dumpClient = true; 12308 } else if ("-h".equals(opt)) { 12309 pw.println("Activity manager dump options:"); 12310 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12311 pw.println(" cmd may be one of:"); 12312 pw.println(" a[ctivities]: activity stack state"); 12313 pw.println(" r[recents]: recent activities state"); 12314 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12315 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12316 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12317 pw.println(" o[om]: out of memory management"); 12318 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12319 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12320 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12321 pw.println(" service [COMP_SPEC]: service client-side state"); 12322 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12323 pw.println(" all: dump all activities"); 12324 pw.println(" top: dump the top activity"); 12325 pw.println(" write: write all pending state to storage"); 12326 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12327 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12328 pw.println(" a partial substring in a component name, a"); 12329 pw.println(" hex object identifier."); 12330 pw.println(" -a: include all available server state."); 12331 pw.println(" -c: include client state."); 12332 return; 12333 } else { 12334 pw.println("Unknown argument: " + opt + "; use -h for help"); 12335 } 12336 } 12337 12338 long origId = Binder.clearCallingIdentity(); 12339 boolean more = false; 12340 // Is the caller requesting to dump a particular piece of data? 12341 if (opti < args.length) { 12342 String cmd = args[opti]; 12343 opti++; 12344 if ("activities".equals(cmd) || "a".equals(cmd)) { 12345 synchronized (this) { 12346 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12347 } 12348 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12349 synchronized (this) { 12350 dumpRecentsLocked(fd, pw, args, opti, true, null); 12351 } 12352 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12353 String[] newArgs; 12354 String name; 12355 if (opti >= args.length) { 12356 name = null; 12357 newArgs = EMPTY_STRING_ARRAY; 12358 } else { 12359 name = args[opti]; 12360 opti++; 12361 newArgs = new String[args.length - opti]; 12362 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12363 args.length - opti); 12364 } 12365 synchronized (this) { 12366 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12367 } 12368 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12369 String[] newArgs; 12370 String name; 12371 if (opti >= args.length) { 12372 name = null; 12373 newArgs = EMPTY_STRING_ARRAY; 12374 } else { 12375 name = args[opti]; 12376 opti++; 12377 newArgs = new String[args.length - opti]; 12378 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12379 args.length - opti); 12380 } 12381 synchronized (this) { 12382 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12383 } 12384 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12385 String[] newArgs; 12386 String name; 12387 if (opti >= args.length) { 12388 name = null; 12389 newArgs = EMPTY_STRING_ARRAY; 12390 } else { 12391 name = args[opti]; 12392 opti++; 12393 newArgs = new String[args.length - opti]; 12394 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12395 args.length - opti); 12396 } 12397 synchronized (this) { 12398 dumpProcessesLocked(fd, pw, args, opti, true, name); 12399 } 12400 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12401 synchronized (this) { 12402 dumpOomLocked(fd, pw, args, opti, true); 12403 } 12404 } else if ("provider".equals(cmd)) { 12405 String[] newArgs; 12406 String name; 12407 if (opti >= args.length) { 12408 name = null; 12409 newArgs = EMPTY_STRING_ARRAY; 12410 } else { 12411 name = args[opti]; 12412 opti++; 12413 newArgs = new String[args.length - opti]; 12414 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12415 } 12416 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12417 pw.println("No providers match: " + name); 12418 pw.println("Use -h for help."); 12419 } 12420 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12421 synchronized (this) { 12422 dumpProvidersLocked(fd, pw, args, opti, true, null); 12423 } 12424 } else if ("service".equals(cmd)) { 12425 String[] newArgs; 12426 String name; 12427 if (opti >= args.length) { 12428 name = null; 12429 newArgs = EMPTY_STRING_ARRAY; 12430 } else { 12431 name = args[opti]; 12432 opti++; 12433 newArgs = new String[args.length - opti]; 12434 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12435 args.length - opti); 12436 } 12437 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12438 pw.println("No services match: " + name); 12439 pw.println("Use -h for help."); 12440 } 12441 } else if ("package".equals(cmd)) { 12442 String[] newArgs; 12443 if (opti >= args.length) { 12444 pw.println("package: no package name specified"); 12445 pw.println("Use -h for help."); 12446 } else { 12447 dumpPackage = args[opti]; 12448 opti++; 12449 newArgs = new String[args.length - opti]; 12450 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12451 args.length - opti); 12452 args = newArgs; 12453 opti = 0; 12454 more = true; 12455 } 12456 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12457 synchronized (this) { 12458 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12459 } 12460 } else if ("write".equals(cmd)) { 12461 mTaskPersister.flush(); 12462 pw.println("All tasks persisted."); 12463 return; 12464 } else { 12465 // Dumping a single activity? 12466 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12467 pw.println("Bad activity command, or no activities match: " + cmd); 12468 pw.println("Use -h for help."); 12469 } 12470 } 12471 if (!more) { 12472 Binder.restoreCallingIdentity(origId); 12473 return; 12474 } 12475 } 12476 12477 // No piece of data specified, dump everything. 12478 synchronized (this) { 12479 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12480 pw.println(); 12481 if (dumpAll) { 12482 pw.println("-------------------------------------------------------------------------------"); 12483 } 12484 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12485 pw.println(); 12486 if (dumpAll) { 12487 pw.println("-------------------------------------------------------------------------------"); 12488 } 12489 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12490 pw.println(); 12491 if (dumpAll) { 12492 pw.println("-------------------------------------------------------------------------------"); 12493 } 12494 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12495 pw.println(); 12496 if (dumpAll) { 12497 pw.println("-------------------------------------------------------------------------------"); 12498 } 12499 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12500 pw.println(); 12501 if (dumpAll) { 12502 pw.println("-------------------------------------------------------------------------------"); 12503 } 12504 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12505 pw.println(); 12506 if (dumpAll) { 12507 pw.println("-------------------------------------------------------------------------------"); 12508 } 12509 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12510 } 12511 Binder.restoreCallingIdentity(origId); 12512 } 12513 12514 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12515 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12516 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12517 12518 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12519 dumpPackage); 12520 boolean needSep = printedAnything; 12521 12522 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12523 dumpPackage, needSep, " mFocusedActivity: "); 12524 if (printed) { 12525 printedAnything = true; 12526 needSep = false; 12527 } 12528 12529 if (dumpPackage == null) { 12530 if (needSep) { 12531 pw.println(); 12532 } 12533 needSep = true; 12534 printedAnything = true; 12535 mStackSupervisor.dump(pw, " "); 12536 } 12537 12538 if (!printedAnything) { 12539 pw.println(" (nothing)"); 12540 } 12541 } 12542 12543 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12544 int opti, boolean dumpAll, String dumpPackage) { 12545 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12546 12547 boolean printedAnything = false; 12548 12549 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12550 boolean printedHeader = false; 12551 12552 final int N = mRecentTasks.size(); 12553 for (int i=0; i<N; i++) { 12554 TaskRecord tr = mRecentTasks.get(i); 12555 if (dumpPackage != null) { 12556 if (tr.realActivity == null || 12557 !dumpPackage.equals(tr.realActivity)) { 12558 continue; 12559 } 12560 } 12561 if (!printedHeader) { 12562 pw.println(" Recent tasks:"); 12563 printedHeader = true; 12564 printedAnything = true; 12565 } 12566 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12567 pw.println(tr); 12568 if (dumpAll) { 12569 mRecentTasks.get(i).dump(pw, " "); 12570 } 12571 } 12572 } 12573 12574 if (!printedAnything) { 12575 pw.println(" (nothing)"); 12576 } 12577 } 12578 12579 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12580 int opti, boolean dumpAll, String dumpPackage) { 12581 boolean needSep = false; 12582 boolean printedAnything = false; 12583 int numPers = 0; 12584 12585 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12586 12587 if (dumpAll) { 12588 final int NP = mProcessNames.getMap().size(); 12589 for (int ip=0; ip<NP; ip++) { 12590 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12591 final int NA = procs.size(); 12592 for (int ia=0; ia<NA; ia++) { 12593 ProcessRecord r = procs.valueAt(ia); 12594 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12595 continue; 12596 } 12597 if (!needSep) { 12598 pw.println(" All known processes:"); 12599 needSep = true; 12600 printedAnything = true; 12601 } 12602 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12603 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12604 pw.print(" "); pw.println(r); 12605 r.dump(pw, " "); 12606 if (r.persistent) { 12607 numPers++; 12608 } 12609 } 12610 } 12611 } 12612 12613 if (mIsolatedProcesses.size() > 0) { 12614 boolean printed = false; 12615 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12616 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12617 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12618 continue; 12619 } 12620 if (!printed) { 12621 if (needSep) { 12622 pw.println(); 12623 } 12624 pw.println(" Isolated process list (sorted by uid):"); 12625 printedAnything = true; 12626 printed = true; 12627 needSep = true; 12628 } 12629 pw.println(String.format("%sIsolated #%2d: %s", 12630 " ", i, r.toString())); 12631 } 12632 } 12633 12634 if (mLruProcesses.size() > 0) { 12635 if (needSep) { 12636 pw.println(); 12637 } 12638 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12639 pw.print(" total, non-act at "); 12640 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12641 pw.print(", non-svc at "); 12642 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12643 pw.println("):"); 12644 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12645 needSep = true; 12646 printedAnything = true; 12647 } 12648 12649 if (dumpAll || dumpPackage != null) { 12650 synchronized (mPidsSelfLocked) { 12651 boolean printed = false; 12652 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12653 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12654 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12655 continue; 12656 } 12657 if (!printed) { 12658 if (needSep) pw.println(); 12659 needSep = true; 12660 pw.println(" PID mappings:"); 12661 printed = true; 12662 printedAnything = true; 12663 } 12664 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12665 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12666 } 12667 } 12668 } 12669 12670 if (mForegroundProcesses.size() > 0) { 12671 synchronized (mPidsSelfLocked) { 12672 boolean printed = false; 12673 for (int i=0; i<mForegroundProcesses.size(); i++) { 12674 ProcessRecord r = mPidsSelfLocked.get( 12675 mForegroundProcesses.valueAt(i).pid); 12676 if (dumpPackage != null && (r == null 12677 || !r.pkgList.containsKey(dumpPackage))) { 12678 continue; 12679 } 12680 if (!printed) { 12681 if (needSep) pw.println(); 12682 needSep = true; 12683 pw.println(" Foreground Processes:"); 12684 printed = true; 12685 printedAnything = true; 12686 } 12687 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12688 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12689 } 12690 } 12691 } 12692 12693 if (mPersistentStartingProcesses.size() > 0) { 12694 if (needSep) pw.println(); 12695 needSep = true; 12696 printedAnything = true; 12697 pw.println(" Persisent processes that are starting:"); 12698 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12699 "Starting Norm", "Restarting PERS", dumpPackage); 12700 } 12701 12702 if (mRemovedProcesses.size() > 0) { 12703 if (needSep) pw.println(); 12704 needSep = true; 12705 printedAnything = true; 12706 pw.println(" Processes that are being removed:"); 12707 dumpProcessList(pw, this, mRemovedProcesses, " ", 12708 "Removed Norm", "Removed PERS", dumpPackage); 12709 } 12710 12711 if (mProcessesOnHold.size() > 0) { 12712 if (needSep) pw.println(); 12713 needSep = true; 12714 printedAnything = true; 12715 pw.println(" Processes that are on old until the system is ready:"); 12716 dumpProcessList(pw, this, mProcessesOnHold, " ", 12717 "OnHold Norm", "OnHold PERS", dumpPackage); 12718 } 12719 12720 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12721 12722 if (mProcessCrashTimes.getMap().size() > 0) { 12723 boolean printed = false; 12724 long now = SystemClock.uptimeMillis(); 12725 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12726 final int NP = pmap.size(); 12727 for (int ip=0; ip<NP; ip++) { 12728 String pname = pmap.keyAt(ip); 12729 SparseArray<Long> uids = pmap.valueAt(ip); 12730 final int N = uids.size(); 12731 for (int i=0; i<N; i++) { 12732 int puid = uids.keyAt(i); 12733 ProcessRecord r = mProcessNames.get(pname, puid); 12734 if (dumpPackage != null && (r == null 12735 || !r.pkgList.containsKey(dumpPackage))) { 12736 continue; 12737 } 12738 if (!printed) { 12739 if (needSep) pw.println(); 12740 needSep = true; 12741 pw.println(" Time since processes crashed:"); 12742 printed = true; 12743 printedAnything = true; 12744 } 12745 pw.print(" Process "); pw.print(pname); 12746 pw.print(" uid "); pw.print(puid); 12747 pw.print(": last crashed "); 12748 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12749 pw.println(" ago"); 12750 } 12751 } 12752 } 12753 12754 if (mBadProcesses.getMap().size() > 0) { 12755 boolean printed = false; 12756 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12757 final int NP = pmap.size(); 12758 for (int ip=0; ip<NP; ip++) { 12759 String pname = pmap.keyAt(ip); 12760 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12761 final int N = uids.size(); 12762 for (int i=0; i<N; i++) { 12763 int puid = uids.keyAt(i); 12764 ProcessRecord r = mProcessNames.get(pname, puid); 12765 if (dumpPackage != null && (r == null 12766 || !r.pkgList.containsKey(dumpPackage))) { 12767 continue; 12768 } 12769 if (!printed) { 12770 if (needSep) pw.println(); 12771 needSep = true; 12772 pw.println(" Bad processes:"); 12773 printedAnything = true; 12774 } 12775 BadProcessInfo info = uids.valueAt(i); 12776 pw.print(" Bad process "); pw.print(pname); 12777 pw.print(" uid "); pw.print(puid); 12778 pw.print(": crashed at time "); pw.println(info.time); 12779 if (info.shortMsg != null) { 12780 pw.print(" Short msg: "); pw.println(info.shortMsg); 12781 } 12782 if (info.longMsg != null) { 12783 pw.print(" Long msg: "); pw.println(info.longMsg); 12784 } 12785 if (info.stack != null) { 12786 pw.println(" Stack:"); 12787 int lastPos = 0; 12788 for (int pos=0; pos<info.stack.length(); pos++) { 12789 if (info.stack.charAt(pos) == '\n') { 12790 pw.print(" "); 12791 pw.write(info.stack, lastPos, pos-lastPos); 12792 pw.println(); 12793 lastPos = pos+1; 12794 } 12795 } 12796 if (lastPos < info.stack.length()) { 12797 pw.print(" "); 12798 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12799 pw.println(); 12800 } 12801 } 12802 } 12803 } 12804 } 12805 12806 if (dumpPackage == null) { 12807 pw.println(); 12808 needSep = false; 12809 pw.println(" mStartedUsers:"); 12810 for (int i=0; i<mStartedUsers.size(); i++) { 12811 UserStartedState uss = mStartedUsers.valueAt(i); 12812 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12813 pw.print(": "); uss.dump("", pw); 12814 } 12815 pw.print(" mStartedUserArray: ["); 12816 for (int i=0; i<mStartedUserArray.length; i++) { 12817 if (i > 0) pw.print(", "); 12818 pw.print(mStartedUserArray[i]); 12819 } 12820 pw.println("]"); 12821 pw.print(" mUserLru: ["); 12822 for (int i=0; i<mUserLru.size(); i++) { 12823 if (i > 0) pw.print(", "); 12824 pw.print(mUserLru.get(i)); 12825 } 12826 pw.println("]"); 12827 if (dumpAll) { 12828 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12829 } 12830 synchronized (mUserProfileGroupIdsSelfLocked) { 12831 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12832 pw.println(" mUserProfileGroupIds:"); 12833 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12834 pw.print(" User #"); 12835 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12836 pw.print(" -> profile #"); 12837 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12838 } 12839 } 12840 } 12841 } 12842 if (mHomeProcess != null && (dumpPackage == null 12843 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12844 if (needSep) { 12845 pw.println(); 12846 needSep = false; 12847 } 12848 pw.println(" mHomeProcess: " + mHomeProcess); 12849 } 12850 if (mPreviousProcess != null && (dumpPackage == null 12851 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12852 if (needSep) { 12853 pw.println(); 12854 needSep = false; 12855 } 12856 pw.println(" mPreviousProcess: " + mPreviousProcess); 12857 } 12858 if (dumpAll) { 12859 StringBuilder sb = new StringBuilder(128); 12860 sb.append(" mPreviousProcessVisibleTime: "); 12861 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12862 pw.println(sb); 12863 } 12864 if (mHeavyWeightProcess != null && (dumpPackage == null 12865 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12866 if (needSep) { 12867 pw.println(); 12868 needSep = false; 12869 } 12870 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12871 } 12872 if (dumpPackage == null) { 12873 pw.println(" mConfiguration: " + mConfiguration); 12874 } 12875 if (dumpAll) { 12876 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12877 if (mCompatModePackages.getPackages().size() > 0) { 12878 boolean printed = false; 12879 for (Map.Entry<String, Integer> entry 12880 : mCompatModePackages.getPackages().entrySet()) { 12881 String pkg = entry.getKey(); 12882 int mode = entry.getValue(); 12883 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12884 continue; 12885 } 12886 if (!printed) { 12887 pw.println(" mScreenCompatPackages:"); 12888 printed = true; 12889 } 12890 pw.print(" "); pw.print(pkg); pw.print(": "); 12891 pw.print(mode); pw.println(); 12892 } 12893 } 12894 } 12895 if (dumpPackage == null) { 12896 pw.println(" mWakefulness=" 12897 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12898 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12899 + lockScreenShownToString()); 12900 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12901 } 12902 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12903 || mOrigWaitForDebugger) { 12904 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12905 || dumpPackage.equals(mOrigDebugApp)) { 12906 if (needSep) { 12907 pw.println(); 12908 needSep = false; 12909 } 12910 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12911 + " mDebugTransient=" + mDebugTransient 12912 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12913 } 12914 } 12915 if (mOpenGlTraceApp != null) { 12916 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12917 if (needSep) { 12918 pw.println(); 12919 needSep = false; 12920 } 12921 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12922 } 12923 } 12924 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12925 || mProfileFd != null) { 12926 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12927 if (needSep) { 12928 pw.println(); 12929 needSep = false; 12930 } 12931 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12932 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12933 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12934 + mAutoStopProfiler); 12935 pw.println(" mProfileType=" + mProfileType); 12936 } 12937 } 12938 if (dumpPackage == null) { 12939 if (mAlwaysFinishActivities || mController != null) { 12940 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12941 + " mController=" + mController); 12942 } 12943 if (dumpAll) { 12944 pw.println(" Total persistent processes: " + numPers); 12945 pw.println(" mProcessesReady=" + mProcessesReady 12946 + " mSystemReady=" + mSystemReady 12947 + " mBooted=" + mBooted 12948 + " mFactoryTest=" + mFactoryTest); 12949 pw.println(" mBooting=" + mBooting 12950 + " mCallFinishBooting=" + mCallFinishBooting 12951 + " mBootAnimationComplete=" + mBootAnimationComplete); 12952 pw.print(" mLastPowerCheckRealtime="); 12953 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12954 pw.println(""); 12955 pw.print(" mLastPowerCheckUptime="); 12956 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12957 pw.println(""); 12958 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12959 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12960 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12961 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12962 + " (" + mLruProcesses.size() + " total)" 12963 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12964 + " mNumServiceProcs=" + mNumServiceProcs 12965 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12966 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12967 + " mLastMemoryLevel" + mLastMemoryLevel 12968 + " mLastNumProcesses" + mLastNumProcesses); 12969 long now = SystemClock.uptimeMillis(); 12970 pw.print(" mLastIdleTime="); 12971 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12972 pw.print(" mLowRamSinceLastIdle="); 12973 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12974 pw.println(); 12975 } 12976 } 12977 12978 if (!printedAnything) { 12979 pw.println(" (nothing)"); 12980 } 12981 } 12982 12983 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12984 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12985 if (mProcessesToGc.size() > 0) { 12986 boolean printed = false; 12987 long now = SystemClock.uptimeMillis(); 12988 for (int i=0; i<mProcessesToGc.size(); i++) { 12989 ProcessRecord proc = mProcessesToGc.get(i); 12990 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12991 continue; 12992 } 12993 if (!printed) { 12994 if (needSep) pw.println(); 12995 needSep = true; 12996 pw.println(" Processes that are waiting to GC:"); 12997 printed = true; 12998 } 12999 pw.print(" Process "); pw.println(proc); 13000 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13001 pw.print(", last gced="); 13002 pw.print(now-proc.lastRequestedGc); 13003 pw.print(" ms ago, last lowMem="); 13004 pw.print(now-proc.lastLowMemory); 13005 pw.println(" ms ago"); 13006 13007 } 13008 } 13009 return needSep; 13010 } 13011 13012 void printOomLevel(PrintWriter pw, String name, int adj) { 13013 pw.print(" "); 13014 if (adj >= 0) { 13015 pw.print(' '); 13016 if (adj < 10) pw.print(' '); 13017 } else { 13018 if (adj > -10) pw.print(' '); 13019 } 13020 pw.print(adj); 13021 pw.print(": "); 13022 pw.print(name); 13023 pw.print(" ("); 13024 pw.print(mProcessList.getMemLevel(adj)/1024); 13025 pw.println(" kB)"); 13026 } 13027 13028 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13029 int opti, boolean dumpAll) { 13030 boolean needSep = false; 13031 13032 if (mLruProcesses.size() > 0) { 13033 if (needSep) pw.println(); 13034 needSep = true; 13035 pw.println(" OOM levels:"); 13036 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13037 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13038 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13039 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13040 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13041 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13042 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13043 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13044 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13045 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13046 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13047 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13048 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13049 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13050 13051 if (needSep) pw.println(); 13052 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13053 pw.print(" total, non-act at "); 13054 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13055 pw.print(", non-svc at "); 13056 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13057 pw.println("):"); 13058 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13059 needSep = true; 13060 } 13061 13062 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13063 13064 pw.println(); 13065 pw.println(" mHomeProcess: " + mHomeProcess); 13066 pw.println(" mPreviousProcess: " + mPreviousProcess); 13067 if (mHeavyWeightProcess != null) { 13068 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13069 } 13070 13071 return true; 13072 } 13073 13074 /** 13075 * There are three ways to call this: 13076 * - no provider specified: dump all the providers 13077 * - a flattened component name that matched an existing provider was specified as the 13078 * first arg: dump that one provider 13079 * - the first arg isn't the flattened component name of an existing provider: 13080 * dump all providers whose component contains the first arg as a substring 13081 */ 13082 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13083 int opti, boolean dumpAll) { 13084 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13085 } 13086 13087 static class ItemMatcher { 13088 ArrayList<ComponentName> components; 13089 ArrayList<String> strings; 13090 ArrayList<Integer> objects; 13091 boolean all; 13092 13093 ItemMatcher() { 13094 all = true; 13095 } 13096 13097 void build(String name) { 13098 ComponentName componentName = ComponentName.unflattenFromString(name); 13099 if (componentName != null) { 13100 if (components == null) { 13101 components = new ArrayList<ComponentName>(); 13102 } 13103 components.add(componentName); 13104 all = false; 13105 } else { 13106 int objectId = 0; 13107 // Not a '/' separated full component name; maybe an object ID? 13108 try { 13109 objectId = Integer.parseInt(name, 16); 13110 if (objects == null) { 13111 objects = new ArrayList<Integer>(); 13112 } 13113 objects.add(objectId); 13114 all = false; 13115 } catch (RuntimeException e) { 13116 // Not an integer; just do string match. 13117 if (strings == null) { 13118 strings = new ArrayList<String>(); 13119 } 13120 strings.add(name); 13121 all = false; 13122 } 13123 } 13124 } 13125 13126 int build(String[] args, int opti) { 13127 for (; opti<args.length; opti++) { 13128 String name = args[opti]; 13129 if ("--".equals(name)) { 13130 return opti+1; 13131 } 13132 build(name); 13133 } 13134 return opti; 13135 } 13136 13137 boolean match(Object object, ComponentName comp) { 13138 if (all) { 13139 return true; 13140 } 13141 if (components != null) { 13142 for (int i=0; i<components.size(); i++) { 13143 if (components.get(i).equals(comp)) { 13144 return true; 13145 } 13146 } 13147 } 13148 if (objects != null) { 13149 for (int i=0; i<objects.size(); i++) { 13150 if (System.identityHashCode(object) == objects.get(i)) { 13151 return true; 13152 } 13153 } 13154 } 13155 if (strings != null) { 13156 String flat = comp.flattenToString(); 13157 for (int i=0; i<strings.size(); i++) { 13158 if (flat.contains(strings.get(i))) { 13159 return true; 13160 } 13161 } 13162 } 13163 return false; 13164 } 13165 } 13166 13167 /** 13168 * There are three things that cmd can be: 13169 * - a flattened component name that matches an existing activity 13170 * - the cmd arg isn't the flattened component name of an existing activity: 13171 * dump all activity whose component contains the cmd as a substring 13172 * - A hex number of the ActivityRecord object instance. 13173 */ 13174 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13175 int opti, boolean dumpAll) { 13176 ArrayList<ActivityRecord> activities; 13177 13178 synchronized (this) { 13179 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13180 } 13181 13182 if (activities.size() <= 0) { 13183 return false; 13184 } 13185 13186 String[] newArgs = new String[args.length - opti]; 13187 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13188 13189 TaskRecord lastTask = null; 13190 boolean needSep = false; 13191 for (int i=activities.size()-1; i>=0; i--) { 13192 ActivityRecord r = activities.get(i); 13193 if (needSep) { 13194 pw.println(); 13195 } 13196 needSep = true; 13197 synchronized (this) { 13198 if (lastTask != r.task) { 13199 lastTask = r.task; 13200 pw.print("TASK "); pw.print(lastTask.affinity); 13201 pw.print(" id="); pw.println(lastTask.taskId); 13202 if (dumpAll) { 13203 lastTask.dump(pw, " "); 13204 } 13205 } 13206 } 13207 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13208 } 13209 return true; 13210 } 13211 13212 /** 13213 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13214 * there is a thread associated with the activity. 13215 */ 13216 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13217 final ActivityRecord r, String[] args, boolean dumpAll) { 13218 String innerPrefix = prefix + " "; 13219 synchronized (this) { 13220 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13221 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13222 pw.print(" pid="); 13223 if (r.app != null) pw.println(r.app.pid); 13224 else pw.println("(not running)"); 13225 if (dumpAll) { 13226 r.dump(pw, innerPrefix); 13227 } 13228 } 13229 if (r.app != null && r.app.thread != null) { 13230 // flush anything that is already in the PrintWriter since the thread is going 13231 // to write to the file descriptor directly 13232 pw.flush(); 13233 try { 13234 TransferPipe tp = new TransferPipe(); 13235 try { 13236 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13237 r.appToken, innerPrefix, args); 13238 tp.go(fd); 13239 } finally { 13240 tp.kill(); 13241 } 13242 } catch (IOException e) { 13243 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13244 } catch (RemoteException e) { 13245 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13246 } 13247 } 13248 } 13249 13250 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13251 int opti, boolean dumpAll, String dumpPackage) { 13252 boolean needSep = false; 13253 boolean onlyHistory = false; 13254 boolean printedAnything = false; 13255 13256 if ("history".equals(dumpPackage)) { 13257 if (opti < args.length && "-s".equals(args[opti])) { 13258 dumpAll = false; 13259 } 13260 onlyHistory = true; 13261 dumpPackage = null; 13262 } 13263 13264 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13265 if (!onlyHistory && dumpAll) { 13266 if (mRegisteredReceivers.size() > 0) { 13267 boolean printed = false; 13268 Iterator it = mRegisteredReceivers.values().iterator(); 13269 while (it.hasNext()) { 13270 ReceiverList r = (ReceiverList)it.next(); 13271 if (dumpPackage != null && (r.app == null || 13272 !dumpPackage.equals(r.app.info.packageName))) { 13273 continue; 13274 } 13275 if (!printed) { 13276 pw.println(" Registered Receivers:"); 13277 needSep = true; 13278 printed = true; 13279 printedAnything = true; 13280 } 13281 pw.print(" * "); pw.println(r); 13282 r.dump(pw, " "); 13283 } 13284 } 13285 13286 if (mReceiverResolver.dump(pw, needSep ? 13287 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13288 " ", dumpPackage, false, false)) { 13289 needSep = true; 13290 printedAnything = true; 13291 } 13292 } 13293 13294 for (BroadcastQueue q : mBroadcastQueues) { 13295 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13296 printedAnything |= needSep; 13297 } 13298 13299 needSep = true; 13300 13301 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13302 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13303 if (needSep) { 13304 pw.println(); 13305 } 13306 needSep = true; 13307 printedAnything = true; 13308 pw.print(" Sticky broadcasts for user "); 13309 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13310 StringBuilder sb = new StringBuilder(128); 13311 for (Map.Entry<String, ArrayList<Intent>> ent 13312 : mStickyBroadcasts.valueAt(user).entrySet()) { 13313 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13314 if (dumpAll) { 13315 pw.println(":"); 13316 ArrayList<Intent> intents = ent.getValue(); 13317 final int N = intents.size(); 13318 for (int i=0; i<N; i++) { 13319 sb.setLength(0); 13320 sb.append(" Intent: "); 13321 intents.get(i).toShortString(sb, false, true, false, false); 13322 pw.println(sb.toString()); 13323 Bundle bundle = intents.get(i).getExtras(); 13324 if (bundle != null) { 13325 pw.print(" "); 13326 pw.println(bundle.toString()); 13327 } 13328 } 13329 } else { 13330 pw.println(""); 13331 } 13332 } 13333 } 13334 } 13335 13336 if (!onlyHistory && dumpAll) { 13337 pw.println(); 13338 for (BroadcastQueue queue : mBroadcastQueues) { 13339 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13340 + queue.mBroadcastsScheduled); 13341 } 13342 pw.println(" mHandler:"); 13343 mHandler.dump(new PrintWriterPrinter(pw), " "); 13344 needSep = true; 13345 printedAnything = true; 13346 } 13347 13348 if (!printedAnything) { 13349 pw.println(" (nothing)"); 13350 } 13351 } 13352 13353 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13354 int opti, boolean dumpAll, String dumpPackage) { 13355 boolean needSep; 13356 boolean printedAnything = false; 13357 13358 ItemMatcher matcher = new ItemMatcher(); 13359 matcher.build(args, opti); 13360 13361 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13362 13363 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13364 printedAnything |= needSep; 13365 13366 if (mLaunchingProviders.size() > 0) { 13367 boolean printed = false; 13368 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13369 ContentProviderRecord r = mLaunchingProviders.get(i); 13370 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13371 continue; 13372 } 13373 if (!printed) { 13374 if (needSep) pw.println(); 13375 needSep = true; 13376 pw.println(" Launching content providers:"); 13377 printed = true; 13378 printedAnything = true; 13379 } 13380 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13381 pw.println(r); 13382 } 13383 } 13384 13385 if (mGrantedUriPermissions.size() > 0) { 13386 boolean printed = false; 13387 int dumpUid = -2; 13388 if (dumpPackage != null) { 13389 try { 13390 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13391 } catch (NameNotFoundException e) { 13392 dumpUid = -1; 13393 } 13394 } 13395 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13396 int uid = mGrantedUriPermissions.keyAt(i); 13397 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13398 continue; 13399 } 13400 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13401 if (!printed) { 13402 if (needSep) pw.println(); 13403 needSep = true; 13404 pw.println(" Granted Uri Permissions:"); 13405 printed = true; 13406 printedAnything = true; 13407 } 13408 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13409 for (UriPermission perm : perms.values()) { 13410 pw.print(" "); pw.println(perm); 13411 if (dumpAll) { 13412 perm.dump(pw, " "); 13413 } 13414 } 13415 } 13416 } 13417 13418 if (!printedAnything) { 13419 pw.println(" (nothing)"); 13420 } 13421 } 13422 13423 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13424 int opti, boolean dumpAll, String dumpPackage) { 13425 boolean printed = false; 13426 13427 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13428 13429 if (mIntentSenderRecords.size() > 0) { 13430 Iterator<WeakReference<PendingIntentRecord>> it 13431 = mIntentSenderRecords.values().iterator(); 13432 while (it.hasNext()) { 13433 WeakReference<PendingIntentRecord> ref = it.next(); 13434 PendingIntentRecord rec = ref != null ? ref.get(): null; 13435 if (dumpPackage != null && (rec == null 13436 || !dumpPackage.equals(rec.key.packageName))) { 13437 continue; 13438 } 13439 printed = true; 13440 if (rec != null) { 13441 pw.print(" * "); pw.println(rec); 13442 if (dumpAll) { 13443 rec.dump(pw, " "); 13444 } 13445 } else { 13446 pw.print(" * "); pw.println(ref); 13447 } 13448 } 13449 } 13450 13451 if (!printed) { 13452 pw.println(" (nothing)"); 13453 } 13454 } 13455 13456 private static final int dumpProcessList(PrintWriter pw, 13457 ActivityManagerService service, List list, 13458 String prefix, String normalLabel, String persistentLabel, 13459 String dumpPackage) { 13460 int numPers = 0; 13461 final int N = list.size()-1; 13462 for (int i=N; i>=0; i--) { 13463 ProcessRecord r = (ProcessRecord)list.get(i); 13464 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13465 continue; 13466 } 13467 pw.println(String.format("%s%s #%2d: %s", 13468 prefix, (r.persistent ? persistentLabel : normalLabel), 13469 i, r.toString())); 13470 if (r.persistent) { 13471 numPers++; 13472 } 13473 } 13474 return numPers; 13475 } 13476 13477 private static final boolean dumpProcessOomList(PrintWriter pw, 13478 ActivityManagerService service, List<ProcessRecord> origList, 13479 String prefix, String normalLabel, String persistentLabel, 13480 boolean inclDetails, String dumpPackage) { 13481 13482 ArrayList<Pair<ProcessRecord, Integer>> list 13483 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13484 for (int i=0; i<origList.size(); i++) { 13485 ProcessRecord r = origList.get(i); 13486 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13487 continue; 13488 } 13489 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13490 } 13491 13492 if (list.size() <= 0) { 13493 return false; 13494 } 13495 13496 Comparator<Pair<ProcessRecord, Integer>> comparator 13497 = new Comparator<Pair<ProcessRecord, Integer>>() { 13498 @Override 13499 public int compare(Pair<ProcessRecord, Integer> object1, 13500 Pair<ProcessRecord, Integer> object2) { 13501 if (object1.first.setAdj != object2.first.setAdj) { 13502 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13503 } 13504 if (object1.second.intValue() != object2.second.intValue()) { 13505 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13506 } 13507 return 0; 13508 } 13509 }; 13510 13511 Collections.sort(list, comparator); 13512 13513 final long curRealtime = SystemClock.elapsedRealtime(); 13514 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13515 final long curUptime = SystemClock.uptimeMillis(); 13516 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13517 13518 for (int i=list.size()-1; i>=0; i--) { 13519 ProcessRecord r = list.get(i).first; 13520 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13521 char schedGroup; 13522 switch (r.setSchedGroup) { 13523 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13524 schedGroup = 'B'; 13525 break; 13526 case Process.THREAD_GROUP_DEFAULT: 13527 schedGroup = 'F'; 13528 break; 13529 default: 13530 schedGroup = '?'; 13531 break; 13532 } 13533 char foreground; 13534 if (r.foregroundActivities) { 13535 foreground = 'A'; 13536 } else if (r.foregroundServices) { 13537 foreground = 'S'; 13538 } else { 13539 foreground = ' '; 13540 } 13541 String procState = ProcessList.makeProcStateString(r.curProcState); 13542 pw.print(prefix); 13543 pw.print(r.persistent ? persistentLabel : normalLabel); 13544 pw.print(" #"); 13545 int num = (origList.size()-1)-list.get(i).second; 13546 if (num < 10) pw.print(' '); 13547 pw.print(num); 13548 pw.print(": "); 13549 pw.print(oomAdj); 13550 pw.print(' '); 13551 pw.print(schedGroup); 13552 pw.print('/'); 13553 pw.print(foreground); 13554 pw.print('/'); 13555 pw.print(procState); 13556 pw.print(" trm:"); 13557 if (r.trimMemoryLevel < 10) pw.print(' '); 13558 pw.print(r.trimMemoryLevel); 13559 pw.print(' '); 13560 pw.print(r.toShortString()); 13561 pw.print(" ("); 13562 pw.print(r.adjType); 13563 pw.println(')'); 13564 if (r.adjSource != null || r.adjTarget != null) { 13565 pw.print(prefix); 13566 pw.print(" "); 13567 if (r.adjTarget instanceof ComponentName) { 13568 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13569 } else if (r.adjTarget != null) { 13570 pw.print(r.adjTarget.toString()); 13571 } else { 13572 pw.print("{null}"); 13573 } 13574 pw.print("<="); 13575 if (r.adjSource instanceof ProcessRecord) { 13576 pw.print("Proc{"); 13577 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13578 pw.println("}"); 13579 } else if (r.adjSource != null) { 13580 pw.println(r.adjSource.toString()); 13581 } else { 13582 pw.println("{null}"); 13583 } 13584 } 13585 if (inclDetails) { 13586 pw.print(prefix); 13587 pw.print(" "); 13588 pw.print("oom: max="); pw.print(r.maxAdj); 13589 pw.print(" curRaw="); pw.print(r.curRawAdj); 13590 pw.print(" setRaw="); pw.print(r.setRawAdj); 13591 pw.print(" cur="); pw.print(r.curAdj); 13592 pw.print(" set="); pw.println(r.setAdj); 13593 pw.print(prefix); 13594 pw.print(" "); 13595 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13596 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13597 pw.print(" lastPss="); pw.print(r.lastPss); 13598 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13599 pw.print(prefix); 13600 pw.print(" "); 13601 pw.print("cached="); pw.print(r.cached); 13602 pw.print(" empty="); pw.print(r.empty); 13603 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13604 13605 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13606 if (r.lastWakeTime != 0) { 13607 long wtime; 13608 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13609 synchronized (stats) { 13610 wtime = stats.getProcessWakeTime(r.info.uid, 13611 r.pid, curRealtime); 13612 } 13613 long timeUsed = wtime - r.lastWakeTime; 13614 pw.print(prefix); 13615 pw.print(" "); 13616 pw.print("keep awake over "); 13617 TimeUtils.formatDuration(realtimeSince, pw); 13618 pw.print(" used "); 13619 TimeUtils.formatDuration(timeUsed, pw); 13620 pw.print(" ("); 13621 pw.print((timeUsed*100)/realtimeSince); 13622 pw.println("%)"); 13623 } 13624 if (r.lastCpuTime != 0) { 13625 long timeUsed = r.curCpuTime - r.lastCpuTime; 13626 pw.print(prefix); 13627 pw.print(" "); 13628 pw.print("run cpu over "); 13629 TimeUtils.formatDuration(uptimeSince, pw); 13630 pw.print(" used "); 13631 TimeUtils.formatDuration(timeUsed, pw); 13632 pw.print(" ("); 13633 pw.print((timeUsed*100)/uptimeSince); 13634 pw.println("%)"); 13635 } 13636 } 13637 } 13638 } 13639 return true; 13640 } 13641 13642 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13643 String[] args) { 13644 ArrayList<ProcessRecord> procs; 13645 synchronized (this) { 13646 if (args != null && args.length > start 13647 && args[start].charAt(0) != '-') { 13648 procs = new ArrayList<ProcessRecord>(); 13649 int pid = -1; 13650 try { 13651 pid = Integer.parseInt(args[start]); 13652 } catch (NumberFormatException e) { 13653 } 13654 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13655 ProcessRecord proc = mLruProcesses.get(i); 13656 if (proc.pid == pid) { 13657 procs.add(proc); 13658 } else if (allPkgs && proc.pkgList != null 13659 && proc.pkgList.containsKey(args[start])) { 13660 procs.add(proc); 13661 } else if (proc.processName.equals(args[start])) { 13662 procs.add(proc); 13663 } 13664 } 13665 if (procs.size() <= 0) { 13666 return null; 13667 } 13668 } else { 13669 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13670 } 13671 } 13672 return procs; 13673 } 13674 13675 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13676 PrintWriter pw, String[] args) { 13677 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13678 if (procs == null) { 13679 pw.println("No process found for: " + args[0]); 13680 return; 13681 } 13682 13683 long uptime = SystemClock.uptimeMillis(); 13684 long realtime = SystemClock.elapsedRealtime(); 13685 pw.println("Applications Graphics Acceleration Info:"); 13686 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13687 13688 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13689 ProcessRecord r = procs.get(i); 13690 if (r.thread != null) { 13691 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13692 pw.flush(); 13693 try { 13694 TransferPipe tp = new TransferPipe(); 13695 try { 13696 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13697 tp.go(fd); 13698 } finally { 13699 tp.kill(); 13700 } 13701 } catch (IOException e) { 13702 pw.println("Failure while dumping the app: " + r); 13703 pw.flush(); 13704 } catch (RemoteException e) { 13705 pw.println("Got a RemoteException while dumping the app " + r); 13706 pw.flush(); 13707 } 13708 } 13709 } 13710 } 13711 13712 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13713 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13714 if (procs == null) { 13715 pw.println("No process found for: " + args[0]); 13716 return; 13717 } 13718 13719 pw.println("Applications Database Info:"); 13720 13721 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13722 ProcessRecord r = procs.get(i); 13723 if (r.thread != null) { 13724 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13725 pw.flush(); 13726 try { 13727 TransferPipe tp = new TransferPipe(); 13728 try { 13729 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13730 tp.go(fd); 13731 } finally { 13732 tp.kill(); 13733 } 13734 } catch (IOException e) { 13735 pw.println("Failure while dumping the app: " + r); 13736 pw.flush(); 13737 } catch (RemoteException e) { 13738 pw.println("Got a RemoteException while dumping the app " + r); 13739 pw.flush(); 13740 } 13741 } 13742 } 13743 } 13744 13745 final static class MemItem { 13746 final boolean isProc; 13747 final String label; 13748 final String shortLabel; 13749 final long pss; 13750 final int id; 13751 final boolean hasActivities; 13752 ArrayList<MemItem> subitems; 13753 13754 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13755 boolean _hasActivities) { 13756 isProc = true; 13757 label = _label; 13758 shortLabel = _shortLabel; 13759 pss = _pss; 13760 id = _id; 13761 hasActivities = _hasActivities; 13762 } 13763 13764 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13765 isProc = false; 13766 label = _label; 13767 shortLabel = _shortLabel; 13768 pss = _pss; 13769 id = _id; 13770 hasActivities = false; 13771 } 13772 } 13773 13774 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13775 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13776 if (sort && !isCompact) { 13777 Collections.sort(items, new Comparator<MemItem>() { 13778 @Override 13779 public int compare(MemItem lhs, MemItem rhs) { 13780 if (lhs.pss < rhs.pss) { 13781 return 1; 13782 } else if (lhs.pss > rhs.pss) { 13783 return -1; 13784 } 13785 return 0; 13786 } 13787 }); 13788 } 13789 13790 for (int i=0; i<items.size(); i++) { 13791 MemItem mi = items.get(i); 13792 if (!isCompact) { 13793 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13794 } else if (mi.isProc) { 13795 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13796 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13797 pw.println(mi.hasActivities ? ",a" : ",e"); 13798 } else { 13799 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13800 pw.println(mi.pss); 13801 } 13802 if (mi.subitems != null) { 13803 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13804 true, isCompact); 13805 } 13806 } 13807 } 13808 13809 // These are in KB. 13810 static final long[] DUMP_MEM_BUCKETS = new long[] { 13811 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13812 120*1024, 160*1024, 200*1024, 13813 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13814 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13815 }; 13816 13817 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13818 boolean stackLike) { 13819 int start = label.lastIndexOf('.'); 13820 if (start >= 0) start++; 13821 else start = 0; 13822 int end = label.length(); 13823 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13824 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13825 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13826 out.append(bucket); 13827 out.append(stackLike ? "MB." : "MB "); 13828 out.append(label, start, end); 13829 return; 13830 } 13831 } 13832 out.append(memKB/1024); 13833 out.append(stackLike ? "MB." : "MB "); 13834 out.append(label, start, end); 13835 } 13836 13837 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13838 ProcessList.NATIVE_ADJ, 13839 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13840 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13841 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13842 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13843 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13844 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13845 }; 13846 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13847 "Native", 13848 "System", "Persistent", "Persistent Service", "Foreground", 13849 "Visible", "Perceptible", 13850 "Heavy Weight", "Backup", 13851 "A Services", "Home", 13852 "Previous", "B Services", "Cached" 13853 }; 13854 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13855 "native", 13856 "sys", "pers", "persvc", "fore", 13857 "vis", "percept", 13858 "heavy", "backup", 13859 "servicea", "home", 13860 "prev", "serviceb", "cached" 13861 }; 13862 13863 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13864 long realtime, boolean isCheckinRequest, boolean isCompact) { 13865 if (isCheckinRequest || isCompact) { 13866 // short checkin version 13867 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13868 } else { 13869 pw.println("Applications Memory Usage (kB):"); 13870 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13871 } 13872 } 13873 13874 private static final int KSM_SHARED = 0; 13875 private static final int KSM_SHARING = 1; 13876 private static final int KSM_UNSHARED = 2; 13877 private static final int KSM_VOLATILE = 3; 13878 13879 private final long[] getKsmInfo() { 13880 long[] longOut = new long[4]; 13881 final int[] SINGLE_LONG_FORMAT = new int[] { 13882 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13883 }; 13884 long[] longTmp = new long[1]; 13885 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13886 SINGLE_LONG_FORMAT, null, longTmp, null); 13887 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13888 longTmp[0] = 0; 13889 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13890 SINGLE_LONG_FORMAT, null, longTmp, null); 13891 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13892 longTmp[0] = 0; 13893 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13894 SINGLE_LONG_FORMAT, null, longTmp, null); 13895 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13896 longTmp[0] = 0; 13897 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13898 SINGLE_LONG_FORMAT, null, longTmp, null); 13899 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13900 return longOut; 13901 } 13902 13903 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13904 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13905 boolean dumpDetails = false; 13906 boolean dumpFullDetails = false; 13907 boolean dumpDalvik = false; 13908 boolean oomOnly = false; 13909 boolean isCompact = false; 13910 boolean localOnly = false; 13911 boolean packages = false; 13912 13913 int opti = 0; 13914 while (opti < args.length) { 13915 String opt = args[opti]; 13916 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13917 break; 13918 } 13919 opti++; 13920 if ("-a".equals(opt)) { 13921 dumpDetails = true; 13922 dumpFullDetails = true; 13923 dumpDalvik = true; 13924 } else if ("-d".equals(opt)) { 13925 dumpDalvik = true; 13926 } else if ("-c".equals(opt)) { 13927 isCompact = true; 13928 } else if ("--oom".equals(opt)) { 13929 oomOnly = true; 13930 } else if ("--local".equals(opt)) { 13931 localOnly = true; 13932 } else if ("--package".equals(opt)) { 13933 packages = true; 13934 } else if ("-h".equals(opt)) { 13935 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13936 pw.println(" -a: include all available information for each process."); 13937 pw.println(" -d: include dalvik details when dumping process details."); 13938 pw.println(" -c: dump in a compact machine-parseable representation."); 13939 pw.println(" --oom: only show processes organized by oom adj."); 13940 pw.println(" --local: only collect details locally, don't call process."); 13941 pw.println(" --package: interpret process arg as package, dumping all"); 13942 pw.println(" processes that have loaded that package."); 13943 pw.println("If [process] is specified it can be the name or "); 13944 pw.println("pid of a specific process to dump."); 13945 return; 13946 } else { 13947 pw.println("Unknown argument: " + opt + "; use -h for help"); 13948 } 13949 } 13950 13951 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13952 long uptime = SystemClock.uptimeMillis(); 13953 long realtime = SystemClock.elapsedRealtime(); 13954 final long[] tmpLong = new long[1]; 13955 13956 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13957 if (procs == null) { 13958 // No Java processes. Maybe they want to print a native process. 13959 if (args != null && args.length > opti 13960 && args[opti].charAt(0) != '-') { 13961 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13962 = new ArrayList<ProcessCpuTracker.Stats>(); 13963 updateCpuStatsNow(); 13964 int findPid = -1; 13965 try { 13966 findPid = Integer.parseInt(args[opti]); 13967 } catch (NumberFormatException e) { 13968 } 13969 synchronized (mProcessCpuTracker) { 13970 final int N = mProcessCpuTracker.countStats(); 13971 for (int i=0; i<N; i++) { 13972 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13973 if (st.pid == findPid || (st.baseName != null 13974 && st.baseName.equals(args[opti]))) { 13975 nativeProcs.add(st); 13976 } 13977 } 13978 } 13979 if (nativeProcs.size() > 0) { 13980 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13981 isCompact); 13982 Debug.MemoryInfo mi = null; 13983 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13984 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13985 final int pid = r.pid; 13986 if (!isCheckinRequest && dumpDetails) { 13987 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13988 } 13989 if (mi == null) { 13990 mi = new Debug.MemoryInfo(); 13991 } 13992 if (dumpDetails || (!brief && !oomOnly)) { 13993 Debug.getMemoryInfo(pid, mi); 13994 } else { 13995 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13996 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13997 } 13998 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13999 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14000 if (isCheckinRequest) { 14001 pw.println(); 14002 } 14003 } 14004 return; 14005 } 14006 } 14007 pw.println("No process found for: " + args[opti]); 14008 return; 14009 } 14010 14011 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14012 dumpDetails = true; 14013 } 14014 14015 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14016 14017 String[] innerArgs = new String[args.length-opti]; 14018 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14019 14020 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14021 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14022 long nativePss = 0; 14023 long dalvikPss = 0; 14024 long otherPss = 0; 14025 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14026 14027 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14028 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14029 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14030 14031 long totalPss = 0; 14032 long cachedPss = 0; 14033 14034 Debug.MemoryInfo mi = null; 14035 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14036 final ProcessRecord r = procs.get(i); 14037 final IApplicationThread thread; 14038 final int pid; 14039 final int oomAdj; 14040 final boolean hasActivities; 14041 synchronized (this) { 14042 thread = r.thread; 14043 pid = r.pid; 14044 oomAdj = r.getSetAdjWithServices(); 14045 hasActivities = r.activities.size() > 0; 14046 } 14047 if (thread != null) { 14048 if (!isCheckinRequest && dumpDetails) { 14049 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14050 } 14051 if (mi == null) { 14052 mi = new Debug.MemoryInfo(); 14053 } 14054 if (dumpDetails || (!brief && !oomOnly)) { 14055 Debug.getMemoryInfo(pid, mi); 14056 } else { 14057 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14058 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14059 } 14060 if (dumpDetails) { 14061 if (localOnly) { 14062 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14063 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14064 if (isCheckinRequest) { 14065 pw.println(); 14066 } 14067 } else { 14068 try { 14069 pw.flush(); 14070 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14071 dumpDalvik, innerArgs); 14072 } catch (RemoteException e) { 14073 if (!isCheckinRequest) { 14074 pw.println("Got RemoteException!"); 14075 pw.flush(); 14076 } 14077 } 14078 } 14079 } 14080 14081 final long myTotalPss = mi.getTotalPss(); 14082 final long myTotalUss = mi.getTotalUss(); 14083 14084 synchronized (this) { 14085 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14086 // Record this for posterity if the process has been stable. 14087 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14088 } 14089 } 14090 14091 if (!isCheckinRequest && mi != null) { 14092 totalPss += myTotalPss; 14093 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14094 (hasActivities ? " / activities)" : ")"), 14095 r.processName, myTotalPss, pid, hasActivities); 14096 procMems.add(pssItem); 14097 procMemsMap.put(pid, pssItem); 14098 14099 nativePss += mi.nativePss; 14100 dalvikPss += mi.dalvikPss; 14101 otherPss += mi.otherPss; 14102 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14103 long mem = mi.getOtherPss(j); 14104 miscPss[j] += mem; 14105 otherPss -= mem; 14106 } 14107 14108 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14109 cachedPss += myTotalPss; 14110 } 14111 14112 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14113 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14114 || oomIndex == (oomPss.length-1)) { 14115 oomPss[oomIndex] += myTotalPss; 14116 if (oomProcs[oomIndex] == null) { 14117 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14118 } 14119 oomProcs[oomIndex].add(pssItem); 14120 break; 14121 } 14122 } 14123 } 14124 } 14125 } 14126 14127 long nativeProcTotalPss = 0; 14128 14129 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14130 // If we are showing aggregations, also look for native processes to 14131 // include so that our aggregations are more accurate. 14132 updateCpuStatsNow(); 14133 synchronized (mProcessCpuTracker) { 14134 final int N = mProcessCpuTracker.countStats(); 14135 for (int i=0; i<N; i++) { 14136 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14137 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14138 if (mi == null) { 14139 mi = new Debug.MemoryInfo(); 14140 } 14141 if (!brief && !oomOnly) { 14142 Debug.getMemoryInfo(st.pid, mi); 14143 } else { 14144 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14145 mi.nativePrivateDirty = (int)tmpLong[0]; 14146 } 14147 14148 final long myTotalPss = mi.getTotalPss(); 14149 totalPss += myTotalPss; 14150 nativeProcTotalPss += myTotalPss; 14151 14152 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14153 st.name, myTotalPss, st.pid, false); 14154 procMems.add(pssItem); 14155 14156 nativePss += mi.nativePss; 14157 dalvikPss += mi.dalvikPss; 14158 otherPss += mi.otherPss; 14159 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14160 long mem = mi.getOtherPss(j); 14161 miscPss[j] += mem; 14162 otherPss -= mem; 14163 } 14164 oomPss[0] += myTotalPss; 14165 if (oomProcs[0] == null) { 14166 oomProcs[0] = new ArrayList<MemItem>(); 14167 } 14168 oomProcs[0].add(pssItem); 14169 } 14170 } 14171 } 14172 14173 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14174 14175 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14176 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14177 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14178 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14179 String label = Debug.MemoryInfo.getOtherLabel(j); 14180 catMems.add(new MemItem(label, label, miscPss[j], j)); 14181 } 14182 14183 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14184 for (int j=0; j<oomPss.length; j++) { 14185 if (oomPss[j] != 0) { 14186 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14187 : DUMP_MEM_OOM_LABEL[j]; 14188 MemItem item = new MemItem(label, label, oomPss[j], 14189 DUMP_MEM_OOM_ADJ[j]); 14190 item.subitems = oomProcs[j]; 14191 oomMems.add(item); 14192 } 14193 } 14194 14195 if (!brief && !oomOnly && !isCompact) { 14196 pw.println(); 14197 pw.println("Total PSS by process:"); 14198 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14199 pw.println(); 14200 } 14201 if (!isCompact) { 14202 pw.println("Total PSS by OOM adjustment:"); 14203 } 14204 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14205 if (!brief && !oomOnly) { 14206 PrintWriter out = categoryPw != null ? categoryPw : pw; 14207 if (!isCompact) { 14208 out.println(); 14209 out.println("Total PSS by category:"); 14210 } 14211 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14212 } 14213 if (!isCompact) { 14214 pw.println(); 14215 } 14216 MemInfoReader memInfo = new MemInfoReader(); 14217 memInfo.readMemInfo(); 14218 if (nativeProcTotalPss > 0) { 14219 synchronized (this) { 14220 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14221 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14222 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14223 } 14224 } 14225 if (!brief) { 14226 if (!isCompact) { 14227 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14228 pw.print(" kB (status "); 14229 switch (mLastMemoryLevel) { 14230 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14231 pw.println("normal)"); 14232 break; 14233 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14234 pw.println("moderate)"); 14235 break; 14236 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14237 pw.println("low)"); 14238 break; 14239 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14240 pw.println("critical)"); 14241 break; 14242 default: 14243 pw.print(mLastMemoryLevel); 14244 pw.println(")"); 14245 break; 14246 } 14247 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14248 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14249 pw.print(cachedPss); pw.print(" cached pss + "); 14250 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14251 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14252 } else { 14253 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14254 pw.print(cachedPss + memInfo.getCachedSizeKb() 14255 + memInfo.getFreeSizeKb()); pw.print(","); 14256 pw.println(totalPss - cachedPss); 14257 } 14258 } 14259 if (!isCompact) { 14260 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14261 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14262 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14263 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14264 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14265 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14266 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14267 } 14268 if (!brief) { 14269 if (memInfo.getZramTotalSizeKb() != 0) { 14270 if (!isCompact) { 14271 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14272 pw.print(" kB physical used for "); 14273 pw.print(memInfo.getSwapTotalSizeKb() 14274 - memInfo.getSwapFreeSizeKb()); 14275 pw.print(" kB in swap ("); 14276 pw.print(memInfo.getSwapTotalSizeKb()); 14277 pw.println(" kB total swap)"); 14278 } else { 14279 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14280 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14281 pw.println(memInfo.getSwapFreeSizeKb()); 14282 } 14283 } 14284 final long[] ksm = getKsmInfo(); 14285 if (!isCompact) { 14286 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14287 || ksm[KSM_VOLATILE] != 0) { 14288 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14289 pw.print(" kB saved from shared "); 14290 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14291 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14292 pw.print(" kB unshared; "); 14293 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14294 } 14295 pw.print(" Tuning: "); 14296 pw.print(ActivityManager.staticGetMemoryClass()); 14297 pw.print(" (large "); 14298 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14299 pw.print("), oom "); 14300 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14301 pw.print(" kB"); 14302 pw.print(", restore limit "); 14303 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14304 pw.print(" kB"); 14305 if (ActivityManager.isLowRamDeviceStatic()) { 14306 pw.print(" (low-ram)"); 14307 } 14308 if (ActivityManager.isHighEndGfx()) { 14309 pw.print(" (high-end-gfx)"); 14310 } 14311 pw.println(); 14312 } else { 14313 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14314 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14315 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14316 pw.print("tuning,"); 14317 pw.print(ActivityManager.staticGetMemoryClass()); 14318 pw.print(','); 14319 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14320 pw.print(','); 14321 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14322 if (ActivityManager.isLowRamDeviceStatic()) { 14323 pw.print(",low-ram"); 14324 } 14325 if (ActivityManager.isHighEndGfx()) { 14326 pw.print(",high-end-gfx"); 14327 } 14328 pw.println(); 14329 } 14330 } 14331 } 14332 } 14333 14334 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14335 String name) { 14336 sb.append(" "); 14337 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14338 sb.append(' '); 14339 sb.append(ProcessList.makeProcStateString(procState)); 14340 sb.append(' '); 14341 ProcessList.appendRamKb(sb, pss); 14342 sb.append(" kB: "); 14343 sb.append(name); 14344 } 14345 14346 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14347 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14348 sb.append(" ("); 14349 sb.append(mi.pid); 14350 sb.append(") "); 14351 sb.append(mi.adjType); 14352 sb.append('\n'); 14353 if (mi.adjReason != null) { 14354 sb.append(" "); 14355 sb.append(mi.adjReason); 14356 sb.append('\n'); 14357 } 14358 } 14359 14360 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14361 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14362 for (int i=0, N=memInfos.size(); i<N; i++) { 14363 ProcessMemInfo mi = memInfos.get(i); 14364 infoMap.put(mi.pid, mi); 14365 } 14366 updateCpuStatsNow(); 14367 synchronized (mProcessCpuTracker) { 14368 final int N = mProcessCpuTracker.countStats(); 14369 for (int i=0; i<N; i++) { 14370 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14371 if (st.vsize > 0) { 14372 long pss = Debug.getPss(st.pid, null); 14373 if (pss > 0) { 14374 if (infoMap.indexOfKey(st.pid) < 0) { 14375 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14376 ProcessList.NATIVE_ADJ, -1, "native", null); 14377 mi.pss = pss; 14378 memInfos.add(mi); 14379 } 14380 } 14381 } 14382 } 14383 } 14384 14385 long totalPss = 0; 14386 for (int i=0, N=memInfos.size(); i<N; i++) { 14387 ProcessMemInfo mi = memInfos.get(i); 14388 if (mi.pss == 0) { 14389 mi.pss = Debug.getPss(mi.pid, null); 14390 } 14391 totalPss += mi.pss; 14392 } 14393 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14394 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14395 if (lhs.oomAdj != rhs.oomAdj) { 14396 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14397 } 14398 if (lhs.pss != rhs.pss) { 14399 return lhs.pss < rhs.pss ? 1 : -1; 14400 } 14401 return 0; 14402 } 14403 }); 14404 14405 StringBuilder tag = new StringBuilder(128); 14406 StringBuilder stack = new StringBuilder(128); 14407 tag.append("Low on memory -- "); 14408 appendMemBucket(tag, totalPss, "total", false); 14409 appendMemBucket(stack, totalPss, "total", true); 14410 14411 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14412 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14413 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14414 14415 boolean firstLine = true; 14416 int lastOomAdj = Integer.MIN_VALUE; 14417 long extraNativeRam = 0; 14418 long cachedPss = 0; 14419 for (int i=0, N=memInfos.size(); i<N; i++) { 14420 ProcessMemInfo mi = memInfos.get(i); 14421 14422 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14423 cachedPss += mi.pss; 14424 } 14425 14426 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14427 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14428 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14429 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14430 if (lastOomAdj != mi.oomAdj) { 14431 lastOomAdj = mi.oomAdj; 14432 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14433 tag.append(" / "); 14434 } 14435 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14436 if (firstLine) { 14437 stack.append(":"); 14438 firstLine = false; 14439 } 14440 stack.append("\n\t at "); 14441 } else { 14442 stack.append("$"); 14443 } 14444 } else { 14445 tag.append(" "); 14446 stack.append("$"); 14447 } 14448 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14449 appendMemBucket(tag, mi.pss, mi.name, false); 14450 } 14451 appendMemBucket(stack, mi.pss, mi.name, true); 14452 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14453 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14454 stack.append("("); 14455 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14456 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14457 stack.append(DUMP_MEM_OOM_LABEL[k]); 14458 stack.append(":"); 14459 stack.append(DUMP_MEM_OOM_ADJ[k]); 14460 } 14461 } 14462 stack.append(")"); 14463 } 14464 } 14465 14466 appendMemInfo(fullNativeBuilder, mi); 14467 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14468 // The short form only has native processes that are >= 1MB. 14469 if (mi.pss >= 1000) { 14470 appendMemInfo(shortNativeBuilder, mi); 14471 } else { 14472 extraNativeRam += mi.pss; 14473 } 14474 } else { 14475 // Short form has all other details, but if we have collected RAM 14476 // from smaller native processes let's dump a summary of that. 14477 if (extraNativeRam > 0) { 14478 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14479 -1, extraNativeRam, "(Other native)"); 14480 shortNativeBuilder.append('\n'); 14481 extraNativeRam = 0; 14482 } 14483 appendMemInfo(fullJavaBuilder, mi); 14484 } 14485 } 14486 14487 fullJavaBuilder.append(" "); 14488 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14489 fullJavaBuilder.append(" kB: TOTAL\n"); 14490 14491 MemInfoReader memInfo = new MemInfoReader(); 14492 memInfo.readMemInfo(); 14493 final long[] infos = memInfo.getRawInfo(); 14494 14495 StringBuilder memInfoBuilder = new StringBuilder(1024); 14496 Debug.getMemInfo(infos); 14497 memInfoBuilder.append(" MemInfo: "); 14498 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14499 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14500 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14501 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14502 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14503 memInfoBuilder.append(" "); 14504 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14505 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14506 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14507 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14508 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14509 memInfoBuilder.append(" ZRAM: "); 14510 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14511 memInfoBuilder.append(" kB RAM, "); 14512 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14513 memInfoBuilder.append(" kB swap total, "); 14514 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14515 memInfoBuilder.append(" kB swap free\n"); 14516 } 14517 final long[] ksm = getKsmInfo(); 14518 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14519 || ksm[KSM_VOLATILE] != 0) { 14520 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14521 memInfoBuilder.append(" kB saved from shared "); 14522 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14523 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14524 memInfoBuilder.append(" kB unshared; "); 14525 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14526 } 14527 memInfoBuilder.append(" Free RAM: "); 14528 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14529 + memInfo.getFreeSizeKb()); 14530 memInfoBuilder.append(" kB\n"); 14531 memInfoBuilder.append(" Used RAM: "); 14532 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14533 memInfoBuilder.append(" kB\n"); 14534 memInfoBuilder.append(" Lost RAM: "); 14535 memInfoBuilder.append(memInfo.getTotalSizeKb() 14536 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14537 - memInfo.getKernelUsedSizeKb()); 14538 memInfoBuilder.append(" kB\n"); 14539 Slog.i(TAG, "Low on memory:"); 14540 Slog.i(TAG, shortNativeBuilder.toString()); 14541 Slog.i(TAG, fullJavaBuilder.toString()); 14542 Slog.i(TAG, memInfoBuilder.toString()); 14543 14544 StringBuilder dropBuilder = new StringBuilder(1024); 14545 /* 14546 StringWriter oomSw = new StringWriter(); 14547 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14548 StringWriter catSw = new StringWriter(); 14549 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14550 String[] emptyArgs = new String[] { }; 14551 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14552 oomPw.flush(); 14553 String oomString = oomSw.toString(); 14554 */ 14555 dropBuilder.append("Low on memory:"); 14556 dropBuilder.append(stack); 14557 dropBuilder.append('\n'); 14558 dropBuilder.append(fullNativeBuilder); 14559 dropBuilder.append(fullJavaBuilder); 14560 dropBuilder.append('\n'); 14561 dropBuilder.append(memInfoBuilder); 14562 dropBuilder.append('\n'); 14563 /* 14564 dropBuilder.append(oomString); 14565 dropBuilder.append('\n'); 14566 */ 14567 StringWriter catSw = new StringWriter(); 14568 synchronized (ActivityManagerService.this) { 14569 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14570 String[] emptyArgs = new String[] { }; 14571 catPw.println(); 14572 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14573 catPw.println(); 14574 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14575 false, false, null); 14576 catPw.println(); 14577 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14578 catPw.flush(); 14579 } 14580 dropBuilder.append(catSw.toString()); 14581 addErrorToDropBox("lowmem", null, "system_server", null, 14582 null, tag.toString(), dropBuilder.toString(), null, null); 14583 //Slog.i(TAG, "Sent to dropbox:"); 14584 //Slog.i(TAG, dropBuilder.toString()); 14585 synchronized (ActivityManagerService.this) { 14586 long now = SystemClock.uptimeMillis(); 14587 if (mLastMemUsageReportTime < now) { 14588 mLastMemUsageReportTime = now; 14589 } 14590 } 14591 } 14592 14593 /** 14594 * Searches array of arguments for the specified string 14595 * @param args array of argument strings 14596 * @param value value to search for 14597 * @return true if the value is contained in the array 14598 */ 14599 private static boolean scanArgs(String[] args, String value) { 14600 if (args != null) { 14601 for (String arg : args) { 14602 if (value.equals(arg)) { 14603 return true; 14604 } 14605 } 14606 } 14607 return false; 14608 } 14609 14610 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14611 ContentProviderRecord cpr, boolean always) { 14612 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14613 14614 if (!inLaunching || always) { 14615 synchronized (cpr) { 14616 cpr.launchingApp = null; 14617 cpr.notifyAll(); 14618 } 14619 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14620 String names[] = cpr.info.authority.split(";"); 14621 for (int j = 0; j < names.length; j++) { 14622 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14623 } 14624 } 14625 14626 for (int i=0; i<cpr.connections.size(); i++) { 14627 ContentProviderConnection conn = cpr.connections.get(i); 14628 if (conn.waiting) { 14629 // If this connection is waiting for the provider, then we don't 14630 // need to mess with its process unless we are always removing 14631 // or for some reason the provider is not currently launching. 14632 if (inLaunching && !always) { 14633 continue; 14634 } 14635 } 14636 ProcessRecord capp = conn.client; 14637 conn.dead = true; 14638 if (conn.stableCount > 0) { 14639 if (!capp.persistent && capp.thread != null 14640 && capp.pid != 0 14641 && capp.pid != MY_PID) { 14642 capp.kill("depends on provider " 14643 + cpr.name.flattenToShortString() 14644 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14645 } 14646 } else if (capp.thread != null && conn.provider.provider != null) { 14647 try { 14648 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14649 } catch (RemoteException e) { 14650 } 14651 // In the protocol here, we don't expect the client to correctly 14652 // clean up this connection, we'll just remove it. 14653 cpr.connections.remove(i); 14654 conn.client.conProviders.remove(conn); 14655 } 14656 } 14657 14658 if (inLaunching && always) { 14659 mLaunchingProviders.remove(cpr); 14660 } 14661 return inLaunching; 14662 } 14663 14664 /** 14665 * Main code for cleaning up a process when it has gone away. This is 14666 * called both as a result of the process dying, or directly when stopping 14667 * a process when running in single process mode. 14668 * 14669 * @return Returns true if the given process has been restarted, so the 14670 * app that was passed in must remain on the process lists. 14671 */ 14672 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14673 boolean restarting, boolean allowRestart, int index) { 14674 if (index >= 0) { 14675 removeLruProcessLocked(app); 14676 ProcessList.remove(app.pid); 14677 } 14678 14679 mProcessesToGc.remove(app); 14680 mPendingPssProcesses.remove(app); 14681 14682 // Dismiss any open dialogs. 14683 if (app.crashDialog != null && !app.forceCrashReport) { 14684 app.crashDialog.dismiss(); 14685 app.crashDialog = null; 14686 } 14687 if (app.anrDialog != null) { 14688 app.anrDialog.dismiss(); 14689 app.anrDialog = null; 14690 } 14691 if (app.waitDialog != null) { 14692 app.waitDialog.dismiss(); 14693 app.waitDialog = null; 14694 } 14695 14696 app.crashing = false; 14697 app.notResponding = false; 14698 14699 app.resetPackageList(mProcessStats); 14700 app.unlinkDeathRecipient(); 14701 app.makeInactive(mProcessStats); 14702 app.waitingToKill = null; 14703 app.forcingToForeground = null; 14704 updateProcessForegroundLocked(app, false, false); 14705 app.foregroundActivities = false; 14706 app.hasShownUi = false; 14707 app.treatLikeActivity = false; 14708 app.hasAboveClient = false; 14709 app.hasClientActivities = false; 14710 14711 mServices.killServicesLocked(app, allowRestart); 14712 14713 boolean restart = false; 14714 14715 // Remove published content providers. 14716 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14717 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14718 final boolean always = app.bad || !allowRestart; 14719 if (removeDyingProviderLocked(app, cpr, always) || always) { 14720 // We left the provider in the launching list, need to 14721 // restart it. 14722 restart = true; 14723 } 14724 14725 cpr.provider = null; 14726 cpr.proc = null; 14727 } 14728 app.pubProviders.clear(); 14729 14730 // Take care of any launching providers waiting for this process. 14731 if (checkAppInLaunchingProvidersLocked(app, false)) { 14732 restart = true; 14733 } 14734 14735 // Unregister from connected content providers. 14736 if (!app.conProviders.isEmpty()) { 14737 for (int i=0; i<app.conProviders.size(); i++) { 14738 ContentProviderConnection conn = app.conProviders.get(i); 14739 conn.provider.connections.remove(conn); 14740 } 14741 app.conProviders.clear(); 14742 } 14743 14744 // At this point there may be remaining entries in mLaunchingProviders 14745 // where we were the only one waiting, so they are no longer of use. 14746 // Look for these and clean up if found. 14747 // XXX Commented out for now. Trying to figure out a way to reproduce 14748 // the actual situation to identify what is actually going on. 14749 if (false) { 14750 for (int i=0; i<mLaunchingProviders.size(); i++) { 14751 ContentProviderRecord cpr = (ContentProviderRecord) 14752 mLaunchingProviders.get(i); 14753 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14754 synchronized (cpr) { 14755 cpr.launchingApp = null; 14756 cpr.notifyAll(); 14757 } 14758 } 14759 } 14760 } 14761 14762 skipCurrentReceiverLocked(app); 14763 14764 // Unregister any receivers. 14765 for (int i=app.receivers.size()-1; i>=0; i--) { 14766 removeReceiverLocked(app.receivers.valueAt(i)); 14767 } 14768 app.receivers.clear(); 14769 14770 // If the app is undergoing backup, tell the backup manager about it 14771 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14772 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14773 + mBackupTarget.appInfo + " died during backup"); 14774 try { 14775 IBackupManager bm = IBackupManager.Stub.asInterface( 14776 ServiceManager.getService(Context.BACKUP_SERVICE)); 14777 bm.agentDisconnected(app.info.packageName); 14778 } catch (RemoteException e) { 14779 // can't happen; backup manager is local 14780 } 14781 } 14782 14783 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14784 ProcessChangeItem item = mPendingProcessChanges.get(i); 14785 if (item.pid == app.pid) { 14786 mPendingProcessChanges.remove(i); 14787 mAvailProcessChanges.add(item); 14788 } 14789 } 14790 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14791 14792 // If the caller is restarting this app, then leave it in its 14793 // current lists and let the caller take care of it. 14794 if (restarting) { 14795 return false; 14796 } 14797 14798 if (!app.persistent || app.isolated) { 14799 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14800 "Removing non-persistent process during cleanup: " + app); 14801 mProcessNames.remove(app.processName, app.uid); 14802 mIsolatedProcesses.remove(app.uid); 14803 if (mHeavyWeightProcess == app) { 14804 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14805 mHeavyWeightProcess.userId, 0)); 14806 mHeavyWeightProcess = null; 14807 } 14808 } else if (!app.removed) { 14809 // This app is persistent, so we need to keep its record around. 14810 // If it is not already on the pending app list, add it there 14811 // and start a new process for it. 14812 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14813 mPersistentStartingProcesses.add(app); 14814 restart = true; 14815 } 14816 } 14817 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14818 "Clean-up removing on hold: " + app); 14819 mProcessesOnHold.remove(app); 14820 14821 if (app == mHomeProcess) { 14822 mHomeProcess = null; 14823 } 14824 if (app == mPreviousProcess) { 14825 mPreviousProcess = null; 14826 } 14827 14828 if (restart && !app.isolated) { 14829 // We have components that still need to be running in the 14830 // process, so re-launch it. 14831 if (index < 0) { 14832 ProcessList.remove(app.pid); 14833 } 14834 mProcessNames.put(app.processName, app.uid, app); 14835 startProcessLocked(app, "restart", app.processName); 14836 return true; 14837 } else if (app.pid > 0 && app.pid != MY_PID) { 14838 // Goodbye! 14839 boolean removed; 14840 synchronized (mPidsSelfLocked) { 14841 mPidsSelfLocked.remove(app.pid); 14842 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14843 } 14844 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14845 if (app.isolated) { 14846 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14847 } 14848 app.setPid(0); 14849 } 14850 return false; 14851 } 14852 14853 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14854 // Look through the content providers we are waiting to have launched, 14855 // and if any run in this process then either schedule a restart of 14856 // the process or kill the client waiting for it if this process has 14857 // gone bad. 14858 int NL = mLaunchingProviders.size(); 14859 boolean restart = false; 14860 for (int i=0; i<NL; i++) { 14861 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14862 if (cpr.launchingApp == app) { 14863 if (!alwaysBad && !app.bad) { 14864 restart = true; 14865 } else { 14866 removeDyingProviderLocked(app, cpr, true); 14867 // cpr should have been removed from mLaunchingProviders 14868 NL = mLaunchingProviders.size(); 14869 i--; 14870 } 14871 } 14872 } 14873 return restart; 14874 } 14875 14876 // ========================================================= 14877 // SERVICES 14878 // ========================================================= 14879 14880 @Override 14881 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14882 int flags) { 14883 enforceNotIsolatedCaller("getServices"); 14884 synchronized (this) { 14885 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14886 } 14887 } 14888 14889 @Override 14890 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14891 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14892 synchronized (this) { 14893 return mServices.getRunningServiceControlPanelLocked(name); 14894 } 14895 } 14896 14897 @Override 14898 public ComponentName startService(IApplicationThread caller, Intent service, 14899 String resolvedType, int userId) { 14900 enforceNotIsolatedCaller("startService"); 14901 // Refuse possible leaked file descriptors 14902 if (service != null && service.hasFileDescriptors() == true) { 14903 throw new IllegalArgumentException("File descriptors passed in Intent"); 14904 } 14905 14906 if (DEBUG_SERVICE) 14907 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14908 synchronized(this) { 14909 final int callingPid = Binder.getCallingPid(); 14910 final int callingUid = Binder.getCallingUid(); 14911 final long origId = Binder.clearCallingIdentity(); 14912 ComponentName res = mServices.startServiceLocked(caller, service, 14913 resolvedType, callingPid, callingUid, userId); 14914 Binder.restoreCallingIdentity(origId); 14915 return res; 14916 } 14917 } 14918 14919 ComponentName startServiceInPackage(int uid, 14920 Intent service, String resolvedType, int userId) { 14921 synchronized(this) { 14922 if (DEBUG_SERVICE) 14923 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14924 final long origId = Binder.clearCallingIdentity(); 14925 ComponentName res = mServices.startServiceLocked(null, service, 14926 resolvedType, -1, uid, userId); 14927 Binder.restoreCallingIdentity(origId); 14928 return res; 14929 } 14930 } 14931 14932 @Override 14933 public int stopService(IApplicationThread caller, Intent service, 14934 String resolvedType, int userId) { 14935 enforceNotIsolatedCaller("stopService"); 14936 // Refuse possible leaked file descriptors 14937 if (service != null && service.hasFileDescriptors() == true) { 14938 throw new IllegalArgumentException("File descriptors passed in Intent"); 14939 } 14940 14941 synchronized(this) { 14942 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14943 } 14944 } 14945 14946 @Override 14947 public IBinder peekService(Intent service, String resolvedType) { 14948 enforceNotIsolatedCaller("peekService"); 14949 // Refuse possible leaked file descriptors 14950 if (service != null && service.hasFileDescriptors() == true) { 14951 throw new IllegalArgumentException("File descriptors passed in Intent"); 14952 } 14953 synchronized(this) { 14954 return mServices.peekServiceLocked(service, resolvedType); 14955 } 14956 } 14957 14958 @Override 14959 public boolean stopServiceToken(ComponentName className, IBinder token, 14960 int startId) { 14961 synchronized(this) { 14962 return mServices.stopServiceTokenLocked(className, token, startId); 14963 } 14964 } 14965 14966 @Override 14967 public void setServiceForeground(ComponentName className, IBinder token, 14968 int id, Notification notification, boolean removeNotification) { 14969 synchronized(this) { 14970 mServices.setServiceForegroundLocked(className, token, id, notification, 14971 removeNotification); 14972 } 14973 } 14974 14975 @Override 14976 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14977 boolean requireFull, String name, String callerPackage) { 14978 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14979 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14980 } 14981 14982 int unsafeConvertIncomingUser(int userId) { 14983 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14984 ? mCurrentUserId : userId; 14985 } 14986 14987 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14988 int allowMode, String name, String callerPackage) { 14989 final int callingUserId = UserHandle.getUserId(callingUid); 14990 if (callingUserId == userId) { 14991 return userId; 14992 } 14993 14994 // Note that we may be accessing mCurrentUserId outside of a lock... 14995 // shouldn't be a big deal, if this is being called outside 14996 // of a locked context there is intrinsically a race with 14997 // the value the caller will receive and someone else changing it. 14998 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14999 // we will switch to the calling user if access to the current user fails. 15000 int targetUserId = unsafeConvertIncomingUser(userId); 15001 15002 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15003 final boolean allow; 15004 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15005 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15006 // If the caller has this permission, they always pass go. And collect $200. 15007 allow = true; 15008 } else if (allowMode == ALLOW_FULL_ONLY) { 15009 // We require full access, sucks to be you. 15010 allow = false; 15011 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15012 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15013 // If the caller does not have either permission, they are always doomed. 15014 allow = false; 15015 } else if (allowMode == ALLOW_NON_FULL) { 15016 // We are blanket allowing non-full access, you lucky caller! 15017 allow = true; 15018 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15019 // We may or may not allow this depending on whether the two users are 15020 // in the same profile. 15021 synchronized (mUserProfileGroupIdsSelfLocked) { 15022 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15023 UserInfo.NO_PROFILE_GROUP_ID); 15024 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15025 UserInfo.NO_PROFILE_GROUP_ID); 15026 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15027 && callingProfile == targetProfile; 15028 } 15029 } else { 15030 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15031 } 15032 if (!allow) { 15033 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15034 // In this case, they would like to just execute as their 15035 // owner user instead of failing. 15036 targetUserId = callingUserId; 15037 } else { 15038 StringBuilder builder = new StringBuilder(128); 15039 builder.append("Permission Denial: "); 15040 builder.append(name); 15041 if (callerPackage != null) { 15042 builder.append(" from "); 15043 builder.append(callerPackage); 15044 } 15045 builder.append(" asks to run as user "); 15046 builder.append(userId); 15047 builder.append(" but is calling from user "); 15048 builder.append(UserHandle.getUserId(callingUid)); 15049 builder.append("; this requires "); 15050 builder.append(INTERACT_ACROSS_USERS_FULL); 15051 if (allowMode != ALLOW_FULL_ONLY) { 15052 builder.append(" or "); 15053 builder.append(INTERACT_ACROSS_USERS); 15054 } 15055 String msg = builder.toString(); 15056 Slog.w(TAG, msg); 15057 throw new SecurityException(msg); 15058 } 15059 } 15060 } 15061 if (!allowAll && targetUserId < 0) { 15062 throw new IllegalArgumentException( 15063 "Call does not support special user #" + targetUserId); 15064 } 15065 // Check shell permission 15066 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15067 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15068 targetUserId)) { 15069 throw new SecurityException("Shell does not have permission to access user " 15070 + targetUserId + "\n " + Debug.getCallers(3)); 15071 } 15072 } 15073 return targetUserId; 15074 } 15075 15076 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15077 String className, int flags) { 15078 boolean result = false; 15079 // For apps that don't have pre-defined UIDs, check for permission 15080 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15081 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15082 if (ActivityManager.checkUidPermission( 15083 INTERACT_ACROSS_USERS, 15084 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15085 ComponentName comp = new ComponentName(aInfo.packageName, className); 15086 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15087 + " requests FLAG_SINGLE_USER, but app does not hold " 15088 + INTERACT_ACROSS_USERS; 15089 Slog.w(TAG, msg); 15090 throw new SecurityException(msg); 15091 } 15092 // Permission passed 15093 result = true; 15094 } 15095 } else if ("system".equals(componentProcessName)) { 15096 result = true; 15097 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15098 // Phone app and persistent apps are allowed to export singleuser providers. 15099 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15100 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15101 } 15102 if (DEBUG_MU) { 15103 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15104 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15105 } 15106 return result; 15107 } 15108 15109 /** 15110 * Checks to see if the caller is in the same app as the singleton 15111 * component, or the component is in a special app. It allows special apps 15112 * to export singleton components but prevents exporting singleton 15113 * components for regular apps. 15114 */ 15115 boolean isValidSingletonCall(int callingUid, int componentUid) { 15116 int componentAppId = UserHandle.getAppId(componentUid); 15117 return UserHandle.isSameApp(callingUid, componentUid) 15118 || componentAppId == Process.SYSTEM_UID 15119 || componentAppId == Process.PHONE_UID 15120 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15121 == PackageManager.PERMISSION_GRANTED; 15122 } 15123 15124 public int bindService(IApplicationThread caller, IBinder token, 15125 Intent service, String resolvedType, 15126 IServiceConnection connection, int flags, int userId) { 15127 enforceNotIsolatedCaller("bindService"); 15128 15129 // Refuse possible leaked file descriptors 15130 if (service != null && service.hasFileDescriptors() == true) { 15131 throw new IllegalArgumentException("File descriptors passed in Intent"); 15132 } 15133 15134 synchronized(this) { 15135 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15136 connection, flags, userId); 15137 } 15138 } 15139 15140 public boolean unbindService(IServiceConnection connection) { 15141 synchronized (this) { 15142 return mServices.unbindServiceLocked(connection); 15143 } 15144 } 15145 15146 public void publishService(IBinder token, Intent intent, IBinder service) { 15147 // Refuse possible leaked file descriptors 15148 if (intent != null && intent.hasFileDescriptors() == true) { 15149 throw new IllegalArgumentException("File descriptors passed in Intent"); 15150 } 15151 15152 synchronized(this) { 15153 if (!(token instanceof ServiceRecord)) { 15154 throw new IllegalArgumentException("Invalid service token"); 15155 } 15156 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15157 } 15158 } 15159 15160 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15161 // Refuse possible leaked file descriptors 15162 if (intent != null && intent.hasFileDescriptors() == true) { 15163 throw new IllegalArgumentException("File descriptors passed in Intent"); 15164 } 15165 15166 synchronized(this) { 15167 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15168 } 15169 } 15170 15171 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15172 synchronized(this) { 15173 if (!(token instanceof ServiceRecord)) { 15174 throw new IllegalArgumentException("Invalid service token"); 15175 } 15176 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15177 } 15178 } 15179 15180 // ========================================================= 15181 // BACKUP AND RESTORE 15182 // ========================================================= 15183 15184 // Cause the target app to be launched if necessary and its backup agent 15185 // instantiated. The backup agent will invoke backupAgentCreated() on the 15186 // activity manager to announce its creation. 15187 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15188 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15189 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15190 15191 synchronized(this) { 15192 // !!! TODO: currently no check here that we're already bound 15193 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15194 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15195 synchronized (stats) { 15196 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15197 } 15198 15199 // Backup agent is now in use, its package can't be stopped. 15200 try { 15201 AppGlobals.getPackageManager().setPackageStoppedState( 15202 app.packageName, false, UserHandle.getUserId(app.uid)); 15203 } catch (RemoteException e) { 15204 } catch (IllegalArgumentException e) { 15205 Slog.w(TAG, "Failed trying to unstop package " 15206 + app.packageName + ": " + e); 15207 } 15208 15209 BackupRecord r = new BackupRecord(ss, app, backupMode); 15210 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15211 ? new ComponentName(app.packageName, app.backupAgentName) 15212 : new ComponentName("android", "FullBackupAgent"); 15213 // startProcessLocked() returns existing proc's record if it's already running 15214 ProcessRecord proc = startProcessLocked(app.processName, app, 15215 false, 0, "backup", hostingName, false, false, false); 15216 if (proc == null) { 15217 Slog.e(TAG, "Unable to start backup agent process " + r); 15218 return false; 15219 } 15220 15221 r.app = proc; 15222 mBackupTarget = r; 15223 mBackupAppName = app.packageName; 15224 15225 // Try not to kill the process during backup 15226 updateOomAdjLocked(proc); 15227 15228 // If the process is already attached, schedule the creation of the backup agent now. 15229 // If it is not yet live, this will be done when it attaches to the framework. 15230 if (proc.thread != null) { 15231 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15232 try { 15233 proc.thread.scheduleCreateBackupAgent(app, 15234 compatibilityInfoForPackageLocked(app), backupMode); 15235 } catch (RemoteException e) { 15236 // Will time out on the backup manager side 15237 } 15238 } else { 15239 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15240 } 15241 // Invariants: at this point, the target app process exists and the application 15242 // is either already running or in the process of coming up. mBackupTarget and 15243 // mBackupAppName describe the app, so that when it binds back to the AM we 15244 // know that it's scheduled for a backup-agent operation. 15245 } 15246 15247 return true; 15248 } 15249 15250 @Override 15251 public void clearPendingBackup() { 15252 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15253 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15254 15255 synchronized (this) { 15256 mBackupTarget = null; 15257 mBackupAppName = null; 15258 } 15259 } 15260 15261 // A backup agent has just come up 15262 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15263 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15264 + " = " + agent); 15265 15266 synchronized(this) { 15267 if (!agentPackageName.equals(mBackupAppName)) { 15268 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15269 return; 15270 } 15271 } 15272 15273 long oldIdent = Binder.clearCallingIdentity(); 15274 try { 15275 IBackupManager bm = IBackupManager.Stub.asInterface( 15276 ServiceManager.getService(Context.BACKUP_SERVICE)); 15277 bm.agentConnected(agentPackageName, agent); 15278 } catch (RemoteException e) { 15279 // can't happen; the backup manager service is local 15280 } catch (Exception e) { 15281 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15282 e.printStackTrace(); 15283 } finally { 15284 Binder.restoreCallingIdentity(oldIdent); 15285 } 15286 } 15287 15288 // done with this agent 15289 public void unbindBackupAgent(ApplicationInfo appInfo) { 15290 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15291 if (appInfo == null) { 15292 Slog.w(TAG, "unbind backup agent for null app"); 15293 return; 15294 } 15295 15296 synchronized(this) { 15297 try { 15298 if (mBackupAppName == null) { 15299 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15300 return; 15301 } 15302 15303 if (!mBackupAppName.equals(appInfo.packageName)) { 15304 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15305 return; 15306 } 15307 15308 // Not backing this app up any more; reset its OOM adjustment 15309 final ProcessRecord proc = mBackupTarget.app; 15310 updateOomAdjLocked(proc); 15311 15312 // If the app crashed during backup, 'thread' will be null here 15313 if (proc.thread != null) { 15314 try { 15315 proc.thread.scheduleDestroyBackupAgent(appInfo, 15316 compatibilityInfoForPackageLocked(appInfo)); 15317 } catch (Exception e) { 15318 Slog.e(TAG, "Exception when unbinding backup agent:"); 15319 e.printStackTrace(); 15320 } 15321 } 15322 } finally { 15323 mBackupTarget = null; 15324 mBackupAppName = null; 15325 } 15326 } 15327 } 15328 // ========================================================= 15329 // BROADCASTS 15330 // ========================================================= 15331 15332 private final List getStickiesLocked(String action, IntentFilter filter, 15333 List cur, int userId) { 15334 final ContentResolver resolver = mContext.getContentResolver(); 15335 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15336 if (stickies == null) { 15337 return cur; 15338 } 15339 final ArrayList<Intent> list = stickies.get(action); 15340 if (list == null) { 15341 return cur; 15342 } 15343 int N = list.size(); 15344 for (int i=0; i<N; i++) { 15345 Intent intent = list.get(i); 15346 if (filter.match(resolver, intent, true, TAG) >= 0) { 15347 if (cur == null) { 15348 cur = new ArrayList<Intent>(); 15349 } 15350 cur.add(intent); 15351 } 15352 } 15353 return cur; 15354 } 15355 15356 boolean isPendingBroadcastProcessLocked(int pid) { 15357 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15358 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15359 } 15360 15361 void skipPendingBroadcastLocked(int pid) { 15362 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15363 for (BroadcastQueue queue : mBroadcastQueues) { 15364 queue.skipPendingBroadcastLocked(pid); 15365 } 15366 } 15367 15368 // The app just attached; send any pending broadcasts that it should receive 15369 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15370 boolean didSomething = false; 15371 for (BroadcastQueue queue : mBroadcastQueues) { 15372 didSomething |= queue.sendPendingBroadcastsLocked(app); 15373 } 15374 return didSomething; 15375 } 15376 15377 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15378 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15379 enforceNotIsolatedCaller("registerReceiver"); 15380 int callingUid; 15381 int callingPid; 15382 synchronized(this) { 15383 ProcessRecord callerApp = null; 15384 if (caller != null) { 15385 callerApp = getRecordForAppLocked(caller); 15386 if (callerApp == null) { 15387 throw new SecurityException( 15388 "Unable to find app for caller " + caller 15389 + " (pid=" + Binder.getCallingPid() 15390 + ") when registering receiver " + receiver); 15391 } 15392 if (callerApp.info.uid != Process.SYSTEM_UID && 15393 !callerApp.pkgList.containsKey(callerPackage) && 15394 !"android".equals(callerPackage)) { 15395 throw new SecurityException("Given caller package " + callerPackage 15396 + " is not running in process " + callerApp); 15397 } 15398 callingUid = callerApp.info.uid; 15399 callingPid = callerApp.pid; 15400 } else { 15401 callerPackage = null; 15402 callingUid = Binder.getCallingUid(); 15403 callingPid = Binder.getCallingPid(); 15404 } 15405 15406 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15407 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15408 15409 List allSticky = null; 15410 15411 // Look for any matching sticky broadcasts... 15412 Iterator actions = filter.actionsIterator(); 15413 if (actions != null) { 15414 while (actions.hasNext()) { 15415 String action = (String)actions.next(); 15416 allSticky = getStickiesLocked(action, filter, allSticky, 15417 UserHandle.USER_ALL); 15418 allSticky = getStickiesLocked(action, filter, allSticky, 15419 UserHandle.getUserId(callingUid)); 15420 } 15421 } else { 15422 allSticky = getStickiesLocked(null, filter, allSticky, 15423 UserHandle.USER_ALL); 15424 allSticky = getStickiesLocked(null, filter, allSticky, 15425 UserHandle.getUserId(callingUid)); 15426 } 15427 15428 // The first sticky in the list is returned directly back to 15429 // the client. 15430 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15431 15432 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15433 + ": " + sticky); 15434 15435 if (receiver == null) { 15436 return sticky; 15437 } 15438 15439 ReceiverList rl 15440 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15441 if (rl == null) { 15442 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15443 userId, receiver); 15444 if (rl.app != null) { 15445 rl.app.receivers.add(rl); 15446 } else { 15447 try { 15448 receiver.asBinder().linkToDeath(rl, 0); 15449 } catch (RemoteException e) { 15450 return sticky; 15451 } 15452 rl.linkedToDeath = true; 15453 } 15454 mRegisteredReceivers.put(receiver.asBinder(), rl); 15455 } else if (rl.uid != callingUid) { 15456 throw new IllegalArgumentException( 15457 "Receiver requested to register for uid " + callingUid 15458 + " was previously registered for uid " + rl.uid); 15459 } else if (rl.pid != callingPid) { 15460 throw new IllegalArgumentException( 15461 "Receiver requested to register for pid " + callingPid 15462 + " was previously registered for pid " + rl.pid); 15463 } else if (rl.userId != userId) { 15464 throw new IllegalArgumentException( 15465 "Receiver requested to register for user " + userId 15466 + " was previously registered for user " + rl.userId); 15467 } 15468 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15469 permission, callingUid, userId); 15470 rl.add(bf); 15471 if (!bf.debugCheck()) { 15472 Slog.w(TAG, "==> For Dynamic broadast"); 15473 } 15474 mReceiverResolver.addFilter(bf); 15475 15476 // Enqueue broadcasts for all existing stickies that match 15477 // this filter. 15478 if (allSticky != null) { 15479 ArrayList receivers = new ArrayList(); 15480 receivers.add(bf); 15481 15482 int N = allSticky.size(); 15483 for (int i=0; i<N; i++) { 15484 Intent intent = (Intent)allSticky.get(i); 15485 BroadcastQueue queue = broadcastQueueForIntent(intent); 15486 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15487 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15488 null, null, false, true, true, -1); 15489 queue.enqueueParallelBroadcastLocked(r); 15490 queue.scheduleBroadcastsLocked(); 15491 } 15492 } 15493 15494 return sticky; 15495 } 15496 } 15497 15498 public void unregisterReceiver(IIntentReceiver receiver) { 15499 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15500 15501 final long origId = Binder.clearCallingIdentity(); 15502 try { 15503 boolean doTrim = false; 15504 15505 synchronized(this) { 15506 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15507 if (rl != null) { 15508 if (rl.curBroadcast != null) { 15509 BroadcastRecord r = rl.curBroadcast; 15510 final boolean doNext = finishReceiverLocked( 15511 receiver.asBinder(), r.resultCode, r.resultData, 15512 r.resultExtras, r.resultAbort); 15513 if (doNext) { 15514 doTrim = true; 15515 r.queue.processNextBroadcast(false); 15516 } 15517 } 15518 15519 if (rl.app != null) { 15520 rl.app.receivers.remove(rl); 15521 } 15522 removeReceiverLocked(rl); 15523 if (rl.linkedToDeath) { 15524 rl.linkedToDeath = false; 15525 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15526 } 15527 } 15528 } 15529 15530 // If we actually concluded any broadcasts, we might now be able 15531 // to trim the recipients' apps from our working set 15532 if (doTrim) { 15533 trimApplications(); 15534 return; 15535 } 15536 15537 } finally { 15538 Binder.restoreCallingIdentity(origId); 15539 } 15540 } 15541 15542 void removeReceiverLocked(ReceiverList rl) { 15543 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15544 int N = rl.size(); 15545 for (int i=0; i<N; i++) { 15546 mReceiverResolver.removeFilter(rl.get(i)); 15547 } 15548 } 15549 15550 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15551 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15552 ProcessRecord r = mLruProcesses.get(i); 15553 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15554 try { 15555 r.thread.dispatchPackageBroadcast(cmd, packages); 15556 } catch (RemoteException ex) { 15557 } 15558 } 15559 } 15560 } 15561 15562 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15563 int callingUid, int[] users) { 15564 List<ResolveInfo> receivers = null; 15565 try { 15566 HashSet<ComponentName> singleUserReceivers = null; 15567 boolean scannedFirstReceivers = false; 15568 for (int user : users) { 15569 // Skip users that have Shell restrictions 15570 if (callingUid == Process.SHELL_UID 15571 && getUserManagerLocked().hasUserRestriction( 15572 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15573 continue; 15574 } 15575 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15576 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15577 if (user != 0 && newReceivers != null) { 15578 // If this is not the primary user, we need to check for 15579 // any receivers that should be filtered out. 15580 for (int i=0; i<newReceivers.size(); i++) { 15581 ResolveInfo ri = newReceivers.get(i); 15582 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15583 newReceivers.remove(i); 15584 i--; 15585 } 15586 } 15587 } 15588 if (newReceivers != null && newReceivers.size() == 0) { 15589 newReceivers = null; 15590 } 15591 if (receivers == null) { 15592 receivers = newReceivers; 15593 } else if (newReceivers != null) { 15594 // We need to concatenate the additional receivers 15595 // found with what we have do far. This would be easy, 15596 // but we also need to de-dup any receivers that are 15597 // singleUser. 15598 if (!scannedFirstReceivers) { 15599 // Collect any single user receivers we had already retrieved. 15600 scannedFirstReceivers = true; 15601 for (int i=0; i<receivers.size(); i++) { 15602 ResolveInfo ri = receivers.get(i); 15603 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15604 ComponentName cn = new ComponentName( 15605 ri.activityInfo.packageName, ri.activityInfo.name); 15606 if (singleUserReceivers == null) { 15607 singleUserReceivers = new HashSet<ComponentName>(); 15608 } 15609 singleUserReceivers.add(cn); 15610 } 15611 } 15612 } 15613 // Add the new results to the existing results, tracking 15614 // and de-dupping single user receivers. 15615 for (int i=0; i<newReceivers.size(); i++) { 15616 ResolveInfo ri = newReceivers.get(i); 15617 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15618 ComponentName cn = new ComponentName( 15619 ri.activityInfo.packageName, ri.activityInfo.name); 15620 if (singleUserReceivers == null) { 15621 singleUserReceivers = new HashSet<ComponentName>(); 15622 } 15623 if (!singleUserReceivers.contains(cn)) { 15624 singleUserReceivers.add(cn); 15625 receivers.add(ri); 15626 } 15627 } else { 15628 receivers.add(ri); 15629 } 15630 } 15631 } 15632 } 15633 } catch (RemoteException ex) { 15634 // pm is in same process, this will never happen. 15635 } 15636 return receivers; 15637 } 15638 15639 private final int broadcastIntentLocked(ProcessRecord callerApp, 15640 String callerPackage, Intent intent, String resolvedType, 15641 IIntentReceiver resultTo, int resultCode, String resultData, 15642 Bundle map, String requiredPermission, int appOp, 15643 boolean ordered, boolean sticky, int callingPid, int callingUid, 15644 int userId) { 15645 intent = new Intent(intent); 15646 15647 // By default broadcasts do not go to stopped apps. 15648 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15649 15650 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15651 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15652 + " ordered=" + ordered + " userid=" + userId); 15653 if ((resultTo != null) && !ordered) { 15654 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15655 } 15656 15657 userId = handleIncomingUser(callingPid, callingUid, userId, 15658 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15659 15660 // Make sure that the user who is receiving this broadcast is started. 15661 // If not, we will just skip it. 15662 15663 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15664 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15665 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15666 Slog.w(TAG, "Skipping broadcast of " + intent 15667 + ": user " + userId + " is stopped"); 15668 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15669 } 15670 } 15671 15672 /* 15673 * Prevent non-system code (defined here to be non-persistent 15674 * processes) from sending protected broadcasts. 15675 */ 15676 int callingAppId = UserHandle.getAppId(callingUid); 15677 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15678 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15679 || callingAppId == Process.NFC_UID || callingUid == 0) { 15680 // Always okay. 15681 } else if (callerApp == null || !callerApp.persistent) { 15682 try { 15683 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15684 intent.getAction())) { 15685 String msg = "Permission Denial: not allowed to send broadcast " 15686 + intent.getAction() + " from pid=" 15687 + callingPid + ", uid=" + callingUid; 15688 Slog.w(TAG, msg); 15689 throw new SecurityException(msg); 15690 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15691 // Special case for compatibility: we don't want apps to send this, 15692 // but historically it has not been protected and apps may be using it 15693 // to poke their own app widget. So, instead of making it protected, 15694 // just limit it to the caller. 15695 if (callerApp == null) { 15696 String msg = "Permission Denial: not allowed to send broadcast " 15697 + intent.getAction() + " from unknown caller."; 15698 Slog.w(TAG, msg); 15699 throw new SecurityException(msg); 15700 } else if (intent.getComponent() != null) { 15701 // They are good enough to send to an explicit component... verify 15702 // it is being sent to the calling app. 15703 if (!intent.getComponent().getPackageName().equals( 15704 callerApp.info.packageName)) { 15705 String msg = "Permission Denial: not allowed to send broadcast " 15706 + intent.getAction() + " to " 15707 + intent.getComponent().getPackageName() + " from " 15708 + callerApp.info.packageName; 15709 Slog.w(TAG, msg); 15710 throw new SecurityException(msg); 15711 } 15712 } else { 15713 // Limit broadcast to their own package. 15714 intent.setPackage(callerApp.info.packageName); 15715 } 15716 } 15717 } catch (RemoteException e) { 15718 Slog.w(TAG, "Remote exception", e); 15719 return ActivityManager.BROADCAST_SUCCESS; 15720 } 15721 } 15722 15723 final String action = intent.getAction(); 15724 if (action != null) { 15725 switch (action) { 15726 case Intent.ACTION_UID_REMOVED: 15727 case Intent.ACTION_PACKAGE_REMOVED: 15728 case Intent.ACTION_PACKAGE_CHANGED: 15729 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15730 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15731 // Handle special intents: if this broadcast is from the package 15732 // manager about a package being removed, we need to remove all of 15733 // its activities from the history stack. 15734 if (checkComponentPermission( 15735 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15736 callingPid, callingUid, -1, true) 15737 != PackageManager.PERMISSION_GRANTED) { 15738 String msg = "Permission Denial: " + intent.getAction() 15739 + " broadcast from " + callerPackage + " (pid=" + callingPid 15740 + ", uid=" + callingUid + ")" 15741 + " requires " 15742 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15743 Slog.w(TAG, msg); 15744 throw new SecurityException(msg); 15745 } 15746 switch (action) { 15747 case Intent.ACTION_UID_REMOVED: 15748 final Bundle intentExtras = intent.getExtras(); 15749 final int uid = intentExtras != null 15750 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15751 if (uid >= 0) { 15752 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15753 synchronized (bs) { 15754 bs.removeUidStatsLocked(uid); 15755 } 15756 mAppOpsService.uidRemoved(uid); 15757 } 15758 break; 15759 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15760 // If resources are unavailable just force stop all those packages 15761 // and flush the attribute cache as well. 15762 String list[] = 15763 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15764 if (list != null && list.length > 0) { 15765 for (int i = 0; i < list.length; i++) { 15766 forceStopPackageLocked(list[i], -1, false, true, true, 15767 false, false, userId, "storage unmount"); 15768 } 15769 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15770 sendPackageBroadcastLocked( 15771 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15772 userId); 15773 } 15774 break; 15775 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15776 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15777 break; 15778 case Intent.ACTION_PACKAGE_REMOVED: 15779 case Intent.ACTION_PACKAGE_CHANGED: 15780 Uri data = intent.getData(); 15781 String ssp; 15782 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15783 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15784 boolean fullUninstall = removed && 15785 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15786 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15787 forceStopPackageLocked(ssp, UserHandle.getAppId( 15788 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15789 false, true, true, false, fullUninstall, userId, 15790 removed ? "pkg removed" : "pkg changed"); 15791 } 15792 if (removed) { 15793 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15794 new String[] {ssp}, userId); 15795 if (fullUninstall) { 15796 mAppOpsService.packageRemoved( 15797 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15798 15799 // Remove all permissions granted from/to this package 15800 removeUriPermissionsForPackageLocked(ssp, userId, true); 15801 15802 removeTasksByPackageNameLocked(ssp, userId); 15803 } 15804 } else { 15805 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15806 if (userId == UserHandle.USER_OWNER) { 15807 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15808 } 15809 } 15810 } 15811 break; 15812 } 15813 break; 15814 case Intent.ACTION_PACKAGE_ADDED: 15815 // Special case for adding a package: by default turn on compatibility mode. 15816 Uri data = intent.getData(); 15817 String ssp; 15818 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15819 final boolean replacing = 15820 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15821 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15822 15823 if (replacing) { 15824 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15825 } 15826 if (userId == UserHandle.USER_OWNER) { 15827 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15828 } 15829 } 15830 break; 15831 case Intent.ACTION_TIMEZONE_CHANGED: 15832 // If this is the time zone changed action, queue up a message that will reset 15833 // the timezone of all currently running processes. This message will get 15834 // queued up before the broadcast happens. 15835 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15836 break; 15837 case Intent.ACTION_TIME_CHANGED: 15838 // If the user set the time, let all running processes know. 15839 final int is24Hour = 15840 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15841 : 0; 15842 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15843 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15844 synchronized (stats) { 15845 stats.noteCurrentTimeChangedLocked(); 15846 } 15847 break; 15848 case Intent.ACTION_CLEAR_DNS_CACHE: 15849 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15850 break; 15851 case Proxy.PROXY_CHANGE_ACTION: 15852 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15853 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15854 break; 15855 } 15856 } 15857 15858 // Add to the sticky list if requested. 15859 if (sticky) { 15860 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15861 callingPid, callingUid) 15862 != PackageManager.PERMISSION_GRANTED) { 15863 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15864 + callingPid + ", uid=" + callingUid 15865 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15866 Slog.w(TAG, msg); 15867 throw new SecurityException(msg); 15868 } 15869 if (requiredPermission != null) { 15870 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15871 + " and enforce permission " + requiredPermission); 15872 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15873 } 15874 if (intent.getComponent() != null) { 15875 throw new SecurityException( 15876 "Sticky broadcasts can't target a specific component"); 15877 } 15878 // We use userId directly here, since the "all" target is maintained 15879 // as a separate set of sticky broadcasts. 15880 if (userId != UserHandle.USER_ALL) { 15881 // But first, if this is not a broadcast to all users, then 15882 // make sure it doesn't conflict with an existing broadcast to 15883 // all users. 15884 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15885 UserHandle.USER_ALL); 15886 if (stickies != null) { 15887 ArrayList<Intent> list = stickies.get(intent.getAction()); 15888 if (list != null) { 15889 int N = list.size(); 15890 int i; 15891 for (i=0; i<N; i++) { 15892 if (intent.filterEquals(list.get(i))) { 15893 throw new IllegalArgumentException( 15894 "Sticky broadcast " + intent + " for user " 15895 + userId + " conflicts with existing global broadcast"); 15896 } 15897 } 15898 } 15899 } 15900 } 15901 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15902 if (stickies == null) { 15903 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15904 mStickyBroadcasts.put(userId, stickies); 15905 } 15906 ArrayList<Intent> list = stickies.get(intent.getAction()); 15907 if (list == null) { 15908 list = new ArrayList<Intent>(); 15909 stickies.put(intent.getAction(), list); 15910 } 15911 int N = list.size(); 15912 int i; 15913 for (i=0; i<N; i++) { 15914 if (intent.filterEquals(list.get(i))) { 15915 // This sticky already exists, replace it. 15916 list.set(i, new Intent(intent)); 15917 break; 15918 } 15919 } 15920 if (i >= N) { 15921 list.add(new Intent(intent)); 15922 } 15923 } 15924 15925 int[] users; 15926 if (userId == UserHandle.USER_ALL) { 15927 // Caller wants broadcast to go to all started users. 15928 users = mStartedUserArray; 15929 } else { 15930 // Caller wants broadcast to go to one specific user. 15931 users = new int[] {userId}; 15932 } 15933 15934 // Figure out who all will receive this broadcast. 15935 List receivers = null; 15936 List<BroadcastFilter> registeredReceivers = null; 15937 // Need to resolve the intent to interested receivers... 15938 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15939 == 0) { 15940 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15941 } 15942 if (intent.getComponent() == null) { 15943 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15944 // Query one target user at a time, excluding shell-restricted users 15945 UserManagerService ums = getUserManagerLocked(); 15946 for (int i = 0; i < users.length; i++) { 15947 if (ums.hasUserRestriction( 15948 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15949 continue; 15950 } 15951 List<BroadcastFilter> registeredReceiversForUser = 15952 mReceiverResolver.queryIntent(intent, 15953 resolvedType, false, users[i]); 15954 if (registeredReceivers == null) { 15955 registeredReceivers = registeredReceiversForUser; 15956 } else if (registeredReceiversForUser != null) { 15957 registeredReceivers.addAll(registeredReceiversForUser); 15958 } 15959 } 15960 } else { 15961 registeredReceivers = mReceiverResolver.queryIntent(intent, 15962 resolvedType, false, userId); 15963 } 15964 } 15965 15966 final boolean replacePending = 15967 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15968 15969 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15970 + " replacePending=" + replacePending); 15971 15972 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15973 if (!ordered && NR > 0) { 15974 // If we are not serializing this broadcast, then send the 15975 // registered receivers separately so they don't wait for the 15976 // components to be launched. 15977 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15978 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15979 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15980 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15981 ordered, sticky, false, userId); 15982 if (DEBUG_BROADCAST) Slog.v( 15983 TAG, "Enqueueing parallel broadcast " + r); 15984 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15985 if (!replaced) { 15986 queue.enqueueParallelBroadcastLocked(r); 15987 queue.scheduleBroadcastsLocked(); 15988 } 15989 registeredReceivers = null; 15990 NR = 0; 15991 } 15992 15993 // Merge into one list. 15994 int ir = 0; 15995 if (receivers != null) { 15996 // A special case for PACKAGE_ADDED: do not allow the package 15997 // being added to see this broadcast. This prevents them from 15998 // using this as a back door to get run as soon as they are 15999 // installed. Maybe in the future we want to have a special install 16000 // broadcast or such for apps, but we'd like to deliberately make 16001 // this decision. 16002 String skipPackages[] = null; 16003 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16004 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16005 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16006 Uri data = intent.getData(); 16007 if (data != null) { 16008 String pkgName = data.getSchemeSpecificPart(); 16009 if (pkgName != null) { 16010 skipPackages = new String[] { pkgName }; 16011 } 16012 } 16013 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16014 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16015 } 16016 if (skipPackages != null && (skipPackages.length > 0)) { 16017 for (String skipPackage : skipPackages) { 16018 if (skipPackage != null) { 16019 int NT = receivers.size(); 16020 for (int it=0; it<NT; it++) { 16021 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16022 if (curt.activityInfo.packageName.equals(skipPackage)) { 16023 receivers.remove(it); 16024 it--; 16025 NT--; 16026 } 16027 } 16028 } 16029 } 16030 } 16031 16032 int NT = receivers != null ? receivers.size() : 0; 16033 int it = 0; 16034 ResolveInfo curt = null; 16035 BroadcastFilter curr = null; 16036 while (it < NT && ir < NR) { 16037 if (curt == null) { 16038 curt = (ResolveInfo)receivers.get(it); 16039 } 16040 if (curr == null) { 16041 curr = registeredReceivers.get(ir); 16042 } 16043 if (curr.getPriority() >= curt.priority) { 16044 // Insert this broadcast record into the final list. 16045 receivers.add(it, curr); 16046 ir++; 16047 curr = null; 16048 it++; 16049 NT++; 16050 } else { 16051 // Skip to the next ResolveInfo in the final list. 16052 it++; 16053 curt = null; 16054 } 16055 } 16056 } 16057 while (ir < NR) { 16058 if (receivers == null) { 16059 receivers = new ArrayList(); 16060 } 16061 receivers.add(registeredReceivers.get(ir)); 16062 ir++; 16063 } 16064 16065 if ((receivers != null && receivers.size() > 0) 16066 || resultTo != null) { 16067 BroadcastQueue queue = broadcastQueueForIntent(intent); 16068 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16069 callerPackage, callingPid, callingUid, resolvedType, 16070 requiredPermission, appOp, receivers, resultTo, resultCode, 16071 resultData, map, ordered, sticky, false, userId); 16072 if (DEBUG_BROADCAST) Slog.v( 16073 TAG, "Enqueueing ordered broadcast " + r 16074 + ": prev had " + queue.mOrderedBroadcasts.size()); 16075 if (DEBUG_BROADCAST) { 16076 int seq = r.intent.getIntExtra("seq", -1); 16077 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16078 } 16079 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16080 if (!replaced) { 16081 queue.enqueueOrderedBroadcastLocked(r); 16082 queue.scheduleBroadcastsLocked(); 16083 } 16084 } 16085 16086 return ActivityManager.BROADCAST_SUCCESS; 16087 } 16088 16089 final Intent verifyBroadcastLocked(Intent intent) { 16090 // Refuse possible leaked file descriptors 16091 if (intent != null && intent.hasFileDescriptors() == true) { 16092 throw new IllegalArgumentException("File descriptors passed in Intent"); 16093 } 16094 16095 int flags = intent.getFlags(); 16096 16097 if (!mProcessesReady) { 16098 // if the caller really truly claims to know what they're doing, go 16099 // ahead and allow the broadcast without launching any receivers 16100 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16101 intent = new Intent(intent); 16102 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16103 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16104 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16105 + " before boot completion"); 16106 throw new IllegalStateException("Cannot broadcast before boot completed"); 16107 } 16108 } 16109 16110 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16111 throw new IllegalArgumentException( 16112 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16113 } 16114 16115 return intent; 16116 } 16117 16118 public final int broadcastIntent(IApplicationThread caller, 16119 Intent intent, String resolvedType, IIntentReceiver resultTo, 16120 int resultCode, String resultData, Bundle map, 16121 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16122 enforceNotIsolatedCaller("broadcastIntent"); 16123 synchronized(this) { 16124 intent = verifyBroadcastLocked(intent); 16125 16126 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16127 final int callingPid = Binder.getCallingPid(); 16128 final int callingUid = Binder.getCallingUid(); 16129 final long origId = Binder.clearCallingIdentity(); 16130 int res = broadcastIntentLocked(callerApp, 16131 callerApp != null ? callerApp.info.packageName : null, 16132 intent, resolvedType, resultTo, 16133 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16134 callingPid, callingUid, userId); 16135 Binder.restoreCallingIdentity(origId); 16136 return res; 16137 } 16138 } 16139 16140 int broadcastIntentInPackage(String packageName, int uid, 16141 Intent intent, String resolvedType, IIntentReceiver resultTo, 16142 int resultCode, String resultData, Bundle map, 16143 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16144 synchronized(this) { 16145 intent = verifyBroadcastLocked(intent); 16146 16147 final long origId = Binder.clearCallingIdentity(); 16148 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16149 resultTo, resultCode, resultData, map, requiredPermission, 16150 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16151 Binder.restoreCallingIdentity(origId); 16152 return res; 16153 } 16154 } 16155 16156 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16157 // Refuse possible leaked file descriptors 16158 if (intent != null && intent.hasFileDescriptors() == true) { 16159 throw new IllegalArgumentException("File descriptors passed in Intent"); 16160 } 16161 16162 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16163 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16164 16165 synchronized(this) { 16166 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16167 != PackageManager.PERMISSION_GRANTED) { 16168 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16169 + Binder.getCallingPid() 16170 + ", uid=" + Binder.getCallingUid() 16171 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16172 Slog.w(TAG, msg); 16173 throw new SecurityException(msg); 16174 } 16175 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16176 if (stickies != null) { 16177 ArrayList<Intent> list = stickies.get(intent.getAction()); 16178 if (list != null) { 16179 int N = list.size(); 16180 int i; 16181 for (i=0; i<N; i++) { 16182 if (intent.filterEquals(list.get(i))) { 16183 list.remove(i); 16184 break; 16185 } 16186 } 16187 if (list.size() <= 0) { 16188 stickies.remove(intent.getAction()); 16189 } 16190 } 16191 if (stickies.size() <= 0) { 16192 mStickyBroadcasts.remove(userId); 16193 } 16194 } 16195 } 16196 } 16197 16198 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16199 String resultData, Bundle resultExtras, boolean resultAbort) { 16200 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16201 if (r == null) { 16202 Slog.w(TAG, "finishReceiver called but not found on queue"); 16203 return false; 16204 } 16205 16206 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16207 } 16208 16209 void backgroundServicesFinishedLocked(int userId) { 16210 for (BroadcastQueue queue : mBroadcastQueues) { 16211 queue.backgroundServicesFinishedLocked(userId); 16212 } 16213 } 16214 16215 public void finishReceiver(IBinder who, int resultCode, String resultData, 16216 Bundle resultExtras, boolean resultAbort) { 16217 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16218 16219 // Refuse possible leaked file descriptors 16220 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16221 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16222 } 16223 16224 final long origId = Binder.clearCallingIdentity(); 16225 try { 16226 boolean doNext = false; 16227 BroadcastRecord r; 16228 16229 synchronized(this) { 16230 r = broadcastRecordForReceiverLocked(who); 16231 if (r != null) { 16232 doNext = r.queue.finishReceiverLocked(r, resultCode, 16233 resultData, resultExtras, resultAbort, true); 16234 } 16235 } 16236 16237 if (doNext) { 16238 r.queue.processNextBroadcast(false); 16239 } 16240 trimApplications(); 16241 } finally { 16242 Binder.restoreCallingIdentity(origId); 16243 } 16244 } 16245 16246 // ========================================================= 16247 // INSTRUMENTATION 16248 // ========================================================= 16249 16250 public boolean startInstrumentation(ComponentName className, 16251 String profileFile, int flags, Bundle arguments, 16252 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16253 int userId, String abiOverride) { 16254 enforceNotIsolatedCaller("startInstrumentation"); 16255 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16256 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16257 // Refuse possible leaked file descriptors 16258 if (arguments != null && arguments.hasFileDescriptors()) { 16259 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16260 } 16261 16262 synchronized(this) { 16263 InstrumentationInfo ii = null; 16264 ApplicationInfo ai = null; 16265 try { 16266 ii = mContext.getPackageManager().getInstrumentationInfo( 16267 className, STOCK_PM_FLAGS); 16268 ai = AppGlobals.getPackageManager().getApplicationInfo( 16269 ii.targetPackage, STOCK_PM_FLAGS, userId); 16270 } catch (PackageManager.NameNotFoundException e) { 16271 } catch (RemoteException e) { 16272 } 16273 if (ii == null) { 16274 reportStartInstrumentationFailure(watcher, className, 16275 "Unable to find instrumentation info for: " + className); 16276 return false; 16277 } 16278 if (ai == null) { 16279 reportStartInstrumentationFailure(watcher, className, 16280 "Unable to find instrumentation target package: " + ii.targetPackage); 16281 return false; 16282 } 16283 16284 int match = mContext.getPackageManager().checkSignatures( 16285 ii.targetPackage, ii.packageName); 16286 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16287 String msg = "Permission Denial: starting instrumentation " 16288 + className + " from pid=" 16289 + Binder.getCallingPid() 16290 + ", uid=" + Binder.getCallingPid() 16291 + " not allowed because package " + ii.packageName 16292 + " does not have a signature matching the target " 16293 + ii.targetPackage; 16294 reportStartInstrumentationFailure(watcher, className, msg); 16295 throw new SecurityException(msg); 16296 } 16297 16298 final long origId = Binder.clearCallingIdentity(); 16299 // Instrumentation can kill and relaunch even persistent processes 16300 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16301 "start instr"); 16302 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16303 app.instrumentationClass = className; 16304 app.instrumentationInfo = ai; 16305 app.instrumentationProfileFile = profileFile; 16306 app.instrumentationArguments = arguments; 16307 app.instrumentationWatcher = watcher; 16308 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16309 app.instrumentationResultClass = className; 16310 Binder.restoreCallingIdentity(origId); 16311 } 16312 16313 return true; 16314 } 16315 16316 /** 16317 * Report errors that occur while attempting to start Instrumentation. Always writes the 16318 * error to the logs, but if somebody is watching, send the report there too. This enables 16319 * the "am" command to report errors with more information. 16320 * 16321 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16322 * @param cn The component name of the instrumentation. 16323 * @param report The error report. 16324 */ 16325 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16326 ComponentName cn, String report) { 16327 Slog.w(TAG, report); 16328 try { 16329 if (watcher != null) { 16330 Bundle results = new Bundle(); 16331 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16332 results.putString("Error", report); 16333 watcher.instrumentationStatus(cn, -1, results); 16334 } 16335 } catch (RemoteException e) { 16336 Slog.w(TAG, e); 16337 } 16338 } 16339 16340 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16341 if (app.instrumentationWatcher != null) { 16342 try { 16343 // NOTE: IInstrumentationWatcher *must* be oneway here 16344 app.instrumentationWatcher.instrumentationFinished( 16345 app.instrumentationClass, 16346 resultCode, 16347 results); 16348 } catch (RemoteException e) { 16349 } 16350 } 16351 if (app.instrumentationUiAutomationConnection != null) { 16352 try { 16353 app.instrumentationUiAutomationConnection.shutdown(); 16354 } catch (RemoteException re) { 16355 /* ignore */ 16356 } 16357 // Only a UiAutomation can set this flag and now that 16358 // it is finished we make sure it is reset to its default. 16359 mUserIsMonkey = false; 16360 } 16361 app.instrumentationWatcher = null; 16362 app.instrumentationUiAutomationConnection = null; 16363 app.instrumentationClass = null; 16364 app.instrumentationInfo = null; 16365 app.instrumentationProfileFile = null; 16366 app.instrumentationArguments = null; 16367 16368 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16369 "finished inst"); 16370 } 16371 16372 public void finishInstrumentation(IApplicationThread target, 16373 int resultCode, Bundle results) { 16374 int userId = UserHandle.getCallingUserId(); 16375 // Refuse possible leaked file descriptors 16376 if (results != null && results.hasFileDescriptors()) { 16377 throw new IllegalArgumentException("File descriptors passed in Intent"); 16378 } 16379 16380 synchronized(this) { 16381 ProcessRecord app = getRecordForAppLocked(target); 16382 if (app == null) { 16383 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16384 return; 16385 } 16386 final long origId = Binder.clearCallingIdentity(); 16387 finishInstrumentationLocked(app, resultCode, results); 16388 Binder.restoreCallingIdentity(origId); 16389 } 16390 } 16391 16392 // ========================================================= 16393 // CONFIGURATION 16394 // ========================================================= 16395 16396 public ConfigurationInfo getDeviceConfigurationInfo() { 16397 ConfigurationInfo config = new ConfigurationInfo(); 16398 synchronized (this) { 16399 config.reqTouchScreen = mConfiguration.touchscreen; 16400 config.reqKeyboardType = mConfiguration.keyboard; 16401 config.reqNavigation = mConfiguration.navigation; 16402 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16403 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16404 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16405 } 16406 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16407 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16408 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16409 } 16410 config.reqGlEsVersion = GL_ES_VERSION; 16411 } 16412 return config; 16413 } 16414 16415 ActivityStack getFocusedStack() { 16416 return mStackSupervisor.getFocusedStack(); 16417 } 16418 16419 public Configuration getConfiguration() { 16420 Configuration ci; 16421 synchronized(this) { 16422 ci = new Configuration(mConfiguration); 16423 } 16424 return ci; 16425 } 16426 16427 public void updatePersistentConfiguration(Configuration values) { 16428 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16429 "updateConfiguration()"); 16430 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16431 "updateConfiguration()"); 16432 if (values == null) { 16433 throw new NullPointerException("Configuration must not be null"); 16434 } 16435 16436 synchronized(this) { 16437 final long origId = Binder.clearCallingIdentity(); 16438 updateConfigurationLocked(values, null, true, false); 16439 Binder.restoreCallingIdentity(origId); 16440 } 16441 } 16442 16443 public void updateConfiguration(Configuration values) { 16444 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16445 "updateConfiguration()"); 16446 16447 synchronized(this) { 16448 if (values == null && mWindowManager != null) { 16449 // sentinel: fetch the current configuration from the window manager 16450 values = mWindowManager.computeNewConfiguration(); 16451 } 16452 16453 if (mWindowManager != null) { 16454 mProcessList.applyDisplaySize(mWindowManager); 16455 } 16456 16457 final long origId = Binder.clearCallingIdentity(); 16458 if (values != null) { 16459 Settings.System.clearConfiguration(values); 16460 } 16461 updateConfigurationLocked(values, null, false, false); 16462 Binder.restoreCallingIdentity(origId); 16463 } 16464 } 16465 16466 /** 16467 * Do either or both things: (1) change the current configuration, and (2) 16468 * make sure the given activity is running with the (now) current 16469 * configuration. Returns true if the activity has been left running, or 16470 * false if <var>starting</var> is being destroyed to match the new 16471 * configuration. 16472 * @param persistent TODO 16473 */ 16474 boolean updateConfigurationLocked(Configuration values, 16475 ActivityRecord starting, boolean persistent, boolean initLocale) { 16476 int changes = 0; 16477 16478 if (values != null) { 16479 Configuration newConfig = new Configuration(mConfiguration); 16480 changes = newConfig.updateFrom(values); 16481 if (changes != 0) { 16482 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16483 Slog.i(TAG, "Updating configuration to: " + values); 16484 } 16485 16486 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16487 16488 if (values.locale != null && !initLocale) { 16489 saveLocaleLocked(values.locale, 16490 !values.locale.equals(mConfiguration.locale), 16491 values.userSetLocale); 16492 } 16493 16494 mConfigurationSeq++; 16495 if (mConfigurationSeq <= 0) { 16496 mConfigurationSeq = 1; 16497 } 16498 newConfig.seq = mConfigurationSeq; 16499 mConfiguration = newConfig; 16500 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16501 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16502 //mUsageStatsService.noteStartConfig(newConfig); 16503 16504 final Configuration configCopy = new Configuration(mConfiguration); 16505 16506 // TODO: If our config changes, should we auto dismiss any currently 16507 // showing dialogs? 16508 mShowDialogs = shouldShowDialogs(newConfig); 16509 16510 AttributeCache ac = AttributeCache.instance(); 16511 if (ac != null) { 16512 ac.updateConfiguration(configCopy); 16513 } 16514 16515 // Make sure all resources in our process are updated 16516 // right now, so that anyone who is going to retrieve 16517 // resource values after we return will be sure to get 16518 // the new ones. This is especially important during 16519 // boot, where the first config change needs to guarantee 16520 // all resources have that config before following boot 16521 // code is executed. 16522 mSystemThread.applyConfigurationToResources(configCopy); 16523 16524 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16525 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16526 msg.obj = new Configuration(configCopy); 16527 mHandler.sendMessage(msg); 16528 } 16529 16530 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16531 ProcessRecord app = mLruProcesses.get(i); 16532 try { 16533 if (app.thread != null) { 16534 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16535 + app.processName + " new config " + mConfiguration); 16536 app.thread.scheduleConfigurationChanged(configCopy); 16537 } 16538 } catch (Exception e) { 16539 } 16540 } 16541 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16542 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16543 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16544 | Intent.FLAG_RECEIVER_FOREGROUND); 16545 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16546 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16547 Process.SYSTEM_UID, UserHandle.USER_ALL); 16548 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16549 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16550 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16551 broadcastIntentLocked(null, null, intent, 16552 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16553 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16554 } 16555 } 16556 } 16557 16558 boolean kept = true; 16559 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16560 // mainStack is null during startup. 16561 if (mainStack != null) { 16562 if (changes != 0 && starting == null) { 16563 // If the configuration changed, and the caller is not already 16564 // in the process of starting an activity, then find the top 16565 // activity to check if its configuration needs to change. 16566 starting = mainStack.topRunningActivityLocked(null); 16567 } 16568 16569 if (starting != null) { 16570 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16571 // And we need to make sure at this point that all other activities 16572 // are made visible with the correct configuration. 16573 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16574 } 16575 } 16576 16577 if (values != null && mWindowManager != null) { 16578 mWindowManager.setNewConfiguration(mConfiguration); 16579 } 16580 16581 return kept; 16582 } 16583 16584 /** 16585 * Decide based on the configuration whether we should shouw the ANR, 16586 * crash, etc dialogs. The idea is that if there is no affordnace to 16587 * press the on-screen buttons, we shouldn't show the dialog. 16588 * 16589 * A thought: SystemUI might also want to get told about this, the Power 16590 * dialog / global actions also might want different behaviors. 16591 */ 16592 private static final boolean shouldShowDialogs(Configuration config) { 16593 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16594 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16595 } 16596 16597 /** 16598 * Save the locale. You must be inside a synchronized (this) block. 16599 */ 16600 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16601 if(isDiff) { 16602 SystemProperties.set("user.language", l.getLanguage()); 16603 SystemProperties.set("user.region", l.getCountry()); 16604 } 16605 16606 if(isPersist) { 16607 SystemProperties.set("persist.sys.language", l.getLanguage()); 16608 SystemProperties.set("persist.sys.country", l.getCountry()); 16609 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16610 16611 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16612 } 16613 } 16614 16615 @Override 16616 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16617 synchronized (this) { 16618 ActivityRecord srec = ActivityRecord.forToken(token); 16619 if (srec.task != null && srec.task.stack != null) { 16620 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16621 } 16622 } 16623 return false; 16624 } 16625 16626 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16627 Intent resultData) { 16628 16629 synchronized (this) { 16630 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16631 if (stack != null) { 16632 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16633 } 16634 return false; 16635 } 16636 } 16637 16638 public int getLaunchedFromUid(IBinder activityToken) { 16639 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16640 if (srec == null) { 16641 return -1; 16642 } 16643 return srec.launchedFromUid; 16644 } 16645 16646 public String getLaunchedFromPackage(IBinder activityToken) { 16647 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16648 if (srec == null) { 16649 return null; 16650 } 16651 return srec.launchedFromPackage; 16652 } 16653 16654 // ========================================================= 16655 // LIFETIME MANAGEMENT 16656 // ========================================================= 16657 16658 // Returns which broadcast queue the app is the current [or imminent] receiver 16659 // on, or 'null' if the app is not an active broadcast recipient. 16660 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16661 BroadcastRecord r = app.curReceiver; 16662 if (r != null) { 16663 return r.queue; 16664 } 16665 16666 // It's not the current receiver, but it might be starting up to become one 16667 synchronized (this) { 16668 for (BroadcastQueue queue : mBroadcastQueues) { 16669 r = queue.mPendingBroadcast; 16670 if (r != null && r.curApp == app) { 16671 // found it; report which queue it's in 16672 return queue; 16673 } 16674 } 16675 } 16676 16677 return null; 16678 } 16679 16680 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16681 boolean doingAll, long now) { 16682 if (mAdjSeq == app.adjSeq) { 16683 // This adjustment has already been computed. 16684 return app.curRawAdj; 16685 } 16686 16687 if (app.thread == null) { 16688 app.adjSeq = mAdjSeq; 16689 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16690 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16691 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16692 } 16693 16694 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16695 app.adjSource = null; 16696 app.adjTarget = null; 16697 app.empty = false; 16698 app.cached = false; 16699 16700 final int activitiesSize = app.activities.size(); 16701 16702 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16703 // The max adjustment doesn't allow this app to be anything 16704 // below foreground, so it is not worth doing work for it. 16705 app.adjType = "fixed"; 16706 app.adjSeq = mAdjSeq; 16707 app.curRawAdj = app.maxAdj; 16708 app.foregroundActivities = false; 16709 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16710 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16711 // System processes can do UI, and when they do we want to have 16712 // them trim their memory after the user leaves the UI. To 16713 // facilitate this, here we need to determine whether or not it 16714 // is currently showing UI. 16715 app.systemNoUi = true; 16716 if (app == TOP_APP) { 16717 app.systemNoUi = false; 16718 } else if (activitiesSize > 0) { 16719 for (int j = 0; j < activitiesSize; j++) { 16720 final ActivityRecord r = app.activities.get(j); 16721 if (r.visible) { 16722 app.systemNoUi = false; 16723 } 16724 } 16725 } 16726 if (!app.systemNoUi) { 16727 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16728 } 16729 return (app.curAdj=app.maxAdj); 16730 } 16731 16732 app.systemNoUi = false; 16733 16734 // Determine the importance of the process, starting with most 16735 // important to least, and assign an appropriate OOM adjustment. 16736 int adj; 16737 int schedGroup; 16738 int procState; 16739 boolean foregroundActivities = false; 16740 BroadcastQueue queue; 16741 if (app == TOP_APP) { 16742 // The last app on the list is the foreground app. 16743 adj = ProcessList.FOREGROUND_APP_ADJ; 16744 schedGroup = Process.THREAD_GROUP_DEFAULT; 16745 app.adjType = "top-activity"; 16746 foregroundActivities = true; 16747 procState = ActivityManager.PROCESS_STATE_TOP; 16748 } else if (app.instrumentationClass != null) { 16749 // Don't want to kill running instrumentation. 16750 adj = ProcessList.FOREGROUND_APP_ADJ; 16751 schedGroup = Process.THREAD_GROUP_DEFAULT; 16752 app.adjType = "instrumentation"; 16753 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16754 } else if ((queue = isReceivingBroadcast(app)) != null) { 16755 // An app that is currently receiving a broadcast also 16756 // counts as being in the foreground for OOM killer purposes. 16757 // It's placed in a sched group based on the nature of the 16758 // broadcast as reflected by which queue it's active in. 16759 adj = ProcessList.FOREGROUND_APP_ADJ; 16760 schedGroup = (queue == mFgBroadcastQueue) 16761 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16762 app.adjType = "broadcast"; 16763 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16764 } else if (app.executingServices.size() > 0) { 16765 // An app that is currently executing a service callback also 16766 // counts as being in the foreground. 16767 adj = ProcessList.FOREGROUND_APP_ADJ; 16768 schedGroup = app.execServicesFg ? 16769 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16770 app.adjType = "exec-service"; 16771 procState = ActivityManager.PROCESS_STATE_SERVICE; 16772 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16773 } else { 16774 // As far as we know the process is empty. We may change our mind later. 16775 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16776 // At this point we don't actually know the adjustment. Use the cached adj 16777 // value that the caller wants us to. 16778 adj = cachedAdj; 16779 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16780 app.cached = true; 16781 app.empty = true; 16782 app.adjType = "cch-empty"; 16783 } 16784 16785 // Examine all activities if not already foreground. 16786 if (!foregroundActivities && activitiesSize > 0) { 16787 for (int j = 0; j < activitiesSize; j++) { 16788 final ActivityRecord r = app.activities.get(j); 16789 if (r.app != app) { 16790 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16791 + app + "?!?"); 16792 continue; 16793 } 16794 if (r.visible) { 16795 // App has a visible activity; only upgrade adjustment. 16796 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16797 adj = ProcessList.VISIBLE_APP_ADJ; 16798 app.adjType = "visible"; 16799 } 16800 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16801 procState = ActivityManager.PROCESS_STATE_TOP; 16802 } 16803 schedGroup = Process.THREAD_GROUP_DEFAULT; 16804 app.cached = false; 16805 app.empty = false; 16806 foregroundActivities = true; 16807 break; 16808 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16809 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16810 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16811 app.adjType = "pausing"; 16812 } 16813 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16814 procState = ActivityManager.PROCESS_STATE_TOP; 16815 } 16816 schedGroup = Process.THREAD_GROUP_DEFAULT; 16817 app.cached = false; 16818 app.empty = false; 16819 foregroundActivities = true; 16820 } else if (r.state == ActivityState.STOPPING) { 16821 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16822 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16823 app.adjType = "stopping"; 16824 } 16825 // For the process state, we will at this point consider the 16826 // process to be cached. It will be cached either as an activity 16827 // or empty depending on whether the activity is finishing. We do 16828 // this so that we can treat the process as cached for purposes of 16829 // memory trimming (determing current memory level, trim command to 16830 // send to process) since there can be an arbitrary number of stopping 16831 // processes and they should soon all go into the cached state. 16832 if (!r.finishing) { 16833 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16834 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16835 } 16836 } 16837 app.cached = false; 16838 app.empty = false; 16839 foregroundActivities = true; 16840 } else { 16841 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16842 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16843 app.adjType = "cch-act"; 16844 } 16845 } 16846 } 16847 } 16848 16849 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16850 if (app.foregroundServices) { 16851 // The user is aware of this app, so make it visible. 16852 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16853 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16854 app.cached = false; 16855 app.adjType = "fg-service"; 16856 schedGroup = Process.THREAD_GROUP_DEFAULT; 16857 } else if (app.forcingToForeground != null) { 16858 // The user is aware of this app, so make it visible. 16859 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16860 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16861 app.cached = false; 16862 app.adjType = "force-fg"; 16863 app.adjSource = app.forcingToForeground; 16864 schedGroup = Process.THREAD_GROUP_DEFAULT; 16865 } 16866 } 16867 16868 if (app == mHeavyWeightProcess) { 16869 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16870 // We don't want to kill the current heavy-weight process. 16871 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16872 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16873 app.cached = false; 16874 app.adjType = "heavy"; 16875 } 16876 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16877 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16878 } 16879 } 16880 16881 if (app == mHomeProcess) { 16882 if (adj > ProcessList.HOME_APP_ADJ) { 16883 // This process is hosting what we currently consider to be the 16884 // home app, so we don't want to let it go into the background. 16885 adj = ProcessList.HOME_APP_ADJ; 16886 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16887 app.cached = false; 16888 app.adjType = "home"; 16889 } 16890 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16891 procState = ActivityManager.PROCESS_STATE_HOME; 16892 } 16893 } 16894 16895 if (app == mPreviousProcess && app.activities.size() > 0) { 16896 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16897 // This was the previous process that showed UI to the user. 16898 // We want to try to keep it around more aggressively, to give 16899 // a good experience around switching between two apps. 16900 adj = ProcessList.PREVIOUS_APP_ADJ; 16901 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16902 app.cached = false; 16903 app.adjType = "previous"; 16904 } 16905 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16906 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16907 } 16908 } 16909 16910 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16911 + " reason=" + app.adjType); 16912 16913 // By default, we use the computed adjustment. It may be changed if 16914 // there are applications dependent on our services or providers, but 16915 // this gives us a baseline and makes sure we don't get into an 16916 // infinite recursion. 16917 app.adjSeq = mAdjSeq; 16918 app.curRawAdj = adj; 16919 app.hasStartedServices = false; 16920 16921 if (mBackupTarget != null && app == mBackupTarget.app) { 16922 // If possible we want to avoid killing apps while they're being backed up 16923 if (adj > ProcessList.BACKUP_APP_ADJ) { 16924 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16925 adj = ProcessList.BACKUP_APP_ADJ; 16926 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16927 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16928 } 16929 app.adjType = "backup"; 16930 app.cached = false; 16931 } 16932 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16933 procState = ActivityManager.PROCESS_STATE_BACKUP; 16934 } 16935 } 16936 16937 boolean mayBeTop = false; 16938 16939 for (int is = app.services.size()-1; 16940 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16941 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16942 || procState > ActivityManager.PROCESS_STATE_TOP); 16943 is--) { 16944 ServiceRecord s = app.services.valueAt(is); 16945 if (s.startRequested) { 16946 app.hasStartedServices = true; 16947 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16948 procState = ActivityManager.PROCESS_STATE_SERVICE; 16949 } 16950 if (app.hasShownUi && app != mHomeProcess) { 16951 // If this process has shown some UI, let it immediately 16952 // go to the LRU list because it may be pretty heavy with 16953 // UI stuff. We'll tag it with a label just to help 16954 // debug and understand what is going on. 16955 if (adj > ProcessList.SERVICE_ADJ) { 16956 app.adjType = "cch-started-ui-services"; 16957 } 16958 } else { 16959 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16960 // This service has seen some activity within 16961 // recent memory, so we will keep its process ahead 16962 // of the background processes. 16963 if (adj > ProcessList.SERVICE_ADJ) { 16964 adj = ProcessList.SERVICE_ADJ; 16965 app.adjType = "started-services"; 16966 app.cached = false; 16967 } 16968 } 16969 // If we have let the service slide into the background 16970 // state, still have some text describing what it is doing 16971 // even though the service no longer has an impact. 16972 if (adj > ProcessList.SERVICE_ADJ) { 16973 app.adjType = "cch-started-services"; 16974 } 16975 } 16976 } 16977 for (int conni = s.connections.size()-1; 16978 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16979 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16980 || procState > ActivityManager.PROCESS_STATE_TOP); 16981 conni--) { 16982 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16983 for (int i = 0; 16984 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16985 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16986 || procState > ActivityManager.PROCESS_STATE_TOP); 16987 i++) { 16988 // XXX should compute this based on the max of 16989 // all connected clients. 16990 ConnectionRecord cr = clist.get(i); 16991 if (cr.binding.client == app) { 16992 // Binding to ourself is not interesting. 16993 continue; 16994 } 16995 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16996 ProcessRecord client = cr.binding.client; 16997 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16998 TOP_APP, doingAll, now); 16999 int clientProcState = client.curProcState; 17000 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17001 // If the other app is cached for any reason, for purposes here 17002 // we are going to consider it empty. The specific cached state 17003 // doesn't propagate except under certain conditions. 17004 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17005 } 17006 String adjType = null; 17007 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17008 // Not doing bind OOM management, so treat 17009 // this guy more like a started service. 17010 if (app.hasShownUi && app != mHomeProcess) { 17011 // If this process has shown some UI, let it immediately 17012 // go to the LRU list because it may be pretty heavy with 17013 // UI stuff. We'll tag it with a label just to help 17014 // debug and understand what is going on. 17015 if (adj > clientAdj) { 17016 adjType = "cch-bound-ui-services"; 17017 } 17018 app.cached = false; 17019 clientAdj = adj; 17020 clientProcState = procState; 17021 } else { 17022 if (now >= (s.lastActivity 17023 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17024 // This service has not seen activity within 17025 // recent memory, so allow it to drop to the 17026 // LRU list if there is no other reason to keep 17027 // it around. We'll also tag it with a label just 17028 // to help debug and undertand what is going on. 17029 if (adj > clientAdj) { 17030 adjType = "cch-bound-services"; 17031 } 17032 clientAdj = adj; 17033 } 17034 } 17035 } 17036 if (adj > clientAdj) { 17037 // If this process has recently shown UI, and 17038 // the process that is binding to it is less 17039 // important than being visible, then we don't 17040 // care about the binding as much as we care 17041 // about letting this process get into the LRU 17042 // list to be killed and restarted if needed for 17043 // memory. 17044 if (app.hasShownUi && app != mHomeProcess 17045 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17046 adjType = "cch-bound-ui-services"; 17047 } else { 17048 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17049 |Context.BIND_IMPORTANT)) != 0) { 17050 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17051 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17052 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17053 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17054 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17055 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17056 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17057 adj = clientAdj; 17058 } else { 17059 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17060 adj = ProcessList.VISIBLE_APP_ADJ; 17061 } 17062 } 17063 if (!client.cached) { 17064 app.cached = false; 17065 } 17066 adjType = "service"; 17067 } 17068 } 17069 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17070 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17071 schedGroup = Process.THREAD_GROUP_DEFAULT; 17072 } 17073 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17074 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17075 // Special handling of clients who are in the top state. 17076 // We *may* want to consider this process to be in the 17077 // top state as well, but only if there is not another 17078 // reason for it to be running. Being on the top is a 17079 // special state, meaning you are specifically running 17080 // for the current top app. If the process is already 17081 // running in the background for some other reason, it 17082 // is more important to continue considering it to be 17083 // in the background state. 17084 mayBeTop = true; 17085 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17086 } else { 17087 // Special handling for above-top states (persistent 17088 // processes). These should not bring the current process 17089 // into the top state, since they are not on top. Instead 17090 // give them the best state after that. 17091 clientProcState = 17092 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17093 } 17094 } 17095 } else { 17096 if (clientProcState < 17097 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17098 clientProcState = 17099 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17100 } 17101 } 17102 if (procState > clientProcState) { 17103 procState = clientProcState; 17104 } 17105 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17106 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17107 app.pendingUiClean = true; 17108 } 17109 if (adjType != null) { 17110 app.adjType = adjType; 17111 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17112 .REASON_SERVICE_IN_USE; 17113 app.adjSource = cr.binding.client; 17114 app.adjSourceProcState = clientProcState; 17115 app.adjTarget = s.name; 17116 } 17117 } 17118 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17119 app.treatLikeActivity = true; 17120 } 17121 final ActivityRecord a = cr.activity; 17122 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17123 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17124 (a.visible || a.state == ActivityState.RESUMED 17125 || a.state == ActivityState.PAUSING)) { 17126 adj = ProcessList.FOREGROUND_APP_ADJ; 17127 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17128 schedGroup = Process.THREAD_GROUP_DEFAULT; 17129 } 17130 app.cached = false; 17131 app.adjType = "service"; 17132 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17133 .REASON_SERVICE_IN_USE; 17134 app.adjSource = a; 17135 app.adjSourceProcState = procState; 17136 app.adjTarget = s.name; 17137 } 17138 } 17139 } 17140 } 17141 } 17142 17143 for (int provi = app.pubProviders.size()-1; 17144 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17145 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17146 || procState > ActivityManager.PROCESS_STATE_TOP); 17147 provi--) { 17148 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17149 for (int i = cpr.connections.size()-1; 17150 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17151 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17152 || procState > ActivityManager.PROCESS_STATE_TOP); 17153 i--) { 17154 ContentProviderConnection conn = cpr.connections.get(i); 17155 ProcessRecord client = conn.client; 17156 if (client == app) { 17157 // Being our own client is not interesting. 17158 continue; 17159 } 17160 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17161 int clientProcState = client.curProcState; 17162 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17163 // If the other app is cached for any reason, for purposes here 17164 // we are going to consider it empty. 17165 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17166 } 17167 if (adj > clientAdj) { 17168 if (app.hasShownUi && app != mHomeProcess 17169 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17170 app.adjType = "cch-ui-provider"; 17171 } else { 17172 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17173 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17174 app.adjType = "provider"; 17175 } 17176 app.cached &= client.cached; 17177 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17178 .REASON_PROVIDER_IN_USE; 17179 app.adjSource = client; 17180 app.adjSourceProcState = clientProcState; 17181 app.adjTarget = cpr.name; 17182 } 17183 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17184 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17185 // Special handling of clients who are in the top state. 17186 // We *may* want to consider this process to be in the 17187 // top state as well, but only if there is not another 17188 // reason for it to be running. Being on the top is a 17189 // special state, meaning you are specifically running 17190 // for the current top app. If the process is already 17191 // running in the background for some other reason, it 17192 // is more important to continue considering it to be 17193 // in the background state. 17194 mayBeTop = true; 17195 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17196 } else { 17197 // Special handling for above-top states (persistent 17198 // processes). These should not bring the current process 17199 // into the top state, since they are not on top. Instead 17200 // give them the best state after that. 17201 clientProcState = 17202 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17203 } 17204 } 17205 if (procState > clientProcState) { 17206 procState = clientProcState; 17207 } 17208 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17209 schedGroup = Process.THREAD_GROUP_DEFAULT; 17210 } 17211 } 17212 // If the provider has external (non-framework) process 17213 // dependencies, ensure that its adjustment is at least 17214 // FOREGROUND_APP_ADJ. 17215 if (cpr.hasExternalProcessHandles()) { 17216 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17217 adj = ProcessList.FOREGROUND_APP_ADJ; 17218 schedGroup = Process.THREAD_GROUP_DEFAULT; 17219 app.cached = false; 17220 app.adjType = "provider"; 17221 app.adjTarget = cpr.name; 17222 } 17223 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17224 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17225 } 17226 } 17227 } 17228 17229 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17230 // A client of one of our services or providers is in the top state. We 17231 // *may* want to be in the top state, but not if we are already running in 17232 // the background for some other reason. For the decision here, we are going 17233 // to pick out a few specific states that we want to remain in when a client 17234 // is top (states that tend to be longer-term) and otherwise allow it to go 17235 // to the top state. 17236 switch (procState) { 17237 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17238 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17239 case ActivityManager.PROCESS_STATE_SERVICE: 17240 // These all are longer-term states, so pull them up to the top 17241 // of the background states, but not all the way to the top state. 17242 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17243 break; 17244 default: 17245 // Otherwise, top is a better choice, so take it. 17246 procState = ActivityManager.PROCESS_STATE_TOP; 17247 break; 17248 } 17249 } 17250 17251 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17252 if (app.hasClientActivities) { 17253 // This is a cached process, but with client activities. Mark it so. 17254 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17255 app.adjType = "cch-client-act"; 17256 } else if (app.treatLikeActivity) { 17257 // This is a cached process, but somebody wants us to treat it like it has 17258 // an activity, okay! 17259 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17260 app.adjType = "cch-as-act"; 17261 } 17262 } 17263 17264 if (adj == ProcessList.SERVICE_ADJ) { 17265 if (doingAll) { 17266 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17267 mNewNumServiceProcs++; 17268 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17269 if (!app.serviceb) { 17270 // This service isn't far enough down on the LRU list to 17271 // normally be a B service, but if we are low on RAM and it 17272 // is large we want to force it down since we would prefer to 17273 // keep launcher over it. 17274 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17275 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17276 app.serviceHighRam = true; 17277 app.serviceb = true; 17278 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17279 } else { 17280 mNewNumAServiceProcs++; 17281 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17282 } 17283 } else { 17284 app.serviceHighRam = false; 17285 } 17286 } 17287 if (app.serviceb) { 17288 adj = ProcessList.SERVICE_B_ADJ; 17289 } 17290 } 17291 17292 app.curRawAdj = adj; 17293 17294 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17295 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17296 if (adj > app.maxAdj) { 17297 adj = app.maxAdj; 17298 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17299 schedGroup = Process.THREAD_GROUP_DEFAULT; 17300 } 17301 } 17302 17303 // Do final modification to adj. Everything we do between here and applying 17304 // the final setAdj must be done in this function, because we will also use 17305 // it when computing the final cached adj later. Note that we don't need to 17306 // worry about this for max adj above, since max adj will always be used to 17307 // keep it out of the cached vaues. 17308 app.curAdj = app.modifyRawOomAdj(adj); 17309 app.curSchedGroup = schedGroup; 17310 app.curProcState = procState; 17311 app.foregroundActivities = foregroundActivities; 17312 17313 return app.curRawAdj; 17314 } 17315 17316 /** 17317 * Schedule PSS collection of a process. 17318 */ 17319 void requestPssLocked(ProcessRecord proc, int procState) { 17320 if (mPendingPssProcesses.contains(proc)) { 17321 return; 17322 } 17323 if (mPendingPssProcesses.size() == 0) { 17324 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17325 } 17326 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17327 proc.pssProcState = procState; 17328 mPendingPssProcesses.add(proc); 17329 } 17330 17331 /** 17332 * Schedule PSS collection of all processes. 17333 */ 17334 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17335 if (!always) { 17336 if (now < (mLastFullPssTime + 17337 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17338 return; 17339 } 17340 } 17341 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17342 mLastFullPssTime = now; 17343 mFullPssPending = true; 17344 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17345 mPendingPssProcesses.clear(); 17346 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17347 ProcessRecord app = mLruProcesses.get(i); 17348 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17349 app.pssProcState = app.setProcState; 17350 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17351 isSleeping(), now); 17352 mPendingPssProcesses.add(app); 17353 } 17354 } 17355 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17356 } 17357 17358 /** 17359 * Ask a given process to GC right now. 17360 */ 17361 final void performAppGcLocked(ProcessRecord app) { 17362 try { 17363 app.lastRequestedGc = SystemClock.uptimeMillis(); 17364 if (app.thread != null) { 17365 if (app.reportLowMemory) { 17366 app.reportLowMemory = false; 17367 app.thread.scheduleLowMemory(); 17368 } else { 17369 app.thread.processInBackground(); 17370 } 17371 } 17372 } catch (Exception e) { 17373 // whatever. 17374 } 17375 } 17376 17377 /** 17378 * Returns true if things are idle enough to perform GCs. 17379 */ 17380 private final boolean canGcNowLocked() { 17381 boolean processingBroadcasts = false; 17382 for (BroadcastQueue q : mBroadcastQueues) { 17383 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17384 processingBroadcasts = true; 17385 } 17386 } 17387 return !processingBroadcasts 17388 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17389 } 17390 17391 /** 17392 * Perform GCs on all processes that are waiting for it, but only 17393 * if things are idle. 17394 */ 17395 final void performAppGcsLocked() { 17396 final int N = mProcessesToGc.size(); 17397 if (N <= 0) { 17398 return; 17399 } 17400 if (canGcNowLocked()) { 17401 while (mProcessesToGc.size() > 0) { 17402 ProcessRecord proc = mProcessesToGc.remove(0); 17403 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17404 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17405 <= SystemClock.uptimeMillis()) { 17406 // To avoid spamming the system, we will GC processes one 17407 // at a time, waiting a few seconds between each. 17408 performAppGcLocked(proc); 17409 scheduleAppGcsLocked(); 17410 return; 17411 } else { 17412 // It hasn't been long enough since we last GCed this 17413 // process... put it in the list to wait for its time. 17414 addProcessToGcListLocked(proc); 17415 break; 17416 } 17417 } 17418 } 17419 17420 scheduleAppGcsLocked(); 17421 } 17422 } 17423 17424 /** 17425 * If all looks good, perform GCs on all processes waiting for them. 17426 */ 17427 final void performAppGcsIfAppropriateLocked() { 17428 if (canGcNowLocked()) { 17429 performAppGcsLocked(); 17430 return; 17431 } 17432 // Still not idle, wait some more. 17433 scheduleAppGcsLocked(); 17434 } 17435 17436 /** 17437 * Schedule the execution of all pending app GCs. 17438 */ 17439 final void scheduleAppGcsLocked() { 17440 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17441 17442 if (mProcessesToGc.size() > 0) { 17443 // Schedule a GC for the time to the next process. 17444 ProcessRecord proc = mProcessesToGc.get(0); 17445 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17446 17447 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17448 long now = SystemClock.uptimeMillis(); 17449 if (when < (now+GC_TIMEOUT)) { 17450 when = now + GC_TIMEOUT; 17451 } 17452 mHandler.sendMessageAtTime(msg, when); 17453 } 17454 } 17455 17456 /** 17457 * Add a process to the array of processes waiting to be GCed. Keeps the 17458 * list in sorted order by the last GC time. The process can't already be 17459 * on the list. 17460 */ 17461 final void addProcessToGcListLocked(ProcessRecord proc) { 17462 boolean added = false; 17463 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17464 if (mProcessesToGc.get(i).lastRequestedGc < 17465 proc.lastRequestedGc) { 17466 added = true; 17467 mProcessesToGc.add(i+1, proc); 17468 break; 17469 } 17470 } 17471 if (!added) { 17472 mProcessesToGc.add(0, proc); 17473 } 17474 } 17475 17476 /** 17477 * Set up to ask a process to GC itself. This will either do it 17478 * immediately, or put it on the list of processes to gc the next 17479 * time things are idle. 17480 */ 17481 final void scheduleAppGcLocked(ProcessRecord app) { 17482 long now = SystemClock.uptimeMillis(); 17483 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17484 return; 17485 } 17486 if (!mProcessesToGc.contains(app)) { 17487 addProcessToGcListLocked(app); 17488 scheduleAppGcsLocked(); 17489 } 17490 } 17491 17492 final void checkExcessivePowerUsageLocked(boolean doKills) { 17493 updateCpuStatsNow(); 17494 17495 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17496 boolean doWakeKills = doKills; 17497 boolean doCpuKills = doKills; 17498 if (mLastPowerCheckRealtime == 0) { 17499 doWakeKills = false; 17500 } 17501 if (mLastPowerCheckUptime == 0) { 17502 doCpuKills = false; 17503 } 17504 if (stats.isScreenOn()) { 17505 doWakeKills = false; 17506 } 17507 final long curRealtime = SystemClock.elapsedRealtime(); 17508 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17509 final long curUptime = SystemClock.uptimeMillis(); 17510 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17511 mLastPowerCheckRealtime = curRealtime; 17512 mLastPowerCheckUptime = curUptime; 17513 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17514 doWakeKills = false; 17515 } 17516 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17517 doCpuKills = false; 17518 } 17519 int i = mLruProcesses.size(); 17520 while (i > 0) { 17521 i--; 17522 ProcessRecord app = mLruProcesses.get(i); 17523 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17524 long wtime; 17525 synchronized (stats) { 17526 wtime = stats.getProcessWakeTime(app.info.uid, 17527 app.pid, curRealtime); 17528 } 17529 long wtimeUsed = wtime - app.lastWakeTime; 17530 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17531 if (DEBUG_POWER) { 17532 StringBuilder sb = new StringBuilder(128); 17533 sb.append("Wake for "); 17534 app.toShortString(sb); 17535 sb.append(": over "); 17536 TimeUtils.formatDuration(realtimeSince, sb); 17537 sb.append(" used "); 17538 TimeUtils.formatDuration(wtimeUsed, sb); 17539 sb.append(" ("); 17540 sb.append((wtimeUsed*100)/realtimeSince); 17541 sb.append("%)"); 17542 Slog.i(TAG, sb.toString()); 17543 sb.setLength(0); 17544 sb.append("CPU for "); 17545 app.toShortString(sb); 17546 sb.append(": over "); 17547 TimeUtils.formatDuration(uptimeSince, sb); 17548 sb.append(" used "); 17549 TimeUtils.formatDuration(cputimeUsed, sb); 17550 sb.append(" ("); 17551 sb.append((cputimeUsed*100)/uptimeSince); 17552 sb.append("%)"); 17553 Slog.i(TAG, sb.toString()); 17554 } 17555 // If a process has held a wake lock for more 17556 // than 50% of the time during this period, 17557 // that sounds bad. Kill! 17558 if (doWakeKills && realtimeSince > 0 17559 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17560 synchronized (stats) { 17561 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17562 realtimeSince, wtimeUsed); 17563 } 17564 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17565 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17566 } else if (doCpuKills && uptimeSince > 0 17567 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17568 synchronized (stats) { 17569 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17570 uptimeSince, cputimeUsed); 17571 } 17572 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17573 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17574 } else { 17575 app.lastWakeTime = wtime; 17576 app.lastCpuTime = app.curCpuTime; 17577 } 17578 } 17579 } 17580 } 17581 17582 private final boolean applyOomAdjLocked(ProcessRecord app, 17583 ProcessRecord TOP_APP, boolean doingAll, long now) { 17584 boolean success = true; 17585 17586 if (app.curRawAdj != app.setRawAdj) { 17587 app.setRawAdj = app.curRawAdj; 17588 } 17589 17590 int changes = 0; 17591 17592 if (app.curAdj != app.setAdj) { 17593 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17594 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17595 TAG, "Set " + app.pid + " " + app.processName + 17596 " adj " + app.curAdj + ": " + app.adjType); 17597 app.setAdj = app.curAdj; 17598 } 17599 17600 if (app.setSchedGroup != app.curSchedGroup) { 17601 app.setSchedGroup = app.curSchedGroup; 17602 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17603 "Setting process group of " + app.processName 17604 + " to " + app.curSchedGroup); 17605 if (app.waitingToKill != null && 17606 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17607 app.kill(app.waitingToKill, true); 17608 success = false; 17609 } else { 17610 if (true) { 17611 long oldId = Binder.clearCallingIdentity(); 17612 try { 17613 Process.setProcessGroup(app.pid, app.curSchedGroup); 17614 } catch (Exception e) { 17615 Slog.w(TAG, "Failed setting process group of " + app.pid 17616 + " to " + app.curSchedGroup); 17617 e.printStackTrace(); 17618 } finally { 17619 Binder.restoreCallingIdentity(oldId); 17620 } 17621 } else { 17622 if (app.thread != null) { 17623 try { 17624 app.thread.setSchedulingGroup(app.curSchedGroup); 17625 } catch (RemoteException e) { 17626 } 17627 } 17628 } 17629 Process.setSwappiness(app.pid, 17630 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17631 } 17632 } 17633 if (app.repForegroundActivities != app.foregroundActivities) { 17634 app.repForegroundActivities = app.foregroundActivities; 17635 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17636 } 17637 if (app.repProcState != app.curProcState) { 17638 app.repProcState = app.curProcState; 17639 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17640 if (app.thread != null) { 17641 try { 17642 if (false) { 17643 //RuntimeException h = new RuntimeException("here"); 17644 Slog.i(TAG, "Sending new process state " + app.repProcState 17645 + " to " + app /*, h*/); 17646 } 17647 app.thread.setProcessState(app.repProcState); 17648 } catch (RemoteException e) { 17649 } 17650 } 17651 } 17652 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17653 app.setProcState)) { 17654 app.lastStateTime = now; 17655 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17656 isSleeping(), now); 17657 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17658 + ProcessList.makeProcStateString(app.setProcState) + " to " 17659 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17660 + (app.nextPssTime-now) + ": " + app); 17661 } else { 17662 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17663 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17664 requestPssLocked(app, app.setProcState); 17665 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17666 isSleeping(), now); 17667 } else if (false && DEBUG_PSS) { 17668 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17669 } 17670 } 17671 if (app.setProcState != app.curProcState) { 17672 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17673 "Proc state change of " + app.processName 17674 + " to " + app.curProcState); 17675 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17676 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17677 if (setImportant && !curImportant) { 17678 // This app is no longer something we consider important enough to allow to 17679 // use arbitrary amounts of battery power. Note 17680 // its current wake lock time to later know to kill it if 17681 // it is not behaving well. 17682 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17683 synchronized (stats) { 17684 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17685 app.pid, SystemClock.elapsedRealtime()); 17686 } 17687 app.lastCpuTime = app.curCpuTime; 17688 17689 } 17690 app.setProcState = app.curProcState; 17691 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17692 app.notCachedSinceIdle = false; 17693 } 17694 if (!doingAll) { 17695 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17696 } else { 17697 app.procStateChanged = true; 17698 } 17699 } 17700 17701 if (changes != 0) { 17702 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17703 int i = mPendingProcessChanges.size()-1; 17704 ProcessChangeItem item = null; 17705 while (i >= 0) { 17706 item = mPendingProcessChanges.get(i); 17707 if (item.pid == app.pid) { 17708 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17709 break; 17710 } 17711 i--; 17712 } 17713 if (i < 0) { 17714 // No existing item in pending changes; need a new one. 17715 final int NA = mAvailProcessChanges.size(); 17716 if (NA > 0) { 17717 item = mAvailProcessChanges.remove(NA-1); 17718 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17719 } else { 17720 item = new ProcessChangeItem(); 17721 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17722 } 17723 item.changes = 0; 17724 item.pid = app.pid; 17725 item.uid = app.info.uid; 17726 if (mPendingProcessChanges.size() == 0) { 17727 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17728 "*** Enqueueing dispatch processes changed!"); 17729 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17730 } 17731 mPendingProcessChanges.add(item); 17732 } 17733 item.changes |= changes; 17734 item.processState = app.repProcState; 17735 item.foregroundActivities = app.repForegroundActivities; 17736 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17737 + Integer.toHexString(System.identityHashCode(item)) 17738 + " " + app.toShortString() + ": changes=" + item.changes 17739 + " procState=" + item.processState 17740 + " foreground=" + item.foregroundActivities 17741 + " type=" + app.adjType + " source=" + app.adjSource 17742 + " target=" + app.adjTarget); 17743 } 17744 17745 return success; 17746 } 17747 17748 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17749 if (proc.thread != null) { 17750 if (proc.baseProcessTracker != null) { 17751 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17752 } 17753 if (proc.repProcState >= 0) { 17754 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17755 proc.repProcState); 17756 } 17757 } 17758 } 17759 17760 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17761 ProcessRecord TOP_APP, boolean doingAll, long now) { 17762 if (app.thread == null) { 17763 return false; 17764 } 17765 17766 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17767 17768 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17769 } 17770 17771 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17772 boolean oomAdj) { 17773 if (isForeground != proc.foregroundServices) { 17774 proc.foregroundServices = isForeground; 17775 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17776 proc.info.uid); 17777 if (isForeground) { 17778 if (curProcs == null) { 17779 curProcs = new ArrayList<ProcessRecord>(); 17780 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17781 } 17782 if (!curProcs.contains(proc)) { 17783 curProcs.add(proc); 17784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17785 proc.info.packageName, proc.info.uid); 17786 } 17787 } else { 17788 if (curProcs != null) { 17789 if (curProcs.remove(proc)) { 17790 mBatteryStatsService.noteEvent( 17791 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17792 proc.info.packageName, proc.info.uid); 17793 if (curProcs.size() <= 0) { 17794 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17795 } 17796 } 17797 } 17798 } 17799 if (oomAdj) { 17800 updateOomAdjLocked(); 17801 } 17802 } 17803 } 17804 17805 private final ActivityRecord resumedAppLocked() { 17806 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17807 String pkg; 17808 int uid; 17809 if (act != null) { 17810 pkg = act.packageName; 17811 uid = act.info.applicationInfo.uid; 17812 } else { 17813 pkg = null; 17814 uid = -1; 17815 } 17816 // Has the UID or resumed package name changed? 17817 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17818 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17819 if (mCurResumedPackage != null) { 17820 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17821 mCurResumedPackage, mCurResumedUid); 17822 } 17823 mCurResumedPackage = pkg; 17824 mCurResumedUid = uid; 17825 if (mCurResumedPackage != null) { 17826 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17827 mCurResumedPackage, mCurResumedUid); 17828 } 17829 } 17830 return act; 17831 } 17832 17833 final boolean updateOomAdjLocked(ProcessRecord app) { 17834 final ActivityRecord TOP_ACT = resumedAppLocked(); 17835 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17836 final boolean wasCached = app.cached; 17837 17838 mAdjSeq++; 17839 17840 // This is the desired cached adjusment we want to tell it to use. 17841 // If our app is currently cached, we know it, and that is it. Otherwise, 17842 // we don't know it yet, and it needs to now be cached we will then 17843 // need to do a complete oom adj. 17844 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17845 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17846 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17847 SystemClock.uptimeMillis()); 17848 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17849 // Changed to/from cached state, so apps after it in the LRU 17850 // list may also be changed. 17851 updateOomAdjLocked(); 17852 } 17853 return success; 17854 } 17855 17856 final void updateOomAdjLocked() { 17857 final ActivityRecord TOP_ACT = resumedAppLocked(); 17858 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17859 final long now = SystemClock.uptimeMillis(); 17860 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17861 final int N = mLruProcesses.size(); 17862 17863 if (false) { 17864 RuntimeException e = new RuntimeException(); 17865 e.fillInStackTrace(); 17866 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17867 } 17868 17869 mAdjSeq++; 17870 mNewNumServiceProcs = 0; 17871 mNewNumAServiceProcs = 0; 17872 17873 final int emptyProcessLimit; 17874 final int cachedProcessLimit; 17875 if (mProcessLimit <= 0) { 17876 emptyProcessLimit = cachedProcessLimit = 0; 17877 } else if (mProcessLimit == 1) { 17878 emptyProcessLimit = 1; 17879 cachedProcessLimit = 0; 17880 } else { 17881 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17882 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17883 } 17884 17885 // Let's determine how many processes we have running vs. 17886 // how many slots we have for background processes; we may want 17887 // to put multiple processes in a slot of there are enough of 17888 // them. 17889 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17890 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17891 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17892 if (numEmptyProcs > cachedProcessLimit) { 17893 // If there are more empty processes than our limit on cached 17894 // processes, then use the cached process limit for the factor. 17895 // This ensures that the really old empty processes get pushed 17896 // down to the bottom, so if we are running low on memory we will 17897 // have a better chance at keeping around more cached processes 17898 // instead of a gazillion empty processes. 17899 numEmptyProcs = cachedProcessLimit; 17900 } 17901 int emptyFactor = numEmptyProcs/numSlots; 17902 if (emptyFactor < 1) emptyFactor = 1; 17903 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17904 if (cachedFactor < 1) cachedFactor = 1; 17905 int stepCached = 0; 17906 int stepEmpty = 0; 17907 int numCached = 0; 17908 int numEmpty = 0; 17909 int numTrimming = 0; 17910 17911 mNumNonCachedProcs = 0; 17912 mNumCachedHiddenProcs = 0; 17913 17914 // First update the OOM adjustment for each of the 17915 // application processes based on their current state. 17916 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17917 int nextCachedAdj = curCachedAdj+1; 17918 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17919 int nextEmptyAdj = curEmptyAdj+2; 17920 for (int i=N-1; i>=0; i--) { 17921 ProcessRecord app = mLruProcesses.get(i); 17922 if (!app.killedByAm && app.thread != null) { 17923 app.procStateChanged = false; 17924 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17925 17926 // If we haven't yet assigned the final cached adj 17927 // to the process, do that now. 17928 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17929 switch (app.curProcState) { 17930 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17931 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17932 // This process is a cached process holding activities... 17933 // assign it the next cached value for that type, and then 17934 // step that cached level. 17935 app.curRawAdj = curCachedAdj; 17936 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17937 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17938 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17939 + ")"); 17940 if (curCachedAdj != nextCachedAdj) { 17941 stepCached++; 17942 if (stepCached >= cachedFactor) { 17943 stepCached = 0; 17944 curCachedAdj = nextCachedAdj; 17945 nextCachedAdj += 2; 17946 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17947 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17948 } 17949 } 17950 } 17951 break; 17952 default: 17953 // For everything else, assign next empty cached process 17954 // level and bump that up. Note that this means that 17955 // long-running services that have dropped down to the 17956 // cached level will be treated as empty (since their process 17957 // state is still as a service), which is what we want. 17958 app.curRawAdj = curEmptyAdj; 17959 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17960 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17961 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17962 + ")"); 17963 if (curEmptyAdj != nextEmptyAdj) { 17964 stepEmpty++; 17965 if (stepEmpty >= emptyFactor) { 17966 stepEmpty = 0; 17967 curEmptyAdj = nextEmptyAdj; 17968 nextEmptyAdj += 2; 17969 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17970 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17971 } 17972 } 17973 } 17974 break; 17975 } 17976 } 17977 17978 applyOomAdjLocked(app, TOP_APP, true, now); 17979 17980 // Count the number of process types. 17981 switch (app.curProcState) { 17982 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17983 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17984 mNumCachedHiddenProcs++; 17985 numCached++; 17986 if (numCached > cachedProcessLimit) { 17987 app.kill("cached #" + numCached, true); 17988 } 17989 break; 17990 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17991 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17992 && app.lastActivityTime < oldTime) { 17993 app.kill("empty for " 17994 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17995 / 1000) + "s", true); 17996 } else { 17997 numEmpty++; 17998 if (numEmpty > emptyProcessLimit) { 17999 app.kill("empty #" + numEmpty, true); 18000 } 18001 } 18002 break; 18003 default: 18004 mNumNonCachedProcs++; 18005 break; 18006 } 18007 18008 if (app.isolated && app.services.size() <= 0) { 18009 // If this is an isolated process, and there are no 18010 // services running in it, then the process is no longer 18011 // needed. We agressively kill these because we can by 18012 // definition not re-use the same process again, and it is 18013 // good to avoid having whatever code was running in them 18014 // left sitting around after no longer needed. 18015 app.kill("isolated not needed", true); 18016 } 18017 18018 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18019 && !app.killedByAm) { 18020 numTrimming++; 18021 } 18022 } 18023 } 18024 18025 mNumServiceProcs = mNewNumServiceProcs; 18026 18027 // Now determine the memory trimming level of background processes. 18028 // Unfortunately we need to start at the back of the list to do this 18029 // properly. We only do this if the number of background apps we 18030 // are managing to keep around is less than half the maximum we desire; 18031 // if we are keeping a good number around, we'll let them use whatever 18032 // memory they want. 18033 final int numCachedAndEmpty = numCached + numEmpty; 18034 int memFactor; 18035 if (numCached <= ProcessList.TRIM_CACHED_APPS 18036 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18037 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18038 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18039 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18040 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18041 } else { 18042 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18043 } 18044 } else { 18045 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18046 } 18047 // We always allow the memory level to go up (better). We only allow it to go 18048 // down if we are in a state where that is allowed, *and* the total number of processes 18049 // has gone down since last time. 18050 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18051 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18052 + " last=" + mLastNumProcesses); 18053 if (memFactor > mLastMemoryLevel) { 18054 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18055 memFactor = mLastMemoryLevel; 18056 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18057 } 18058 } 18059 mLastMemoryLevel = memFactor; 18060 mLastNumProcesses = mLruProcesses.size(); 18061 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18062 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18063 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18064 if (mLowRamStartTime == 0) { 18065 mLowRamStartTime = now; 18066 } 18067 int step = 0; 18068 int fgTrimLevel; 18069 switch (memFactor) { 18070 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18071 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18072 break; 18073 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18074 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18075 break; 18076 default: 18077 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18078 break; 18079 } 18080 int factor = numTrimming/3; 18081 int minFactor = 2; 18082 if (mHomeProcess != null) minFactor++; 18083 if (mPreviousProcess != null) minFactor++; 18084 if (factor < minFactor) factor = minFactor; 18085 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18086 for (int i=N-1; i>=0; i--) { 18087 ProcessRecord app = mLruProcesses.get(i); 18088 if (allChanged || app.procStateChanged) { 18089 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18090 app.procStateChanged = false; 18091 } 18092 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18093 && !app.killedByAm) { 18094 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18095 try { 18096 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18097 "Trimming memory of " + app.processName 18098 + " to " + curLevel); 18099 app.thread.scheduleTrimMemory(curLevel); 18100 } catch (RemoteException e) { 18101 } 18102 if (false) { 18103 // For now we won't do this; our memory trimming seems 18104 // to be good enough at this point that destroying 18105 // activities causes more harm than good. 18106 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18107 && app != mHomeProcess && app != mPreviousProcess) { 18108 // Need to do this on its own message because the stack may not 18109 // be in a consistent state at this point. 18110 // For these apps we will also finish their activities 18111 // to help them free memory. 18112 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18113 } 18114 } 18115 } 18116 app.trimMemoryLevel = curLevel; 18117 step++; 18118 if (step >= factor) { 18119 step = 0; 18120 switch (curLevel) { 18121 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18122 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18123 break; 18124 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18125 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18126 break; 18127 } 18128 } 18129 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18130 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18131 && app.thread != null) { 18132 try { 18133 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18134 "Trimming memory of heavy-weight " + app.processName 18135 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18136 app.thread.scheduleTrimMemory( 18137 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18138 } catch (RemoteException e) { 18139 } 18140 } 18141 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18142 } else { 18143 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18144 || app.systemNoUi) && app.pendingUiClean) { 18145 // If this application is now in the background and it 18146 // had done UI, then give it the special trim level to 18147 // have it free UI resources. 18148 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18149 if (app.trimMemoryLevel < level && app.thread != null) { 18150 try { 18151 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18152 "Trimming memory of bg-ui " + app.processName 18153 + " to " + level); 18154 app.thread.scheduleTrimMemory(level); 18155 } catch (RemoteException e) { 18156 } 18157 } 18158 app.pendingUiClean = false; 18159 } 18160 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18161 try { 18162 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18163 "Trimming memory of fg " + app.processName 18164 + " to " + fgTrimLevel); 18165 app.thread.scheduleTrimMemory(fgTrimLevel); 18166 } catch (RemoteException e) { 18167 } 18168 } 18169 app.trimMemoryLevel = fgTrimLevel; 18170 } 18171 } 18172 } else { 18173 if (mLowRamStartTime != 0) { 18174 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18175 mLowRamStartTime = 0; 18176 } 18177 for (int i=N-1; i>=0; i--) { 18178 ProcessRecord app = mLruProcesses.get(i); 18179 if (allChanged || app.procStateChanged) { 18180 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18181 app.procStateChanged = false; 18182 } 18183 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18184 || app.systemNoUi) && app.pendingUiClean) { 18185 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18186 && app.thread != null) { 18187 try { 18188 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18189 "Trimming memory of ui hidden " + app.processName 18190 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18191 app.thread.scheduleTrimMemory( 18192 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18193 } catch (RemoteException e) { 18194 } 18195 } 18196 app.pendingUiClean = false; 18197 } 18198 app.trimMemoryLevel = 0; 18199 } 18200 } 18201 18202 if (mAlwaysFinishActivities) { 18203 // Need to do this on its own message because the stack may not 18204 // be in a consistent state at this point. 18205 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18206 } 18207 18208 if (allChanged) { 18209 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18210 } 18211 18212 if (mProcessStats.shouldWriteNowLocked(now)) { 18213 mHandler.post(new Runnable() { 18214 @Override public void run() { 18215 synchronized (ActivityManagerService.this) { 18216 mProcessStats.writeStateAsyncLocked(); 18217 } 18218 } 18219 }); 18220 } 18221 18222 if (DEBUG_OOM_ADJ) { 18223 if (false) { 18224 RuntimeException here = new RuntimeException("here"); 18225 here.fillInStackTrace(); 18226 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18227 } else { 18228 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18229 } 18230 } 18231 } 18232 18233 final void trimApplications() { 18234 synchronized (this) { 18235 int i; 18236 18237 // First remove any unused application processes whose package 18238 // has been removed. 18239 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18240 final ProcessRecord app = mRemovedProcesses.get(i); 18241 if (app.activities.size() == 0 18242 && app.curReceiver == null && app.services.size() == 0) { 18243 Slog.i( 18244 TAG, "Exiting empty application process " 18245 + app.processName + " (" 18246 + (app.thread != null ? app.thread.asBinder() : null) 18247 + ")\n"); 18248 if (app.pid > 0 && app.pid != MY_PID) { 18249 app.kill("empty", false); 18250 } else { 18251 try { 18252 app.thread.scheduleExit(); 18253 } catch (Exception e) { 18254 // Ignore exceptions. 18255 } 18256 } 18257 cleanUpApplicationRecordLocked(app, false, true, -1); 18258 mRemovedProcesses.remove(i); 18259 18260 if (app.persistent) { 18261 addAppLocked(app.info, false, null /* ABI override */); 18262 } 18263 } 18264 } 18265 18266 // Now update the oom adj for all processes. 18267 updateOomAdjLocked(); 18268 } 18269 } 18270 18271 /** This method sends the specified signal to each of the persistent apps */ 18272 public void signalPersistentProcesses(int sig) throws RemoteException { 18273 if (sig != Process.SIGNAL_USR1) { 18274 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18275 } 18276 18277 synchronized (this) { 18278 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18279 != PackageManager.PERMISSION_GRANTED) { 18280 throw new SecurityException("Requires permission " 18281 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18282 } 18283 18284 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18285 ProcessRecord r = mLruProcesses.get(i); 18286 if (r.thread != null && r.persistent) { 18287 Process.sendSignal(r.pid, sig); 18288 } 18289 } 18290 } 18291 } 18292 18293 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18294 if (proc == null || proc == mProfileProc) { 18295 proc = mProfileProc; 18296 profileType = mProfileType; 18297 clearProfilerLocked(); 18298 } 18299 if (proc == null) { 18300 return; 18301 } 18302 try { 18303 proc.thread.profilerControl(false, null, profileType); 18304 } catch (RemoteException e) { 18305 throw new IllegalStateException("Process disappeared"); 18306 } 18307 } 18308 18309 private void clearProfilerLocked() { 18310 if (mProfileFd != null) { 18311 try { 18312 mProfileFd.close(); 18313 } catch (IOException e) { 18314 } 18315 } 18316 mProfileApp = null; 18317 mProfileProc = null; 18318 mProfileFile = null; 18319 mProfileType = 0; 18320 mAutoStopProfiler = false; 18321 mSamplingInterval = 0; 18322 } 18323 18324 public boolean profileControl(String process, int userId, boolean start, 18325 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18326 18327 try { 18328 synchronized (this) { 18329 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18330 // its own permission. 18331 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18332 != PackageManager.PERMISSION_GRANTED) { 18333 throw new SecurityException("Requires permission " 18334 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18335 } 18336 18337 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18338 throw new IllegalArgumentException("null profile info or fd"); 18339 } 18340 18341 ProcessRecord proc = null; 18342 if (process != null) { 18343 proc = findProcessLocked(process, userId, "profileControl"); 18344 } 18345 18346 if (start && (proc == null || proc.thread == null)) { 18347 throw new IllegalArgumentException("Unknown process: " + process); 18348 } 18349 18350 if (start) { 18351 stopProfilerLocked(null, 0); 18352 setProfileApp(proc.info, proc.processName, profilerInfo); 18353 mProfileProc = proc; 18354 mProfileType = profileType; 18355 ParcelFileDescriptor fd = profilerInfo.profileFd; 18356 try { 18357 fd = fd.dup(); 18358 } catch (IOException e) { 18359 fd = null; 18360 } 18361 profilerInfo.profileFd = fd; 18362 proc.thread.profilerControl(start, profilerInfo, profileType); 18363 fd = null; 18364 mProfileFd = null; 18365 } else { 18366 stopProfilerLocked(proc, profileType); 18367 if (profilerInfo != null && profilerInfo.profileFd != null) { 18368 try { 18369 profilerInfo.profileFd.close(); 18370 } catch (IOException e) { 18371 } 18372 } 18373 } 18374 18375 return true; 18376 } 18377 } catch (RemoteException e) { 18378 throw new IllegalStateException("Process disappeared"); 18379 } finally { 18380 if (profilerInfo != null && profilerInfo.profileFd != null) { 18381 try { 18382 profilerInfo.profileFd.close(); 18383 } catch (IOException e) { 18384 } 18385 } 18386 } 18387 } 18388 18389 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18390 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18391 userId, true, ALLOW_FULL_ONLY, callName, null); 18392 ProcessRecord proc = null; 18393 try { 18394 int pid = Integer.parseInt(process); 18395 synchronized (mPidsSelfLocked) { 18396 proc = mPidsSelfLocked.get(pid); 18397 } 18398 } catch (NumberFormatException e) { 18399 } 18400 18401 if (proc == null) { 18402 ArrayMap<String, SparseArray<ProcessRecord>> all 18403 = mProcessNames.getMap(); 18404 SparseArray<ProcessRecord> procs = all.get(process); 18405 if (procs != null && procs.size() > 0) { 18406 proc = procs.valueAt(0); 18407 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18408 for (int i=1; i<procs.size(); i++) { 18409 ProcessRecord thisProc = procs.valueAt(i); 18410 if (thisProc.userId == userId) { 18411 proc = thisProc; 18412 break; 18413 } 18414 } 18415 } 18416 } 18417 } 18418 18419 return proc; 18420 } 18421 18422 public boolean dumpHeap(String process, int userId, boolean managed, 18423 String path, ParcelFileDescriptor fd) throws RemoteException { 18424 18425 try { 18426 synchronized (this) { 18427 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18428 // its own permission (same as profileControl). 18429 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18430 != PackageManager.PERMISSION_GRANTED) { 18431 throw new SecurityException("Requires permission " 18432 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18433 } 18434 18435 if (fd == null) { 18436 throw new IllegalArgumentException("null fd"); 18437 } 18438 18439 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18440 if (proc == null || proc.thread == null) { 18441 throw new IllegalArgumentException("Unknown process: " + process); 18442 } 18443 18444 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18445 if (!isDebuggable) { 18446 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18447 throw new SecurityException("Process not debuggable: " + proc); 18448 } 18449 } 18450 18451 proc.thread.dumpHeap(managed, path, fd); 18452 fd = null; 18453 return true; 18454 } 18455 } catch (RemoteException e) { 18456 throw new IllegalStateException("Process disappeared"); 18457 } finally { 18458 if (fd != null) { 18459 try { 18460 fd.close(); 18461 } catch (IOException e) { 18462 } 18463 } 18464 } 18465 } 18466 18467 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18468 public void monitor() { 18469 synchronized (this) { } 18470 } 18471 18472 void onCoreSettingsChange(Bundle settings) { 18473 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18474 ProcessRecord processRecord = mLruProcesses.get(i); 18475 try { 18476 if (processRecord.thread != null) { 18477 processRecord.thread.setCoreSettings(settings); 18478 } 18479 } catch (RemoteException re) { 18480 /* ignore */ 18481 } 18482 } 18483 } 18484 18485 // Multi-user methods 18486 18487 /** 18488 * Start user, if its not already running, but don't bring it to foreground. 18489 */ 18490 @Override 18491 public boolean startUserInBackground(final int userId) { 18492 return startUser(userId, /* foreground */ false); 18493 } 18494 18495 /** 18496 * Start user, if its not already running, and bring it to foreground. 18497 */ 18498 boolean startUserInForeground(final int userId, Dialog dlg) { 18499 boolean result = startUser(userId, /* foreground */ true); 18500 dlg.dismiss(); 18501 return result; 18502 } 18503 18504 /** 18505 * Refreshes the list of users related to the current user when either a 18506 * user switch happens or when a new related user is started in the 18507 * background. 18508 */ 18509 private void updateCurrentProfileIdsLocked() { 18510 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18511 mCurrentUserId, false /* enabledOnly */); 18512 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18513 for (int i = 0; i < currentProfileIds.length; i++) { 18514 currentProfileIds[i] = profiles.get(i).id; 18515 } 18516 mCurrentProfileIds = currentProfileIds; 18517 18518 synchronized (mUserProfileGroupIdsSelfLocked) { 18519 mUserProfileGroupIdsSelfLocked.clear(); 18520 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18521 for (int i = 0; i < users.size(); i++) { 18522 UserInfo user = users.get(i); 18523 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18524 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18525 } 18526 } 18527 } 18528 } 18529 18530 private Set getProfileIdsLocked(int userId) { 18531 Set userIds = new HashSet<Integer>(); 18532 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18533 userId, false /* enabledOnly */); 18534 for (UserInfo user : profiles) { 18535 userIds.add(Integer.valueOf(user.id)); 18536 } 18537 return userIds; 18538 } 18539 18540 @Override 18541 public boolean switchUser(final int userId) { 18542 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18543 String userName; 18544 synchronized (this) { 18545 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18546 if (userInfo == null) { 18547 Slog.w(TAG, "No user info for user #" + userId); 18548 return false; 18549 } 18550 if (userInfo.isManagedProfile()) { 18551 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18552 return false; 18553 } 18554 userName = userInfo.name; 18555 mTargetUserId = userId; 18556 } 18557 mHandler.removeMessages(START_USER_SWITCH_MSG); 18558 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18559 return true; 18560 } 18561 18562 private void showUserSwitchDialog(int userId, String userName) { 18563 // The dialog will show and then initiate the user switch by calling startUserInForeground 18564 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18565 true /* above system */); 18566 d.show(); 18567 } 18568 18569 private boolean startUser(final int userId, final boolean foreground) { 18570 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18571 != PackageManager.PERMISSION_GRANTED) { 18572 String msg = "Permission Denial: switchUser() from pid=" 18573 + Binder.getCallingPid() 18574 + ", uid=" + Binder.getCallingUid() 18575 + " requires " + INTERACT_ACROSS_USERS_FULL; 18576 Slog.w(TAG, msg); 18577 throw new SecurityException(msg); 18578 } 18579 18580 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18581 18582 final long ident = Binder.clearCallingIdentity(); 18583 try { 18584 synchronized (this) { 18585 final int oldUserId = mCurrentUserId; 18586 if (oldUserId == userId) { 18587 return true; 18588 } 18589 18590 mStackSupervisor.setLockTaskModeLocked(null, false); 18591 18592 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18593 if (userInfo == null) { 18594 Slog.w(TAG, "No user info for user #" + userId); 18595 return false; 18596 } 18597 if (foreground && userInfo.isManagedProfile()) { 18598 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18599 return false; 18600 } 18601 18602 if (foreground) { 18603 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18604 R.anim.screen_user_enter); 18605 } 18606 18607 boolean needStart = false; 18608 18609 // If the user we are switching to is not currently started, then 18610 // we need to start it now. 18611 if (mStartedUsers.get(userId) == null) { 18612 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18613 updateStartedUserArrayLocked(); 18614 needStart = true; 18615 } 18616 18617 final Integer userIdInt = Integer.valueOf(userId); 18618 mUserLru.remove(userIdInt); 18619 mUserLru.add(userIdInt); 18620 18621 if (foreground) { 18622 mCurrentUserId = userId; 18623 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18624 updateCurrentProfileIdsLocked(); 18625 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18626 // Once the internal notion of the active user has switched, we lock the device 18627 // with the option to show the user switcher on the keyguard. 18628 mWindowManager.lockNow(null); 18629 } else { 18630 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18631 updateCurrentProfileIdsLocked(); 18632 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18633 mUserLru.remove(currentUserIdInt); 18634 mUserLru.add(currentUserIdInt); 18635 } 18636 18637 final UserStartedState uss = mStartedUsers.get(userId); 18638 18639 // Make sure user is in the started state. If it is currently 18640 // stopping, we need to knock that off. 18641 if (uss.mState == UserStartedState.STATE_STOPPING) { 18642 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18643 // so we can just fairly silently bring the user back from 18644 // the almost-dead. 18645 uss.mState = UserStartedState.STATE_RUNNING; 18646 updateStartedUserArrayLocked(); 18647 needStart = true; 18648 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18649 // This means ACTION_SHUTDOWN has been sent, so we will 18650 // need to treat this as a new boot of the user. 18651 uss.mState = UserStartedState.STATE_BOOTING; 18652 updateStartedUserArrayLocked(); 18653 needStart = true; 18654 } 18655 18656 if (uss.mState == UserStartedState.STATE_BOOTING) { 18657 // Booting up a new user, need to tell system services about it. 18658 // Note that this is on the same handler as scheduling of broadcasts, 18659 // which is important because it needs to go first. 18660 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18661 } 18662 18663 if (foreground) { 18664 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18665 oldUserId)); 18666 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18667 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18668 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18669 oldUserId, userId, uss)); 18670 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18671 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18672 } 18673 18674 if (needStart) { 18675 // Send USER_STARTED broadcast 18676 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18677 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18678 | Intent.FLAG_RECEIVER_FOREGROUND); 18679 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18680 broadcastIntentLocked(null, null, intent, 18681 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18682 false, false, MY_PID, Process.SYSTEM_UID, userId); 18683 } 18684 18685 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18686 if (userId != UserHandle.USER_OWNER) { 18687 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18688 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18689 broadcastIntentLocked(null, null, intent, null, 18690 new IIntentReceiver.Stub() { 18691 public void performReceive(Intent intent, int resultCode, 18692 String data, Bundle extras, boolean ordered, 18693 boolean sticky, int sendingUser) { 18694 onUserInitialized(uss, foreground, oldUserId, userId); 18695 } 18696 }, 0, null, null, null, AppOpsManager.OP_NONE, 18697 true, false, MY_PID, Process.SYSTEM_UID, 18698 userId); 18699 uss.initializing = true; 18700 } else { 18701 getUserManagerLocked().makeInitialized(userInfo.id); 18702 } 18703 } 18704 18705 if (foreground) { 18706 if (!uss.initializing) { 18707 moveUserToForeground(uss, oldUserId, userId); 18708 } 18709 } else { 18710 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18711 } 18712 18713 if (needStart) { 18714 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18715 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18716 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18717 broadcastIntentLocked(null, null, intent, 18718 null, new IIntentReceiver.Stub() { 18719 @Override 18720 public void performReceive(Intent intent, int resultCode, String data, 18721 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18722 throws RemoteException { 18723 } 18724 }, 0, null, null, 18725 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18726 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18727 } 18728 } 18729 } finally { 18730 Binder.restoreCallingIdentity(ident); 18731 } 18732 18733 return true; 18734 } 18735 18736 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18737 long ident = Binder.clearCallingIdentity(); 18738 try { 18739 Intent intent; 18740 if (oldUserId >= 0) { 18741 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18742 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18743 int count = profiles.size(); 18744 for (int i = 0; i < count; i++) { 18745 int profileUserId = profiles.get(i).id; 18746 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18747 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18748 | Intent.FLAG_RECEIVER_FOREGROUND); 18749 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18750 broadcastIntentLocked(null, null, intent, 18751 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18752 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18753 } 18754 } 18755 if (newUserId >= 0) { 18756 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18757 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18758 int count = profiles.size(); 18759 for (int i = 0; i < count; i++) { 18760 int profileUserId = profiles.get(i).id; 18761 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18762 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18763 | Intent.FLAG_RECEIVER_FOREGROUND); 18764 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18765 broadcastIntentLocked(null, null, intent, 18766 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18767 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18768 } 18769 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18770 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18771 | Intent.FLAG_RECEIVER_FOREGROUND); 18772 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18773 broadcastIntentLocked(null, null, intent, 18774 null, null, 0, null, null, 18775 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18776 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18777 } 18778 } finally { 18779 Binder.restoreCallingIdentity(ident); 18780 } 18781 } 18782 18783 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18784 final int newUserId) { 18785 final int N = mUserSwitchObservers.beginBroadcast(); 18786 if (N > 0) { 18787 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18788 int mCount = 0; 18789 @Override 18790 public void sendResult(Bundle data) throws RemoteException { 18791 synchronized (ActivityManagerService.this) { 18792 if (mCurUserSwitchCallback == this) { 18793 mCount++; 18794 if (mCount == N) { 18795 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18796 } 18797 } 18798 } 18799 } 18800 }; 18801 synchronized (this) { 18802 uss.switching = true; 18803 mCurUserSwitchCallback = callback; 18804 } 18805 for (int i=0; i<N; i++) { 18806 try { 18807 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18808 newUserId, callback); 18809 } catch (RemoteException e) { 18810 } 18811 } 18812 } else { 18813 synchronized (this) { 18814 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18815 } 18816 } 18817 mUserSwitchObservers.finishBroadcast(); 18818 } 18819 18820 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18821 synchronized (this) { 18822 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18823 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18824 } 18825 } 18826 18827 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18828 mCurUserSwitchCallback = null; 18829 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18830 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18831 oldUserId, newUserId, uss)); 18832 } 18833 18834 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18835 synchronized (this) { 18836 if (foreground) { 18837 moveUserToForeground(uss, oldUserId, newUserId); 18838 } 18839 } 18840 18841 completeSwitchAndInitalize(uss, newUserId, true, false); 18842 } 18843 18844 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18845 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18846 if (homeInFront) { 18847 startHomeActivityLocked(newUserId); 18848 } else { 18849 mStackSupervisor.resumeTopActivitiesLocked(); 18850 } 18851 EventLogTags.writeAmSwitchUser(newUserId); 18852 getUserManagerLocked().userForeground(newUserId); 18853 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18854 } 18855 18856 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18857 completeSwitchAndInitalize(uss, newUserId, false, true); 18858 } 18859 18860 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18861 boolean clearInitializing, boolean clearSwitching) { 18862 boolean unfrozen = false; 18863 synchronized (this) { 18864 if (clearInitializing) { 18865 uss.initializing = false; 18866 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18867 } 18868 if (clearSwitching) { 18869 uss.switching = false; 18870 } 18871 if (!uss.switching && !uss.initializing) { 18872 mWindowManager.stopFreezingScreen(); 18873 unfrozen = true; 18874 } 18875 } 18876 if (unfrozen) { 18877 final int N = mUserSwitchObservers.beginBroadcast(); 18878 for (int i=0; i<N; i++) { 18879 try { 18880 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18881 } catch (RemoteException e) { 18882 } 18883 } 18884 mUserSwitchObservers.finishBroadcast(); 18885 } 18886 } 18887 18888 void scheduleStartProfilesLocked() { 18889 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18890 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18891 DateUtils.SECOND_IN_MILLIS); 18892 } 18893 } 18894 18895 void startProfilesLocked() { 18896 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18897 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18898 mCurrentUserId, false /* enabledOnly */); 18899 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18900 for (UserInfo user : profiles) { 18901 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18902 && user.id != mCurrentUserId) { 18903 toStart.add(user); 18904 } 18905 } 18906 final int n = toStart.size(); 18907 int i = 0; 18908 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18909 startUserInBackground(toStart.get(i).id); 18910 } 18911 if (i < n) { 18912 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18913 } 18914 } 18915 18916 void finishUserBoot(UserStartedState uss) { 18917 synchronized (this) { 18918 if (uss.mState == UserStartedState.STATE_BOOTING 18919 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18920 uss.mState = UserStartedState.STATE_RUNNING; 18921 final int userId = uss.mHandle.getIdentifier(); 18922 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18923 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18924 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18925 broadcastIntentLocked(null, null, intent, 18926 null, null, 0, null, null, 18927 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18928 true, false, MY_PID, Process.SYSTEM_UID, userId); 18929 } 18930 } 18931 } 18932 18933 void finishUserSwitch(UserStartedState uss) { 18934 synchronized (this) { 18935 finishUserBoot(uss); 18936 18937 startProfilesLocked(); 18938 18939 int num = mUserLru.size(); 18940 int i = 0; 18941 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18942 Integer oldUserId = mUserLru.get(i); 18943 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18944 if (oldUss == null) { 18945 // Shouldn't happen, but be sane if it does. 18946 mUserLru.remove(i); 18947 num--; 18948 continue; 18949 } 18950 if (oldUss.mState == UserStartedState.STATE_STOPPING 18951 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18952 // This user is already stopping, doesn't count. 18953 num--; 18954 i++; 18955 continue; 18956 } 18957 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18958 // Owner and current can't be stopped, but count as running. 18959 i++; 18960 continue; 18961 } 18962 // This is a user to be stopped. 18963 stopUserLocked(oldUserId, null); 18964 num--; 18965 i++; 18966 } 18967 } 18968 } 18969 18970 @Override 18971 public int stopUser(final int userId, final IStopUserCallback callback) { 18972 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18973 != PackageManager.PERMISSION_GRANTED) { 18974 String msg = "Permission Denial: switchUser() from pid=" 18975 + Binder.getCallingPid() 18976 + ", uid=" + Binder.getCallingUid() 18977 + " requires " + INTERACT_ACROSS_USERS_FULL; 18978 Slog.w(TAG, msg); 18979 throw new SecurityException(msg); 18980 } 18981 if (userId <= 0) { 18982 throw new IllegalArgumentException("Can't stop primary user " + userId); 18983 } 18984 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18985 synchronized (this) { 18986 return stopUserLocked(userId, callback); 18987 } 18988 } 18989 18990 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18991 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18992 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18993 return ActivityManager.USER_OP_IS_CURRENT; 18994 } 18995 18996 final UserStartedState uss = mStartedUsers.get(userId); 18997 if (uss == null) { 18998 // User is not started, nothing to do... but we do need to 18999 // callback if requested. 19000 if (callback != null) { 19001 mHandler.post(new Runnable() { 19002 @Override 19003 public void run() { 19004 try { 19005 callback.userStopped(userId); 19006 } catch (RemoteException e) { 19007 } 19008 } 19009 }); 19010 } 19011 return ActivityManager.USER_OP_SUCCESS; 19012 } 19013 19014 if (callback != null) { 19015 uss.mStopCallbacks.add(callback); 19016 } 19017 19018 if (uss.mState != UserStartedState.STATE_STOPPING 19019 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19020 uss.mState = UserStartedState.STATE_STOPPING; 19021 updateStartedUserArrayLocked(); 19022 19023 long ident = Binder.clearCallingIdentity(); 19024 try { 19025 // We are going to broadcast ACTION_USER_STOPPING and then 19026 // once that is done send a final ACTION_SHUTDOWN and then 19027 // stop the user. 19028 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19029 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19030 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19031 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19032 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19033 // This is the result receiver for the final shutdown broadcast. 19034 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19035 @Override 19036 public void performReceive(Intent intent, int resultCode, String data, 19037 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19038 finishUserStop(uss); 19039 } 19040 }; 19041 // This is the result receiver for the initial stopping broadcast. 19042 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19043 @Override 19044 public void performReceive(Intent intent, int resultCode, String data, 19045 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19046 // On to the next. 19047 synchronized (ActivityManagerService.this) { 19048 if (uss.mState != UserStartedState.STATE_STOPPING) { 19049 // Whoops, we are being started back up. Abort, abort! 19050 return; 19051 } 19052 uss.mState = UserStartedState.STATE_SHUTDOWN; 19053 } 19054 mBatteryStatsService.noteEvent( 19055 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19056 Integer.toString(userId), userId); 19057 mSystemServiceManager.stopUser(userId); 19058 broadcastIntentLocked(null, null, shutdownIntent, 19059 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19060 true, false, MY_PID, Process.SYSTEM_UID, userId); 19061 } 19062 }; 19063 // Kick things off. 19064 broadcastIntentLocked(null, null, stoppingIntent, 19065 null, stoppingReceiver, 0, null, null, 19066 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19067 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19068 } finally { 19069 Binder.restoreCallingIdentity(ident); 19070 } 19071 } 19072 19073 return ActivityManager.USER_OP_SUCCESS; 19074 } 19075 19076 void finishUserStop(UserStartedState uss) { 19077 final int userId = uss.mHandle.getIdentifier(); 19078 boolean stopped; 19079 ArrayList<IStopUserCallback> callbacks; 19080 synchronized (this) { 19081 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19082 if (mStartedUsers.get(userId) != uss) { 19083 stopped = false; 19084 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19085 stopped = false; 19086 } else { 19087 stopped = true; 19088 // User can no longer run. 19089 mStartedUsers.remove(userId); 19090 mUserLru.remove(Integer.valueOf(userId)); 19091 updateStartedUserArrayLocked(); 19092 19093 // Clean up all state and processes associated with the user. 19094 // Kill all the processes for the user. 19095 forceStopUserLocked(userId, "finish user"); 19096 } 19097 19098 // Explicitly remove the old information in mRecentTasks. 19099 removeRecentTasksForUserLocked(userId); 19100 } 19101 19102 for (int i=0; i<callbacks.size(); i++) { 19103 try { 19104 if (stopped) callbacks.get(i).userStopped(userId); 19105 else callbacks.get(i).userStopAborted(userId); 19106 } catch (RemoteException e) { 19107 } 19108 } 19109 19110 if (stopped) { 19111 mSystemServiceManager.cleanupUser(userId); 19112 synchronized (this) { 19113 mStackSupervisor.removeUserLocked(userId); 19114 } 19115 } 19116 } 19117 19118 @Override 19119 public UserInfo getCurrentUser() { 19120 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19121 != PackageManager.PERMISSION_GRANTED) && ( 19122 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19123 != PackageManager.PERMISSION_GRANTED)) { 19124 String msg = "Permission Denial: getCurrentUser() from pid=" 19125 + Binder.getCallingPid() 19126 + ", uid=" + Binder.getCallingUid() 19127 + " requires " + INTERACT_ACROSS_USERS; 19128 Slog.w(TAG, msg); 19129 throw new SecurityException(msg); 19130 } 19131 synchronized (this) { 19132 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19133 return getUserManagerLocked().getUserInfo(userId); 19134 } 19135 } 19136 19137 int getCurrentUserIdLocked() { 19138 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19139 } 19140 19141 @Override 19142 public boolean isUserRunning(int userId, boolean orStopped) { 19143 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19144 != PackageManager.PERMISSION_GRANTED) { 19145 String msg = "Permission Denial: isUserRunning() from pid=" 19146 + Binder.getCallingPid() 19147 + ", uid=" + Binder.getCallingUid() 19148 + " requires " + INTERACT_ACROSS_USERS; 19149 Slog.w(TAG, msg); 19150 throw new SecurityException(msg); 19151 } 19152 synchronized (this) { 19153 return isUserRunningLocked(userId, orStopped); 19154 } 19155 } 19156 19157 boolean isUserRunningLocked(int userId, boolean orStopped) { 19158 UserStartedState state = mStartedUsers.get(userId); 19159 if (state == null) { 19160 return false; 19161 } 19162 if (orStopped) { 19163 return true; 19164 } 19165 return state.mState != UserStartedState.STATE_STOPPING 19166 && state.mState != UserStartedState.STATE_SHUTDOWN; 19167 } 19168 19169 @Override 19170 public int[] getRunningUserIds() { 19171 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19172 != PackageManager.PERMISSION_GRANTED) { 19173 String msg = "Permission Denial: isUserRunning() from pid=" 19174 + Binder.getCallingPid() 19175 + ", uid=" + Binder.getCallingUid() 19176 + " requires " + INTERACT_ACROSS_USERS; 19177 Slog.w(TAG, msg); 19178 throw new SecurityException(msg); 19179 } 19180 synchronized (this) { 19181 return mStartedUserArray; 19182 } 19183 } 19184 19185 private void updateStartedUserArrayLocked() { 19186 int num = 0; 19187 for (int i=0; i<mStartedUsers.size(); i++) { 19188 UserStartedState uss = mStartedUsers.valueAt(i); 19189 // This list does not include stopping users. 19190 if (uss.mState != UserStartedState.STATE_STOPPING 19191 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19192 num++; 19193 } 19194 } 19195 mStartedUserArray = new int[num]; 19196 num = 0; 19197 for (int i=0; i<mStartedUsers.size(); i++) { 19198 UserStartedState uss = mStartedUsers.valueAt(i); 19199 if (uss.mState != UserStartedState.STATE_STOPPING 19200 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19201 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19202 num++; 19203 } 19204 } 19205 } 19206 19207 @Override 19208 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19209 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19210 != PackageManager.PERMISSION_GRANTED) { 19211 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19212 + Binder.getCallingPid() 19213 + ", uid=" + Binder.getCallingUid() 19214 + " requires " + INTERACT_ACROSS_USERS_FULL; 19215 Slog.w(TAG, msg); 19216 throw new SecurityException(msg); 19217 } 19218 19219 mUserSwitchObservers.register(observer); 19220 } 19221 19222 @Override 19223 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19224 mUserSwitchObservers.unregister(observer); 19225 } 19226 19227 private boolean userExists(int userId) { 19228 if (userId == 0) { 19229 return true; 19230 } 19231 UserManagerService ums = getUserManagerLocked(); 19232 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19233 } 19234 19235 int[] getUsersLocked() { 19236 UserManagerService ums = getUserManagerLocked(); 19237 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19238 } 19239 19240 UserManagerService getUserManagerLocked() { 19241 if (mUserManager == null) { 19242 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19243 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19244 } 19245 return mUserManager; 19246 } 19247 19248 private int applyUserId(int uid, int userId) { 19249 return UserHandle.getUid(userId, uid); 19250 } 19251 19252 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19253 if (info == null) return null; 19254 ApplicationInfo newInfo = new ApplicationInfo(info); 19255 newInfo.uid = applyUserId(info.uid, userId); 19256 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19257 + info.packageName; 19258 return newInfo; 19259 } 19260 19261 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19262 if (aInfo == null 19263 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19264 return aInfo; 19265 } 19266 19267 ActivityInfo info = new ActivityInfo(aInfo); 19268 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19269 return info; 19270 } 19271 19272 private final class LocalService extends ActivityManagerInternal { 19273 @Override 19274 public void onWakefulnessChanged(int wakefulness) { 19275 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19276 } 19277 19278 @Override 19279 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19280 String processName, String abiOverride, int uid, Runnable crashHandler) { 19281 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19282 processName, abiOverride, uid, crashHandler); 19283 } 19284 } 19285 19286 /** 19287 * An implementation of IAppTask, that allows an app to manage its own tasks via 19288 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19289 * only the process that calls getAppTasks() can call the AppTask methods. 19290 */ 19291 class AppTaskImpl extends IAppTask.Stub { 19292 private int mTaskId; 19293 private int mCallingUid; 19294 19295 public AppTaskImpl(int taskId, int callingUid) { 19296 mTaskId = taskId; 19297 mCallingUid = callingUid; 19298 } 19299 19300 private void checkCaller() { 19301 if (mCallingUid != Binder.getCallingUid()) { 19302 throw new SecurityException("Caller " + mCallingUid 19303 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19304 } 19305 } 19306 19307 @Override 19308 public void finishAndRemoveTask() { 19309 checkCaller(); 19310 19311 synchronized (ActivityManagerService.this) { 19312 long origId = Binder.clearCallingIdentity(); 19313 try { 19314 if (!removeTaskByIdLocked(mTaskId, false)) { 19315 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19316 } 19317 } finally { 19318 Binder.restoreCallingIdentity(origId); 19319 } 19320 } 19321 } 19322 19323 @Override 19324 public ActivityManager.RecentTaskInfo getTaskInfo() { 19325 checkCaller(); 19326 19327 synchronized (ActivityManagerService.this) { 19328 long origId = Binder.clearCallingIdentity(); 19329 try { 19330 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19331 if (tr == null) { 19332 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19333 } 19334 return createRecentTaskInfoFromTaskRecord(tr); 19335 } finally { 19336 Binder.restoreCallingIdentity(origId); 19337 } 19338 } 19339 } 19340 19341 @Override 19342 public void moveToFront() { 19343 checkCaller(); 19344 19345 final TaskRecord tr; 19346 synchronized (ActivityManagerService.this) { 19347 tr = recentTaskForIdLocked(mTaskId); 19348 if (tr == null) { 19349 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19350 } 19351 if (tr.getRootActivity() != null) { 19352 moveTaskToFrontLocked(tr.taskId, 0, null); 19353 return; 19354 } 19355 } 19356 19357 startActivityFromRecentsInner(tr.taskId, null); 19358 } 19359 19360 @Override 19361 public int startActivity(IBinder whoThread, String callingPackage, 19362 Intent intent, String resolvedType, Bundle options) { 19363 checkCaller(); 19364 19365 int callingUser = UserHandle.getCallingUserId(); 19366 TaskRecord tr; 19367 IApplicationThread appThread; 19368 synchronized (ActivityManagerService.this) { 19369 tr = recentTaskForIdLocked(mTaskId); 19370 if (tr == null) { 19371 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19372 } 19373 appThread = ApplicationThreadNative.asInterface(whoThread); 19374 if (appThread == null) { 19375 throw new IllegalArgumentException("Bad app thread " + appThread); 19376 } 19377 } 19378 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19379 resolvedType, null, null, null, null, 0, 0, null, null, 19380 null, options, callingUser, null, tr); 19381 } 19382 19383 @Override 19384 public void setExcludeFromRecents(boolean exclude) { 19385 checkCaller(); 19386 19387 synchronized (ActivityManagerService.this) { 19388 long origId = Binder.clearCallingIdentity(); 19389 try { 19390 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19391 if (tr == null) { 19392 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19393 } 19394 Intent intent = tr.getBaseIntent(); 19395 if (exclude) { 19396 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19397 } else { 19398 intent.setFlags(intent.getFlags() 19399 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19400 } 19401 } finally { 19402 Binder.restoreCallingIdentity(origId); 19403 } 19404 } 19405 } 19406 } 19407} 19408