ActivityManagerService.java revision c58054f25fb8ad624a749ed48e3f5775de4bec14
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import android.view.Display; 59import com.android.internal.R; 60import com.android.internal.annotations.GuardedBy; 61import com.android.internal.app.IAppOpsService; 62import com.android.internal.app.IVoiceInteractor; 63import com.android.internal.app.ProcessMap; 64import com.android.internal.app.ProcessStats; 65import com.android.internal.content.PackageMonitor; 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.UserManagerService; 86import com.android.server.wm.AppTransition; 87import com.android.server.wm.WindowManagerService; 88import com.google.android.collect.Lists; 89import com.google.android.collect.Maps; 90 91import libcore.io.IoUtils; 92 93import org.xmlpull.v1.XmlPullParser; 94import org.xmlpull.v1.XmlPullParserException; 95import org.xmlpull.v1.XmlSerializer; 96 97import android.app.Activity; 98import android.app.ActivityManager; 99import android.app.ActivityManager.RunningTaskInfo; 100import android.app.ActivityManager.StackInfo; 101import android.app.ActivityManagerInternal; 102import android.app.ActivityManagerNative; 103import android.app.ActivityOptions; 104import android.app.ActivityThread; 105import android.app.AlertDialog; 106import android.app.AppGlobals; 107import android.app.ApplicationErrorReport; 108import android.app.Dialog; 109import android.app.IActivityController; 110import android.app.IApplicationThread; 111import android.app.IInstrumentationWatcher; 112import android.app.INotificationManager; 113import android.app.IProcessObserver; 114import android.app.IServiceConnection; 115import android.app.IStopUserCallback; 116import android.app.IUiAutomationConnection; 117import android.app.IUserSwitchObserver; 118import android.app.Instrumentation; 119import android.app.Notification; 120import android.app.NotificationManager; 121import android.app.PendingIntent; 122import android.app.backup.IBackupManager; 123import android.content.ActivityNotFoundException; 124import android.content.BroadcastReceiver; 125import android.content.ClipData; 126import android.content.ComponentCallbacks2; 127import android.content.ComponentName; 128import android.content.ContentProvider; 129import android.content.ContentResolver; 130import android.content.Context; 131import android.content.DialogInterface; 132import android.content.IContentProvider; 133import android.content.IIntentReceiver; 134import android.content.IIntentSender; 135import android.content.Intent; 136import android.content.IntentFilter; 137import android.content.IntentSender; 138import android.content.pm.ActivityInfo; 139import android.content.pm.ApplicationInfo; 140import android.content.pm.ConfigurationInfo; 141import android.content.pm.IPackageDataObserver; 142import android.content.pm.IPackageManager; 143import android.content.pm.InstrumentationInfo; 144import android.content.pm.PackageInfo; 145import android.content.pm.PackageManager; 146import android.content.pm.ParceledListSlice; 147import android.content.pm.UserInfo; 148import android.content.pm.PackageManager.NameNotFoundException; 149import android.content.pm.PathPermission; 150import android.content.pm.ProviderInfo; 151import android.content.pm.ResolveInfo; 152import android.content.pm.ServiceInfo; 153import android.content.res.CompatibilityInfo; 154import android.content.res.Configuration; 155import android.net.Proxy; 156import android.net.ProxyInfo; 157import android.net.Uri; 158import android.os.Binder; 159import android.os.Build; 160import android.os.Bundle; 161import android.os.Debug; 162import android.os.DropBoxManager; 163import android.os.Environment; 164import android.os.FactoryTest; 165import android.os.FileObserver; 166import android.os.FileUtils; 167import android.os.Handler; 168import android.os.IBinder; 169import android.os.IPermissionController; 170import android.os.IRemoteCallback; 171import android.os.IUserManager; 172import android.os.Looper; 173import android.os.Message; 174import android.os.Parcel; 175import android.os.ParcelFileDescriptor; 176import android.os.Process; 177import android.os.RemoteCallbackList; 178import android.os.RemoteException; 179import android.os.SELinux; 180import android.os.ServiceManager; 181import android.os.StrictMode; 182import android.os.SystemClock; 183import android.os.SystemProperties; 184import android.os.UpdateLock; 185import android.os.UserHandle; 186import android.os.UserManager; 187import android.provider.Settings; 188import android.text.format.DateUtils; 189import android.text.format.Time; 190import android.util.AtomicFile; 191import android.util.EventLog; 192import android.util.Log; 193import android.util.Pair; 194import android.util.PrintWriterPrinter; 195import android.util.Slog; 196import android.util.SparseArray; 197import android.util.TimeUtils; 198import android.util.Xml; 199import android.view.Gravity; 200import android.view.LayoutInflater; 201import android.view.View; 202import android.view.WindowManager; 203import dalvik.system.VMRuntime; 204 205import java.io.BufferedInputStream; 206import java.io.BufferedOutputStream; 207import java.io.DataInputStream; 208import java.io.DataOutputStream; 209import java.io.File; 210import java.io.FileDescriptor; 211import java.io.FileInputStream; 212import java.io.FileNotFoundException; 213import java.io.FileOutputStream; 214import java.io.IOException; 215import java.io.InputStreamReader; 216import java.io.PrintWriter; 217import java.io.StringWriter; 218import java.lang.ref.WeakReference; 219import java.util.ArrayList; 220import java.util.Arrays; 221import java.util.Collections; 222import java.util.Comparator; 223import java.util.HashMap; 224import java.util.HashSet; 225import java.util.Iterator; 226import java.util.List; 227import java.util.Locale; 228import java.util.Map; 229import java.util.Set; 230import java.util.concurrent.atomic.AtomicBoolean; 231import java.util.concurrent.atomic.AtomicLong; 232 233public final class ActivityManagerService extends ActivityManagerNative 234 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 235 236 private static final String USER_DATA_DIR = "/data/user/"; 237 // File that stores last updated system version and called preboot receivers 238 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 239 240 static final String TAG = "ActivityManager"; 241 static final String TAG_MU = "ActivityManagerServiceMU"; 242 static final boolean DEBUG = false; 243 static final boolean localLOGV = DEBUG; 244 static final boolean DEBUG_BACKUP = localLOGV || false; 245 static final boolean DEBUG_BROADCAST = localLOGV || false; 246 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 247 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 248 static final boolean DEBUG_CLEANUP = localLOGV || false; 249 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 250 static final boolean DEBUG_FOCUS = false; 251 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 252 static final boolean DEBUG_MU = localLOGV || false; 253 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 254 static final boolean DEBUG_LRU = localLOGV || false; 255 static final boolean DEBUG_PAUSE = localLOGV || false; 256 static final boolean DEBUG_POWER = localLOGV || false; 257 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 258 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 259 static final boolean DEBUG_PROCESSES = localLOGV || false; 260 static final boolean DEBUG_PROVIDER = localLOGV || false; 261 static final boolean DEBUG_RESULTS = localLOGV || false; 262 static final boolean DEBUG_SERVICE = localLOGV || false; 263 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 264 static final boolean DEBUG_STACK = localLOGV || false; 265 static final boolean DEBUG_SWITCH = localLOGV || false; 266 static final boolean DEBUG_TASKS = localLOGV || false; 267 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 268 static final boolean DEBUG_TRANSITION = localLOGV || false; 269 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 270 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 271 static final boolean DEBUG_VISBILITY = localLOGV || false; 272 static final boolean DEBUG_PSS = localLOGV || false; 273 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 274 static final boolean DEBUG_RECENTS = localLOGV || false; 275 static final boolean VALIDATE_TOKENS = false; 276 static final boolean SHOW_ACTIVITY_START_TIME = true; 277 278 // Control over CPU and battery monitoring. 279 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 280 static final boolean MONITOR_CPU_USAGE = true; 281 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 282 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 283 static final boolean MONITOR_THREAD_CPU_USAGE = false; 284 285 // The flags that are set for all calls we make to the package manager. 286 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 287 288 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 289 290 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 291 292 // Maximum number recent bitmaps to keep in memory. 293 static final int MAX_RECENT_BITMAPS = 5; 294 295 // Amount of time after a call to stopAppSwitches() during which we will 296 // prevent further untrusted switches from happening. 297 static final long APP_SWITCH_DELAY_TIME = 5*1000; 298 299 // How long we wait for a launched process to attach to the activity manager 300 // before we decide it's never going to come up for real. 301 static final int PROC_START_TIMEOUT = 10*1000; 302 303 // How long we wait for a launched process to attach to the activity manager 304 // before we decide it's never going to come up for real, when the process was 305 // started with a wrapper for instrumentation (such as Valgrind) because it 306 // could take much longer than usual. 307 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 308 309 // How long to wait after going idle before forcing apps to GC. 310 static final int GC_TIMEOUT = 5*1000; 311 312 // The minimum amount of time between successive GC requests for a process. 313 static final int GC_MIN_INTERVAL = 60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process. 316 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 317 318 // The minimum amount of time between successive PSS requests for a process 319 // when the request is due to the memory state being lowered. 320 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 321 322 // The rate at which we check for apps using excessive power -- 15 mins. 323 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 324 325 // The minimum sample duration we will allow before deciding we have 326 // enough data on wake locks to start killing things. 327 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on CPU usage to start killing things. 331 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // How long we allow a receiver to run before giving up on it. 334 static final int BROADCAST_FG_TIMEOUT = 10*1000; 335 static final int BROADCAST_BG_TIMEOUT = 60*1000; 336 337 // How long we wait until we timeout on key dispatching. 338 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 339 340 // How long we wait until we timeout on key dispatching during instrumentation. 341 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 342 343 // Amount of time we wait for observers to handle a user switch before 344 // giving up on them and unfreezing the screen. 345 static final int USER_SWITCH_TIMEOUT = 2*1000; 346 347 // Maximum number of users we allow to be running at a time. 348 static final int MAX_RUNNING_USERS = 3; 349 350 // How long to wait in getAssistContextExtras for the activity and foreground services 351 // to respond with the result. 352 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 353 354 // Maximum number of persisted Uri grants a package is allowed 355 static final int MAX_PERSISTED_URI_GRANTS = 128; 356 357 static final int MY_PID = Process.myPid(); 358 359 static final String[] EMPTY_STRING_ARRAY = new String[0]; 360 361 // How many bytes to write into the dropbox log before truncating 362 static final int DROPBOX_MAX_SIZE = 256 * 1024; 363 364 // Access modes for handleIncomingUser. 365 static final int ALLOW_NON_FULL = 0; 366 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 367 static final int ALLOW_FULL_ONLY = 2; 368 369 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 370 371 /** All system services */ 372 SystemServiceManager mSystemServiceManager; 373 374 /** Run all ActivityStacks through this */ 375 ActivityStackSupervisor mStackSupervisor; 376 377 public IntentFirewall mIntentFirewall; 378 379 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 380 // default actuion automatically. Important for devices without direct input 381 // devices. 382 private boolean mShowDialogs = true; 383 384 BroadcastQueue mFgBroadcastQueue; 385 BroadcastQueue mBgBroadcastQueue; 386 // Convenient for easy iteration over the queues. Foreground is first 387 // so that dispatch of foreground broadcasts gets precedence. 388 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 389 390 BroadcastQueue broadcastQueueForIntent(Intent intent) { 391 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 392 if (DEBUG_BACKGROUND_BROADCAST) { 393 Slog.i(TAG, "Broadcast intent " + intent + " on " 394 + (isFg ? "foreground" : "background") 395 + " queue"); 396 } 397 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 398 } 399 400 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 401 for (BroadcastQueue queue : mBroadcastQueues) { 402 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 403 if (r != null) { 404 return r; 405 } 406 } 407 return null; 408 } 409 410 /** 411 * Activity we have told the window manager to have key focus. 412 */ 413 ActivityRecord mFocusedActivity = null; 414 415 /** 416 * List of intents that were used to start the most recent tasks. 417 */ 418 ArrayList<TaskRecord> mRecentTasks; 419 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 420 421 /** 422 * For addAppTask: cached of the last activity component that was added. 423 */ 424 ComponentName mLastAddedTaskComponent; 425 426 /** 427 * For addAppTask: cached of the last activity uid that was added. 428 */ 429 int mLastAddedTaskUid; 430 431 /** 432 * For addAppTask: cached of the last ActivityInfo that was added. 433 */ 434 ActivityInfo mLastAddedTaskActivity; 435 436 public class PendingAssistExtras extends Binder implements Runnable { 437 public final ActivityRecord activity; 438 public final Bundle extras; 439 public final Intent intent; 440 public final String hint; 441 public final int userHandle; 442 public boolean haveResult = false; 443 public Bundle result = null; 444 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 445 String _hint, int _userHandle) { 446 activity = _activity; 447 extras = _extras; 448 intent = _intent; 449 hint = _hint; 450 userHandle = _userHandle; 451 } 452 @Override 453 public void run() { 454 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 455 synchronized (this) { 456 haveResult = true; 457 notifyAll(); 458 } 459 } 460 } 461 462 final ArrayList<PendingAssistExtras> mPendingAssistExtras 463 = new ArrayList<PendingAssistExtras>(); 464 465 /** 466 * Process management. 467 */ 468 final ProcessList mProcessList = new ProcessList(); 469 470 /** 471 * All of the applications we currently have running organized by name. 472 * The keys are strings of the application package name (as 473 * returned by the package manager), and the keys are ApplicationRecord 474 * objects. 475 */ 476 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 477 478 /** 479 * Tracking long-term execution of processes to look for abuse and other 480 * bad app behavior. 481 */ 482 final ProcessStatsService mProcessStats; 483 484 /** 485 * The currently running isolated processes. 486 */ 487 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 488 489 /** 490 * Counter for assigning isolated process uids, to avoid frequently reusing the 491 * same ones. 492 */ 493 int mNextIsolatedProcessUid = 0; 494 495 /** 496 * The currently running heavy-weight process, if any. 497 */ 498 ProcessRecord mHeavyWeightProcess = null; 499 500 /** 501 * The last time that various processes have crashed. 502 */ 503 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 504 505 /** 506 * Information about a process that is currently marked as bad. 507 */ 508 static final class BadProcessInfo { 509 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 510 this.time = time; 511 this.shortMsg = shortMsg; 512 this.longMsg = longMsg; 513 this.stack = stack; 514 } 515 516 final long time; 517 final String shortMsg; 518 final String longMsg; 519 final String stack; 520 } 521 522 /** 523 * Set of applications that we consider to be bad, and will reject 524 * incoming broadcasts from (which the user has no control over). 525 * Processes are added to this set when they have crashed twice within 526 * a minimum amount of time; they are removed from it when they are 527 * later restarted (hopefully due to some user action). The value is the 528 * time it was added to the list. 529 */ 530 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 531 532 /** 533 * All of the processes we currently have running organized by pid. 534 * The keys are the pid running the application. 535 * 536 * <p>NOTE: This object is protected by its own lock, NOT the global 537 * activity manager lock! 538 */ 539 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 540 541 /** 542 * All of the processes that have been forced to be foreground. The key 543 * is the pid of the caller who requested it (we hold a death 544 * link on it). 545 */ 546 abstract class ForegroundToken implements IBinder.DeathRecipient { 547 int pid; 548 IBinder token; 549 } 550 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 551 552 /** 553 * List of records for processes that someone had tried to start before the 554 * system was ready. We don't start them at that point, but ensure they 555 * are started by the time booting is complete. 556 */ 557 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 558 559 /** 560 * List of persistent applications that are in the process 561 * of being started. 562 */ 563 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 564 565 /** 566 * Processes that are being forcibly torn down. 567 */ 568 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 569 570 /** 571 * List of running applications, sorted by recent usage. 572 * The first entry in the list is the least recently used. 573 */ 574 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 575 576 /** 577 * Where in mLruProcesses that the processes hosting activities start. 578 */ 579 int mLruProcessActivityStart = 0; 580 581 /** 582 * Where in mLruProcesses that the processes hosting services start. 583 * This is after (lower index) than mLruProcessesActivityStart. 584 */ 585 int mLruProcessServiceStart = 0; 586 587 /** 588 * List of processes that should gc as soon as things are idle. 589 */ 590 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 591 592 /** 593 * Processes we want to collect PSS data from. 594 */ 595 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 596 597 /** 598 * Last time we requested PSS data of all processes. 599 */ 600 long mLastFullPssTime = SystemClock.uptimeMillis(); 601 602 /** 603 * If set, the next time we collect PSS data we should do a full collection 604 * with data from native processes and the kernel. 605 */ 606 boolean mFullPssPending = false; 607 608 /** 609 * This is the process holding what we currently consider to be 610 * the "home" activity. 611 */ 612 ProcessRecord mHomeProcess; 613 614 /** 615 * This is the process holding the activity the user last visited that 616 * is in a different process from the one they are currently in. 617 */ 618 ProcessRecord mPreviousProcess; 619 620 /** 621 * The time at which the previous process was last visible. 622 */ 623 long mPreviousProcessVisibleTime; 624 625 /** 626 * Which uses have been started, so are allowed to run code. 627 */ 628 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 629 630 /** 631 * LRU list of history of current users. Most recently current is at the end. 632 */ 633 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 634 635 /** 636 * Constant array of the users that are currently started. 637 */ 638 int[] mStartedUserArray = new int[] { 0 }; 639 640 /** 641 * Registered observers of the user switching mechanics. 642 */ 643 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 644 = new RemoteCallbackList<IUserSwitchObserver>(); 645 646 /** 647 * Currently active user switch. 648 */ 649 Object mCurUserSwitchCallback; 650 651 /** 652 * Packages that the user has asked to have run in screen size 653 * compatibility mode instead of filling the screen. 654 */ 655 final CompatModePackages mCompatModePackages; 656 657 /** 658 * Set of IntentSenderRecord objects that are currently active. 659 */ 660 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 661 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 662 663 /** 664 * Fingerprints (hashCode()) of stack traces that we've 665 * already logged DropBox entries for. Guarded by itself. If 666 * something (rogue user app) forces this over 667 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 668 */ 669 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 670 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 671 672 /** 673 * Strict Mode background batched logging state. 674 * 675 * The string buffer is guarded by itself, and its lock is also 676 * used to determine if another batched write is already 677 * in-flight. 678 */ 679 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 680 681 /** 682 * Keeps track of all IIntentReceivers that have been registered for 683 * broadcasts. Hash keys are the receiver IBinder, hash value is 684 * a ReceiverList. 685 */ 686 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 687 new HashMap<IBinder, ReceiverList>(); 688 689 /** 690 * Resolver for broadcast intents to registered receivers. 691 * Holds BroadcastFilter (subclass of IntentFilter). 692 */ 693 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 694 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 695 @Override 696 protected boolean allowFilterResult( 697 BroadcastFilter filter, List<BroadcastFilter> dest) { 698 IBinder target = filter.receiverList.receiver.asBinder(); 699 for (int i=dest.size()-1; i>=0; i--) { 700 if (dest.get(i).receiverList.receiver.asBinder() == target) { 701 return false; 702 } 703 } 704 return true; 705 } 706 707 @Override 708 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 709 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 710 || userId == filter.owningUserId) { 711 return super.newResult(filter, match, userId); 712 } 713 return null; 714 } 715 716 @Override 717 protected BroadcastFilter[] newArray(int size) { 718 return new BroadcastFilter[size]; 719 } 720 721 @Override 722 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 723 return packageName.equals(filter.packageName); 724 } 725 }; 726 727 /** 728 * State of all active sticky broadcasts per user. Keys are the action of the 729 * sticky Intent, values are an ArrayList of all broadcasted intents with 730 * that action (which should usually be one). The SparseArray is keyed 731 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 732 * for stickies that are sent to all users. 733 */ 734 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 735 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 736 737 final ActiveServices mServices; 738 739 /** 740 * Backup/restore process management 741 */ 742 String mBackupAppName = null; 743 BackupRecord mBackupTarget = null; 744 745 final ProviderMap mProviderMap; 746 747 /** 748 * List of content providers who have clients waiting for them. The 749 * application is currently being launched and the provider will be 750 * removed from this list once it is published. 751 */ 752 final ArrayList<ContentProviderRecord> mLaunchingProviders 753 = new ArrayList<ContentProviderRecord>(); 754 755 /** 756 * File storing persisted {@link #mGrantedUriPermissions}. 757 */ 758 private final AtomicFile mGrantFile; 759 760 /** XML constants used in {@link #mGrantFile} */ 761 private static final String TAG_URI_GRANTS = "uri-grants"; 762 private static final String TAG_URI_GRANT = "uri-grant"; 763 private static final String ATTR_USER_HANDLE = "userHandle"; 764 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 765 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 766 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 767 private static final String ATTR_TARGET_PKG = "targetPkg"; 768 private static final String ATTR_URI = "uri"; 769 private static final String ATTR_MODE_FLAGS = "modeFlags"; 770 private static final String ATTR_CREATED_TIME = "createdTime"; 771 private static final String ATTR_PREFIX = "prefix"; 772 773 /** 774 * Global set of specific {@link Uri} permissions that have been granted. 775 * This optimized lookup structure maps from {@link UriPermission#targetUid} 776 * to {@link UriPermission#uri} to {@link UriPermission}. 777 */ 778 @GuardedBy("this") 779 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 780 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 781 782 public static class GrantUri { 783 public final int sourceUserId; 784 public final Uri uri; 785 public boolean prefix; 786 787 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 788 this.sourceUserId = sourceUserId; 789 this.uri = uri; 790 this.prefix = prefix; 791 } 792 793 @Override 794 public int hashCode() { 795 return toString().hashCode(); 796 } 797 798 @Override 799 public boolean equals(Object o) { 800 if (o instanceof GrantUri) { 801 GrantUri other = (GrantUri) o; 802 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 803 && prefix == other.prefix; 804 } 805 return false; 806 } 807 808 @Override 809 public String toString() { 810 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 811 if (prefix) result += " [prefix]"; 812 return result; 813 } 814 815 public String toSafeString() { 816 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 817 if (prefix) result += " [prefix]"; 818 return result; 819 } 820 821 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 822 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 823 ContentProvider.getUriWithoutUserId(uri), false); 824 } 825 } 826 827 CoreSettingsObserver mCoreSettingsObserver; 828 829 /** 830 * Thread-local storage used to carry caller permissions over through 831 * indirect content-provider access. 832 */ 833 private class Identity { 834 public int pid; 835 public int uid; 836 837 Identity(int _pid, int _uid) { 838 pid = _pid; 839 uid = _uid; 840 } 841 } 842 843 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 844 845 /** 846 * All information we have collected about the runtime performance of 847 * any user id that can impact battery performance. 848 */ 849 final BatteryStatsService mBatteryStatsService; 850 851 /** 852 * Information about component usage 853 */ 854 UsageStatsManagerInternal mUsageStatsService; 855 856 /** 857 * Information about and control over application operations 858 */ 859 final AppOpsService mAppOpsService; 860 861 /** 862 * Save recent tasks information across reboots. 863 */ 864 final TaskPersister mTaskPersister; 865 866 /** 867 * Current configuration information. HistoryRecord objects are given 868 * a reference to this object to indicate which configuration they are 869 * currently running in, so this object must be kept immutable. 870 */ 871 Configuration mConfiguration = new Configuration(); 872 873 /** 874 * Current sequencing integer of the configuration, for skipping old 875 * configurations. 876 */ 877 int mConfigurationSeq = 0; 878 879 /** 880 * Hardware-reported OpenGLES version. 881 */ 882 final int GL_ES_VERSION; 883 884 /** 885 * List of initialization arguments to pass to all processes when binding applications to them. 886 * For example, references to the commonly used services. 887 */ 888 HashMap<String, IBinder> mAppBindArgs; 889 890 /** 891 * Temporary to avoid allocations. Protected by main lock. 892 */ 893 final StringBuilder mStringBuilder = new StringBuilder(256); 894 895 /** 896 * Used to control how we initialize the service. 897 */ 898 ComponentName mTopComponent; 899 String mTopAction = Intent.ACTION_MAIN; 900 String mTopData; 901 boolean mProcessesReady = false; 902 boolean mSystemReady = false; 903 boolean mBooting = false; 904 boolean mCallFinishBooting = false; 905 boolean mBootAnimationComplete = false; 906 boolean mWaitingUpdate = false; 907 boolean mDidUpdate = false; 908 boolean mOnBattery = false; 909 boolean mLaunchWarningShown = false; 910 911 Context mContext; 912 913 int mFactoryTest; 914 915 boolean mCheckedForSetup; 916 917 /** 918 * The time at which we will allow normal application switches again, 919 * after a call to {@link #stopAppSwitches()}. 920 */ 921 long mAppSwitchesAllowedTime; 922 923 /** 924 * This is set to true after the first switch after mAppSwitchesAllowedTime 925 * is set; any switches after that will clear the time. 926 */ 927 boolean mDidAppSwitch; 928 929 /** 930 * Last time (in realtime) at which we checked for power usage. 931 */ 932 long mLastPowerCheckRealtime; 933 934 /** 935 * Last time (in uptime) at which we checked for power usage. 936 */ 937 long mLastPowerCheckUptime; 938 939 /** 940 * Set while we are wanting to sleep, to prevent any 941 * activities from being started/resumed. 942 */ 943 private boolean mSleeping = false; 944 945 /** 946 * Set while we are running a voice interaction. This overrides 947 * sleeping while it is active. 948 */ 949 private boolean mRunningVoice = false; 950 951 /** 952 * State of external calls telling us if the device is asleep. 953 */ 954 private boolean mWentToSleep = false; 955 956 /** 957 * State of external call telling us if the lock screen is shown. 958 */ 959 private boolean mLockScreenShown = false; 960 961 /** 962 * Set if we are shutting down the system, similar to sleeping. 963 */ 964 boolean mShuttingDown = false; 965 966 /** 967 * Current sequence id for oom_adj computation traversal. 968 */ 969 int mAdjSeq = 0; 970 971 /** 972 * Current sequence id for process LRU updating. 973 */ 974 int mLruSeq = 0; 975 976 /** 977 * Keep track of the non-cached/empty process we last found, to help 978 * determine how to distribute cached/empty processes next time. 979 */ 980 int mNumNonCachedProcs = 0; 981 982 /** 983 * Keep track of the number of cached hidden procs, to balance oom adj 984 * distribution between those and empty procs. 985 */ 986 int mNumCachedHiddenProcs = 0; 987 988 /** 989 * Keep track of the number of service processes we last found, to 990 * determine on the next iteration which should be B services. 991 */ 992 int mNumServiceProcs = 0; 993 int mNewNumAServiceProcs = 0; 994 int mNewNumServiceProcs = 0; 995 996 /** 997 * Allow the current computed overall memory level of the system to go down? 998 * This is set to false when we are killing processes for reasons other than 999 * memory management, so that the now smaller process list will not be taken as 1000 * an indication that memory is tighter. 1001 */ 1002 boolean mAllowLowerMemLevel = false; 1003 1004 /** 1005 * The last computed memory level, for holding when we are in a state that 1006 * processes are going away for other reasons. 1007 */ 1008 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1009 1010 /** 1011 * The last total number of process we have, to determine if changes actually look 1012 * like a shrinking number of process due to lower RAM. 1013 */ 1014 int mLastNumProcesses; 1015 1016 /** 1017 * The uptime of the last time we performed idle maintenance. 1018 */ 1019 long mLastIdleTime = SystemClock.uptimeMillis(); 1020 1021 /** 1022 * Total time spent with RAM that has been added in the past since the last idle time. 1023 */ 1024 long mLowRamTimeSinceLastIdle = 0; 1025 1026 /** 1027 * If RAM is currently low, when that horrible situation started. 1028 */ 1029 long mLowRamStartTime = 0; 1030 1031 /** 1032 * For reporting to battery stats the current top application. 1033 */ 1034 private String mCurResumedPackage = null; 1035 private int mCurResumedUid = -1; 1036 1037 /** 1038 * For reporting to battery stats the apps currently running foreground 1039 * service. The ProcessMap is package/uid tuples; each of these contain 1040 * an array of the currently foreground processes. 1041 */ 1042 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1043 = new ProcessMap<ArrayList<ProcessRecord>>(); 1044 1045 /** 1046 * This is set if we had to do a delayed dexopt of an app before launching 1047 * it, to increase the ANR timeouts in that case. 1048 */ 1049 boolean mDidDexOpt; 1050 1051 /** 1052 * Set if the systemServer made a call to enterSafeMode. 1053 */ 1054 boolean mSafeMode; 1055 1056 String mDebugApp = null; 1057 boolean mWaitForDebugger = false; 1058 boolean mDebugTransient = false; 1059 String mOrigDebugApp = null; 1060 boolean mOrigWaitForDebugger = false; 1061 boolean mAlwaysFinishActivities = false; 1062 IActivityController mController = null; 1063 String mProfileApp = null; 1064 ProcessRecord mProfileProc = null; 1065 String mProfileFile; 1066 ParcelFileDescriptor mProfileFd; 1067 int mSamplingInterval = 0; 1068 boolean mAutoStopProfiler = false; 1069 int mProfileType = 0; 1070 String mOpenGlTraceApp = null; 1071 1072 static class ProcessChangeItem { 1073 static final int CHANGE_ACTIVITIES = 1<<0; 1074 static final int CHANGE_PROCESS_STATE = 1<<1; 1075 int changes; 1076 int uid; 1077 int pid; 1078 int processState; 1079 boolean foregroundActivities; 1080 } 1081 1082 final RemoteCallbackList<IProcessObserver> mProcessObservers 1083 = new RemoteCallbackList<IProcessObserver>(); 1084 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1085 1086 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1087 = new ArrayList<ProcessChangeItem>(); 1088 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1089 = new ArrayList<ProcessChangeItem>(); 1090 1091 /** 1092 * Runtime CPU use collection thread. This object's lock is used to 1093 * perform synchronization with the thread (notifying it to run). 1094 */ 1095 final Thread mProcessCpuThread; 1096 1097 /** 1098 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1099 * Must acquire this object's lock when accessing it. 1100 * NOTE: this lock will be held while doing long operations (trawling 1101 * through all processes in /proc), so it should never be acquired by 1102 * any critical paths such as when holding the main activity manager lock. 1103 */ 1104 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1105 MONITOR_THREAD_CPU_USAGE); 1106 final AtomicLong mLastCpuTime = new AtomicLong(0); 1107 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1108 1109 long mLastWriteTime = 0; 1110 1111 /** 1112 * Used to retain an update lock when the foreground activity is in 1113 * immersive mode. 1114 */ 1115 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1116 1117 /** 1118 * Set to true after the system has finished booting. 1119 */ 1120 boolean mBooted = false; 1121 1122 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1123 int mProcessLimitOverride = -1; 1124 1125 WindowManagerService mWindowManager; 1126 1127 final ActivityThread mSystemThread; 1128 1129 // Holds the current foreground user's id 1130 int mCurrentUserId = 0; 1131 // Holds the target user's id during a user switch 1132 int mTargetUserId = UserHandle.USER_NULL; 1133 // If there are multiple profiles for the current user, their ids are here 1134 // Currently only the primary user can have managed profiles 1135 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1136 1137 /** 1138 * Mapping from each known user ID to the profile group ID it is associated with. 1139 */ 1140 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1141 1142 private UserManagerService mUserManager; 1143 1144 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1145 final ProcessRecord mApp; 1146 final int mPid; 1147 final IApplicationThread mAppThread; 1148 1149 AppDeathRecipient(ProcessRecord app, int pid, 1150 IApplicationThread thread) { 1151 if (localLOGV) Slog.v( 1152 TAG, "New death recipient " + this 1153 + " for thread " + thread.asBinder()); 1154 mApp = app; 1155 mPid = pid; 1156 mAppThread = thread; 1157 } 1158 1159 @Override 1160 public void binderDied() { 1161 if (localLOGV) Slog.v( 1162 TAG, "Death received in " + this 1163 + " for thread " + mAppThread.asBinder()); 1164 synchronized(ActivityManagerService.this) { 1165 appDiedLocked(mApp, mPid, mAppThread); 1166 } 1167 } 1168 } 1169 1170 static final int SHOW_ERROR_MSG = 1; 1171 static final int SHOW_NOT_RESPONDING_MSG = 2; 1172 static final int SHOW_FACTORY_ERROR_MSG = 3; 1173 static final int UPDATE_CONFIGURATION_MSG = 4; 1174 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1175 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1176 static final int SERVICE_TIMEOUT_MSG = 12; 1177 static final int UPDATE_TIME_ZONE = 13; 1178 static final int SHOW_UID_ERROR_MSG = 14; 1179 static final int IM_FEELING_LUCKY_MSG = 15; 1180 static final int PROC_START_TIMEOUT_MSG = 20; 1181 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1182 static final int KILL_APPLICATION_MSG = 22; 1183 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1184 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1185 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1186 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1187 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1188 static final int CLEAR_DNS_CACHE_MSG = 28; 1189 static final int UPDATE_HTTP_PROXY_MSG = 29; 1190 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1191 static final int DISPATCH_PROCESSES_CHANGED = 31; 1192 static final int DISPATCH_PROCESS_DIED = 32; 1193 static final int REPORT_MEM_USAGE_MSG = 33; 1194 static final int REPORT_USER_SWITCH_MSG = 34; 1195 static final int CONTINUE_USER_SWITCH_MSG = 35; 1196 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1197 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1198 static final int PERSIST_URI_GRANTS_MSG = 38; 1199 static final int REQUEST_ALL_PSS_MSG = 39; 1200 static final int START_PROFILES_MSG = 40; 1201 static final int UPDATE_TIME = 41; 1202 static final int SYSTEM_USER_START_MSG = 42; 1203 static final int SYSTEM_USER_CURRENT_MSG = 43; 1204 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1205 static final int FINISH_BOOTING_MSG = 45; 1206 static final int START_USER_SWITCH_MSG = 46; 1207 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1208 1209 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1210 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1211 static final int FIRST_COMPAT_MODE_MSG = 300; 1212 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1213 1214 AlertDialog mUidAlert; 1215 CompatModeDialog mCompatModeDialog; 1216 long mLastMemUsageReportTime = 0; 1217 1218 private LockToAppRequestDialog mLockToAppRequest; 1219 1220 /** 1221 * Flag whether the current user is a "monkey", i.e. whether 1222 * the UI is driven by a UI automation tool. 1223 */ 1224 private boolean mUserIsMonkey; 1225 1226 /** Flag whether the device has a Recents UI */ 1227 boolean mHasRecents; 1228 1229 /** The dimensions of the thumbnails in the Recents UI. */ 1230 int mThumbnailWidth; 1231 int mThumbnailHeight; 1232 1233 final ServiceThread mHandlerThread; 1234 final MainHandler mHandler; 1235 1236 final class MainHandler extends Handler { 1237 public MainHandler(Looper looper) { 1238 super(looper, null, true); 1239 } 1240 1241 @Override 1242 public void handleMessage(Message msg) { 1243 switch (msg.what) { 1244 case SHOW_ERROR_MSG: { 1245 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1246 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1247 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1248 synchronized (ActivityManagerService.this) { 1249 ProcessRecord proc = (ProcessRecord)data.get("app"); 1250 AppErrorResult res = (AppErrorResult) data.get("result"); 1251 if (proc != null && proc.crashDialog != null) { 1252 Slog.e(TAG, "App already has crash dialog: " + proc); 1253 if (res != null) { 1254 res.set(0); 1255 } 1256 return; 1257 } 1258 boolean isBackground = (UserHandle.getAppId(proc.uid) 1259 >= Process.FIRST_APPLICATION_UID 1260 && proc.pid != MY_PID); 1261 for (int userId : mCurrentProfileIds) { 1262 isBackground &= (proc.userId != userId); 1263 } 1264 if (isBackground && !showBackground) { 1265 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1266 if (res != null) { 1267 res.set(0); 1268 } 1269 return; 1270 } 1271 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1272 Dialog d = new AppErrorDialog(mContext, 1273 ActivityManagerService.this, res, proc); 1274 d.show(); 1275 proc.crashDialog = d; 1276 } else { 1277 // The device is asleep, so just pretend that the user 1278 // saw a crash dialog and hit "force quit". 1279 if (res != null) { 1280 res.set(0); 1281 } 1282 } 1283 } 1284 1285 ensureBootCompleted(); 1286 } break; 1287 case SHOW_NOT_RESPONDING_MSG: { 1288 synchronized (ActivityManagerService.this) { 1289 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1290 ProcessRecord proc = (ProcessRecord)data.get("app"); 1291 if (proc != null && proc.anrDialog != null) { 1292 Slog.e(TAG, "App already has anr dialog: " + proc); 1293 return; 1294 } 1295 1296 Intent intent = new Intent("android.intent.action.ANR"); 1297 if (!mProcessesReady) { 1298 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1299 | Intent.FLAG_RECEIVER_FOREGROUND); 1300 } 1301 broadcastIntentLocked(null, null, intent, 1302 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1303 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1304 1305 if (mShowDialogs) { 1306 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1307 mContext, proc, (ActivityRecord)data.get("activity"), 1308 msg.arg1 != 0); 1309 d.show(); 1310 proc.anrDialog = d; 1311 } else { 1312 // Just kill the app if there is no dialog to be shown. 1313 killAppAtUsersRequest(proc, null); 1314 } 1315 } 1316 1317 ensureBootCompleted(); 1318 } break; 1319 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1320 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1321 synchronized (ActivityManagerService.this) { 1322 ProcessRecord proc = (ProcessRecord) data.get("app"); 1323 if (proc == null) { 1324 Slog.e(TAG, "App not found when showing strict mode dialog."); 1325 break; 1326 } 1327 if (proc.crashDialog != null) { 1328 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1329 return; 1330 } 1331 AppErrorResult res = (AppErrorResult) data.get("result"); 1332 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1333 Dialog d = new StrictModeViolationDialog(mContext, 1334 ActivityManagerService.this, res, proc); 1335 d.show(); 1336 proc.crashDialog = d; 1337 } else { 1338 // The device is asleep, so just pretend that the user 1339 // saw a crash dialog and hit "force quit". 1340 res.set(0); 1341 } 1342 } 1343 ensureBootCompleted(); 1344 } break; 1345 case SHOW_FACTORY_ERROR_MSG: { 1346 Dialog d = new FactoryErrorDialog( 1347 mContext, msg.getData().getCharSequence("msg")); 1348 d.show(); 1349 ensureBootCompleted(); 1350 } break; 1351 case UPDATE_CONFIGURATION_MSG: { 1352 final ContentResolver resolver = mContext.getContentResolver(); 1353 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1354 } break; 1355 case GC_BACKGROUND_PROCESSES_MSG: { 1356 synchronized (ActivityManagerService.this) { 1357 performAppGcsIfAppropriateLocked(); 1358 } 1359 } break; 1360 case WAIT_FOR_DEBUGGER_MSG: { 1361 synchronized (ActivityManagerService.this) { 1362 ProcessRecord app = (ProcessRecord)msg.obj; 1363 if (msg.arg1 != 0) { 1364 if (!app.waitedForDebugger) { 1365 Dialog d = new AppWaitingForDebuggerDialog( 1366 ActivityManagerService.this, 1367 mContext, app); 1368 app.waitDialog = d; 1369 app.waitedForDebugger = true; 1370 d.show(); 1371 } 1372 } else { 1373 if (app.waitDialog != null) { 1374 app.waitDialog.dismiss(); 1375 app.waitDialog = null; 1376 } 1377 } 1378 } 1379 } break; 1380 case SERVICE_TIMEOUT_MSG: { 1381 if (mDidDexOpt) { 1382 mDidDexOpt = false; 1383 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1384 nmsg.obj = msg.obj; 1385 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1386 return; 1387 } 1388 mServices.serviceTimeout((ProcessRecord)msg.obj); 1389 } break; 1390 case UPDATE_TIME_ZONE: { 1391 synchronized (ActivityManagerService.this) { 1392 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1393 ProcessRecord r = mLruProcesses.get(i); 1394 if (r.thread != null) { 1395 try { 1396 r.thread.updateTimeZone(); 1397 } catch (RemoteException ex) { 1398 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1399 } 1400 } 1401 } 1402 } 1403 } break; 1404 case CLEAR_DNS_CACHE_MSG: { 1405 synchronized (ActivityManagerService.this) { 1406 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1407 ProcessRecord r = mLruProcesses.get(i); 1408 if (r.thread != null) { 1409 try { 1410 r.thread.clearDnsCache(); 1411 } catch (RemoteException ex) { 1412 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1413 } 1414 } 1415 } 1416 } 1417 } break; 1418 case UPDATE_HTTP_PROXY_MSG: { 1419 ProxyInfo proxy = (ProxyInfo)msg.obj; 1420 String host = ""; 1421 String port = ""; 1422 String exclList = ""; 1423 Uri pacFileUrl = Uri.EMPTY; 1424 if (proxy != null) { 1425 host = proxy.getHost(); 1426 port = Integer.toString(proxy.getPort()); 1427 exclList = proxy.getExclusionListAsString(); 1428 pacFileUrl = proxy.getPacFileUrl(); 1429 } 1430 synchronized (ActivityManagerService.this) { 1431 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1432 ProcessRecord r = mLruProcesses.get(i); 1433 if (r.thread != null) { 1434 try { 1435 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1436 } catch (RemoteException ex) { 1437 Slog.w(TAG, "Failed to update http proxy for: " + 1438 r.info.processName); 1439 } 1440 } 1441 } 1442 } 1443 } break; 1444 case SHOW_UID_ERROR_MSG: { 1445 String title = "System UIDs Inconsistent"; 1446 String text = "UIDs on the system are inconsistent, you need to wipe your" 1447 + " data partition or your device will be unstable."; 1448 Log.e(TAG, title + ": " + text); 1449 if (mShowDialogs) { 1450 // XXX This is a temporary dialog, no need to localize. 1451 AlertDialog d = new BaseErrorDialog(mContext); 1452 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1453 d.setCancelable(false); 1454 d.setTitle(title); 1455 d.setMessage(text); 1456 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1457 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1458 mUidAlert = d; 1459 d.show(); 1460 } 1461 } break; 1462 case IM_FEELING_LUCKY_MSG: { 1463 if (mUidAlert != null) { 1464 mUidAlert.dismiss(); 1465 mUidAlert = null; 1466 } 1467 } break; 1468 case PROC_START_TIMEOUT_MSG: { 1469 if (mDidDexOpt) { 1470 mDidDexOpt = false; 1471 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1472 nmsg.obj = msg.obj; 1473 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1474 return; 1475 } 1476 ProcessRecord app = (ProcessRecord)msg.obj; 1477 synchronized (ActivityManagerService.this) { 1478 processStartTimedOutLocked(app); 1479 } 1480 } break; 1481 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1482 synchronized (ActivityManagerService.this) { 1483 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1484 } 1485 } break; 1486 case KILL_APPLICATION_MSG: { 1487 synchronized (ActivityManagerService.this) { 1488 int appid = msg.arg1; 1489 boolean restart = (msg.arg2 == 1); 1490 Bundle bundle = (Bundle)msg.obj; 1491 String pkg = bundle.getString("pkg"); 1492 String reason = bundle.getString("reason"); 1493 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1494 false, UserHandle.USER_ALL, reason); 1495 } 1496 } break; 1497 case FINALIZE_PENDING_INTENT_MSG: { 1498 ((PendingIntentRecord)msg.obj).completeFinalize(); 1499 } break; 1500 case POST_HEAVY_NOTIFICATION_MSG: { 1501 INotificationManager inm = NotificationManager.getService(); 1502 if (inm == null) { 1503 return; 1504 } 1505 1506 ActivityRecord root = (ActivityRecord)msg.obj; 1507 ProcessRecord process = root.app; 1508 if (process == null) { 1509 return; 1510 } 1511 1512 try { 1513 Context context = mContext.createPackageContext(process.info.packageName, 0); 1514 String text = mContext.getString(R.string.heavy_weight_notification, 1515 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1516 Notification notification = new Notification(); 1517 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1518 notification.when = 0; 1519 notification.flags = Notification.FLAG_ONGOING_EVENT; 1520 notification.tickerText = text; 1521 notification.defaults = 0; // please be quiet 1522 notification.sound = null; 1523 notification.vibrate = null; 1524 notification.color = mContext.getResources().getColor( 1525 com.android.internal.R.color.system_notification_accent_color); 1526 notification.setLatestEventInfo(context, text, 1527 mContext.getText(R.string.heavy_weight_notification_detail), 1528 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1529 PendingIntent.FLAG_CANCEL_CURRENT, null, 1530 new UserHandle(root.userId))); 1531 1532 try { 1533 int[] outId = new int[1]; 1534 inm.enqueueNotificationWithTag("android", "android", null, 1535 R.string.heavy_weight_notification, 1536 notification, outId, root.userId); 1537 } catch (RuntimeException e) { 1538 Slog.w(ActivityManagerService.TAG, 1539 "Error showing notification for heavy-weight app", e); 1540 } catch (RemoteException e) { 1541 } 1542 } catch (NameNotFoundException e) { 1543 Slog.w(TAG, "Unable to create context for heavy notification", e); 1544 } 1545 } break; 1546 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1547 INotificationManager inm = NotificationManager.getService(); 1548 if (inm == null) { 1549 return; 1550 } 1551 try { 1552 inm.cancelNotificationWithTag("android", null, 1553 R.string.heavy_weight_notification, msg.arg1); 1554 } catch (RuntimeException e) { 1555 Slog.w(ActivityManagerService.TAG, 1556 "Error canceling notification for service", e); 1557 } catch (RemoteException e) { 1558 } 1559 } break; 1560 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1561 synchronized (ActivityManagerService.this) { 1562 checkExcessivePowerUsageLocked(true); 1563 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1564 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1565 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1566 } 1567 } break; 1568 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1569 synchronized (ActivityManagerService.this) { 1570 ActivityRecord ar = (ActivityRecord)msg.obj; 1571 if (mCompatModeDialog != null) { 1572 if (mCompatModeDialog.mAppInfo.packageName.equals( 1573 ar.info.applicationInfo.packageName)) { 1574 return; 1575 } 1576 mCompatModeDialog.dismiss(); 1577 mCompatModeDialog = null; 1578 } 1579 if (ar != null && false) { 1580 if (mCompatModePackages.getPackageAskCompatModeLocked( 1581 ar.packageName)) { 1582 int mode = mCompatModePackages.computeCompatModeLocked( 1583 ar.info.applicationInfo); 1584 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1585 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1586 mCompatModeDialog = new CompatModeDialog( 1587 ActivityManagerService.this, mContext, 1588 ar.info.applicationInfo); 1589 mCompatModeDialog.show(); 1590 } 1591 } 1592 } 1593 } 1594 break; 1595 } 1596 case DISPATCH_PROCESSES_CHANGED: { 1597 dispatchProcessesChanged(); 1598 break; 1599 } 1600 case DISPATCH_PROCESS_DIED: { 1601 final int pid = msg.arg1; 1602 final int uid = msg.arg2; 1603 dispatchProcessDied(pid, uid); 1604 break; 1605 } 1606 case REPORT_MEM_USAGE_MSG: { 1607 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1608 Thread thread = new Thread() { 1609 @Override public void run() { 1610 final SparseArray<ProcessMemInfo> infoMap 1611 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1612 for (int i=0, N=memInfos.size(); i<N; i++) { 1613 ProcessMemInfo mi = memInfos.get(i); 1614 infoMap.put(mi.pid, mi); 1615 } 1616 updateCpuStatsNow(); 1617 synchronized (mProcessCpuTracker) { 1618 final int N = mProcessCpuTracker.countStats(); 1619 for (int i=0; i<N; i++) { 1620 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1621 if (st.vsize > 0) { 1622 long pss = Debug.getPss(st.pid, null); 1623 if (pss > 0) { 1624 if (infoMap.indexOfKey(st.pid) < 0) { 1625 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1626 ProcessList.NATIVE_ADJ, -1, "native", null); 1627 mi.pss = pss; 1628 memInfos.add(mi); 1629 } 1630 } 1631 } 1632 } 1633 } 1634 1635 long totalPss = 0; 1636 for (int i=0, N=memInfos.size(); i<N; i++) { 1637 ProcessMemInfo mi = memInfos.get(i); 1638 if (mi.pss == 0) { 1639 mi.pss = Debug.getPss(mi.pid, null); 1640 } 1641 totalPss += mi.pss; 1642 } 1643 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1644 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1645 if (lhs.oomAdj != rhs.oomAdj) { 1646 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1647 } 1648 if (lhs.pss != rhs.pss) { 1649 return lhs.pss < rhs.pss ? 1 : -1; 1650 } 1651 return 0; 1652 } 1653 }); 1654 1655 StringBuilder tag = new StringBuilder(128); 1656 StringBuilder stack = new StringBuilder(128); 1657 tag.append("Low on memory -- "); 1658 appendMemBucket(tag, totalPss, "total", false); 1659 appendMemBucket(stack, totalPss, "total", true); 1660 1661 StringBuilder logBuilder = new StringBuilder(1024); 1662 logBuilder.append("Low on memory:\n"); 1663 1664 boolean firstLine = true; 1665 int lastOomAdj = Integer.MIN_VALUE; 1666 for (int i=0, N=memInfos.size(); i<N; i++) { 1667 ProcessMemInfo mi = memInfos.get(i); 1668 1669 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1670 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1671 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1672 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1673 if (lastOomAdj != mi.oomAdj) { 1674 lastOomAdj = mi.oomAdj; 1675 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1676 tag.append(" / "); 1677 } 1678 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1679 if (firstLine) { 1680 stack.append(":"); 1681 firstLine = false; 1682 } 1683 stack.append("\n\t at "); 1684 } else { 1685 stack.append("$"); 1686 } 1687 } else { 1688 tag.append(" "); 1689 stack.append("$"); 1690 } 1691 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1692 appendMemBucket(tag, mi.pss, mi.name, false); 1693 } 1694 appendMemBucket(stack, mi.pss, mi.name, true); 1695 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1696 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1697 stack.append("("); 1698 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1699 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1700 stack.append(DUMP_MEM_OOM_LABEL[k]); 1701 stack.append(":"); 1702 stack.append(DUMP_MEM_OOM_ADJ[k]); 1703 } 1704 } 1705 stack.append(")"); 1706 } 1707 } 1708 1709 logBuilder.append(" "); 1710 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1711 logBuilder.append(' '); 1712 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1713 logBuilder.append(' '); 1714 ProcessList.appendRamKb(logBuilder, mi.pss); 1715 logBuilder.append(" kB: "); 1716 logBuilder.append(mi.name); 1717 logBuilder.append(" ("); 1718 logBuilder.append(mi.pid); 1719 logBuilder.append(") "); 1720 logBuilder.append(mi.adjType); 1721 logBuilder.append('\n'); 1722 if (mi.adjReason != null) { 1723 logBuilder.append(" "); 1724 logBuilder.append(mi.adjReason); 1725 logBuilder.append('\n'); 1726 } 1727 } 1728 1729 logBuilder.append(" "); 1730 ProcessList.appendRamKb(logBuilder, totalPss); 1731 logBuilder.append(" kB: TOTAL\n"); 1732 1733 long[] infos = new long[Debug.MEMINFO_COUNT]; 1734 Debug.getMemInfo(infos); 1735 logBuilder.append(" MemInfo: "); 1736 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1737 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1738 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1739 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1740 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1741 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1742 logBuilder.append(" ZRAM: "); 1743 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1744 logBuilder.append(" kB RAM, "); 1745 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1746 logBuilder.append(" kB swap total, "); 1747 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1748 logBuilder.append(" kB swap free\n"); 1749 } 1750 Slog.i(TAG, logBuilder.toString()); 1751 1752 StringBuilder dropBuilder = new StringBuilder(1024); 1753 /* 1754 StringWriter oomSw = new StringWriter(); 1755 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1756 StringWriter catSw = new StringWriter(); 1757 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1758 String[] emptyArgs = new String[] { }; 1759 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1760 oomPw.flush(); 1761 String oomString = oomSw.toString(); 1762 */ 1763 dropBuilder.append(stack); 1764 dropBuilder.append('\n'); 1765 dropBuilder.append('\n'); 1766 dropBuilder.append(logBuilder); 1767 dropBuilder.append('\n'); 1768 /* 1769 dropBuilder.append(oomString); 1770 dropBuilder.append('\n'); 1771 */ 1772 StringWriter catSw = new StringWriter(); 1773 synchronized (ActivityManagerService.this) { 1774 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1775 String[] emptyArgs = new String[] { }; 1776 catPw.println(); 1777 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1778 catPw.println(); 1779 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1780 false, false, null); 1781 catPw.println(); 1782 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1783 catPw.flush(); 1784 } 1785 dropBuilder.append(catSw.toString()); 1786 addErrorToDropBox("lowmem", null, "system_server", null, 1787 null, tag.toString(), dropBuilder.toString(), null, null); 1788 //Slog.i(TAG, "Sent to dropbox:"); 1789 //Slog.i(TAG, dropBuilder.toString()); 1790 synchronized (ActivityManagerService.this) { 1791 long now = SystemClock.uptimeMillis(); 1792 if (mLastMemUsageReportTime < now) { 1793 mLastMemUsageReportTime = now; 1794 } 1795 } 1796 } 1797 }; 1798 thread.start(); 1799 break; 1800 } 1801 case START_USER_SWITCH_MSG: { 1802 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1803 break; 1804 } 1805 case REPORT_USER_SWITCH_MSG: { 1806 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1807 break; 1808 } 1809 case CONTINUE_USER_SWITCH_MSG: { 1810 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1811 break; 1812 } 1813 case USER_SWITCH_TIMEOUT_MSG: { 1814 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1815 break; 1816 } 1817 case IMMERSIVE_MODE_LOCK_MSG: { 1818 final boolean nextState = (msg.arg1 != 0); 1819 if (mUpdateLock.isHeld() != nextState) { 1820 if (DEBUG_IMMERSIVE) { 1821 final ActivityRecord r = (ActivityRecord) msg.obj; 1822 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1823 } 1824 if (nextState) { 1825 mUpdateLock.acquire(); 1826 } else { 1827 mUpdateLock.release(); 1828 } 1829 } 1830 break; 1831 } 1832 case PERSIST_URI_GRANTS_MSG: { 1833 writeGrantedUriPermissions(); 1834 break; 1835 } 1836 case REQUEST_ALL_PSS_MSG: { 1837 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1838 break; 1839 } 1840 case START_PROFILES_MSG: { 1841 synchronized (ActivityManagerService.this) { 1842 startProfilesLocked(); 1843 } 1844 break; 1845 } 1846 case UPDATE_TIME: { 1847 synchronized (ActivityManagerService.this) { 1848 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1849 ProcessRecord r = mLruProcesses.get(i); 1850 if (r.thread != null) { 1851 try { 1852 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1853 } catch (RemoteException ex) { 1854 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1855 } 1856 } 1857 } 1858 } 1859 break; 1860 } 1861 case SYSTEM_USER_START_MSG: { 1862 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1863 Integer.toString(msg.arg1), msg.arg1); 1864 mSystemServiceManager.startUser(msg.arg1); 1865 break; 1866 } 1867 case SYSTEM_USER_CURRENT_MSG: { 1868 mBatteryStatsService.noteEvent( 1869 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1870 Integer.toString(msg.arg2), msg.arg2); 1871 mBatteryStatsService.noteEvent( 1872 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1873 Integer.toString(msg.arg1), msg.arg1); 1874 mSystemServiceManager.switchUser(msg.arg1); 1875 mLockToAppRequest.clearPrompt(); 1876 break; 1877 } 1878 case ENTER_ANIMATION_COMPLETE_MSG: { 1879 synchronized (ActivityManagerService.this) { 1880 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1881 if (r != null && r.app != null && r.app.thread != null) { 1882 try { 1883 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1884 } catch (RemoteException e) { 1885 } 1886 } 1887 } 1888 break; 1889 } 1890 case FINISH_BOOTING_MSG: { 1891 if (msg.arg1 != 0) { 1892 finishBooting(); 1893 } 1894 if (msg.arg2 != 0) { 1895 enableScreenAfterBoot(); 1896 } 1897 break; 1898 } 1899 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1900 try { 1901 Locale l = (Locale) msg.obj; 1902 IBinder service = ServiceManager.getService("mount"); 1903 IMountService mountService = IMountService.Stub.asInterface(service); 1904 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1905 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1906 } catch (RemoteException e) { 1907 Log.e(TAG, "Error storing locale for decryption UI", e); 1908 } 1909 break; 1910 } 1911 } 1912 } 1913 }; 1914 1915 static final int COLLECT_PSS_BG_MSG = 1; 1916 1917 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1918 @Override 1919 public void handleMessage(Message msg) { 1920 switch (msg.what) { 1921 case COLLECT_PSS_BG_MSG: { 1922 long start = SystemClock.uptimeMillis(); 1923 MemInfoReader memInfo = null; 1924 synchronized (ActivityManagerService.this) { 1925 if (mFullPssPending) { 1926 mFullPssPending = false; 1927 memInfo = new MemInfoReader(); 1928 } 1929 } 1930 if (memInfo != null) { 1931 updateCpuStatsNow(); 1932 long nativeTotalPss = 0; 1933 synchronized (mProcessCpuTracker) { 1934 final int N = mProcessCpuTracker.countStats(); 1935 for (int j=0; j<N; j++) { 1936 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1937 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1938 // This is definitely an application process; skip it. 1939 continue; 1940 } 1941 synchronized (mPidsSelfLocked) { 1942 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1943 // This is one of our own processes; skip it. 1944 continue; 1945 } 1946 } 1947 nativeTotalPss += Debug.getPss(st.pid, null); 1948 } 1949 } 1950 memInfo.readMemInfo(); 1951 synchronized (ActivityManagerService.this) { 1952 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1953 + (SystemClock.uptimeMillis()-start) + "ms"); 1954 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1955 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1956 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1957 +memInfo.getSlabSizeKb(), 1958 nativeTotalPss); 1959 } 1960 } 1961 1962 int i=0, num=0; 1963 long[] tmp = new long[1]; 1964 do { 1965 ProcessRecord proc; 1966 int procState; 1967 int pid; 1968 synchronized (ActivityManagerService.this) { 1969 if (i >= mPendingPssProcesses.size()) { 1970 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1971 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1972 mPendingPssProcesses.clear(); 1973 return; 1974 } 1975 proc = mPendingPssProcesses.get(i); 1976 procState = proc.pssProcState; 1977 if (proc.thread != null && procState == proc.setProcState) { 1978 pid = proc.pid; 1979 } else { 1980 proc = null; 1981 pid = 0; 1982 } 1983 i++; 1984 } 1985 if (proc != null) { 1986 long pss = Debug.getPss(pid, tmp); 1987 synchronized (ActivityManagerService.this) { 1988 if (proc.thread != null && proc.setProcState == procState 1989 && proc.pid == pid) { 1990 num++; 1991 proc.lastPssTime = SystemClock.uptimeMillis(); 1992 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1993 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1994 + ": " + pss + " lastPss=" + proc.lastPss 1995 + " state=" + ProcessList.makeProcStateString(procState)); 1996 if (proc.initialIdlePss == 0) { 1997 proc.initialIdlePss = pss; 1998 } 1999 proc.lastPss = pss; 2000 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 2001 proc.lastCachedPss = pss; 2002 } 2003 } 2004 } 2005 } 2006 } while (true); 2007 } 2008 } 2009 } 2010 }; 2011 2012 /** 2013 * Monitor for package changes and update our internal state. 2014 */ 2015 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 2016 @Override 2017 public void onPackageRemoved(String packageName, int uid) { 2018 // Remove all tasks with activities in the specified package from the list of recent tasks 2019 final int eventUserId = getChangingUserId(); 2020 synchronized (ActivityManagerService.this) { 2021 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2022 TaskRecord tr = mRecentTasks.get(i); 2023 if (tr.userId != eventUserId) continue; 2024 2025 ComponentName cn = tr.intent.getComponent(); 2026 if (cn != null && cn.getPackageName().equals(packageName)) { 2027 // If the package name matches, remove the task and kill the process 2028 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2029 } 2030 } 2031 } 2032 } 2033 2034 @Override 2035 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2036 onPackageModified(packageName); 2037 return true; 2038 } 2039 2040 @Override 2041 public void onPackageModified(String packageName) { 2042 final int eventUserId = getChangingUserId(); 2043 final IPackageManager pm = AppGlobals.getPackageManager(); 2044 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2045 new ArrayList<Pair<Intent, Integer>>(); 2046 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2047 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2048 // Copy the list of recent tasks so that we don't hold onto the lock on 2049 // ActivityManagerService for long periods while checking if components exist. 2050 synchronized (ActivityManagerService.this) { 2051 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2052 TaskRecord tr = mRecentTasks.get(i); 2053 if (tr.userId != eventUserId) continue; 2054 2055 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2056 } 2057 } 2058 // Check the recent tasks and filter out all tasks with components that no longer exist. 2059 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2060 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2061 ComponentName cn = p.first.getComponent(); 2062 if (cn != null && cn.getPackageName().equals(packageName)) { 2063 if (componentsKnownToExist.contains(cn)) { 2064 // If we know that the component still exists in the package, then skip 2065 continue; 2066 } 2067 try { 2068 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 2069 if (info != null) { 2070 componentsKnownToExist.add(cn); 2071 } else { 2072 tasksToRemove.add(p.second); 2073 } 2074 } catch (RemoteException e) { 2075 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 2076 } 2077 } 2078 } 2079 // Prune all the tasks with removed components from the list of recent tasks 2080 synchronized (ActivityManagerService.this) { 2081 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2082 // Remove the task but don't kill the process (since other components in that 2083 // package may still be running and in the background) 2084 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2085 } 2086 } 2087 } 2088 2089 @Override 2090 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2091 // Force stop the specified packages 2092 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2093 if (packages != null) { 2094 for (String pkg : packages) { 2095 synchronized (ActivityManagerService.this) { 2096 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2097 userId, "finished booting")) { 2098 return true; 2099 } 2100 } 2101 } 2102 } 2103 return false; 2104 } 2105 }; 2106 2107 public void setSystemProcess() { 2108 try { 2109 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2110 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2111 ServiceManager.addService("meminfo", new MemBinder(this)); 2112 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2113 ServiceManager.addService("dbinfo", new DbBinder(this)); 2114 if (MONITOR_CPU_USAGE) { 2115 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2116 } 2117 ServiceManager.addService("permission", new PermissionController(this)); 2118 2119 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2120 "android", STOCK_PM_FLAGS); 2121 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2122 2123 synchronized (this) { 2124 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2125 app.persistent = true; 2126 app.pid = MY_PID; 2127 app.maxAdj = ProcessList.SYSTEM_ADJ; 2128 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2129 mProcessNames.put(app.processName, app.uid, app); 2130 synchronized (mPidsSelfLocked) { 2131 mPidsSelfLocked.put(app.pid, app); 2132 } 2133 updateLruProcessLocked(app, false, null); 2134 updateOomAdjLocked(); 2135 } 2136 } catch (PackageManager.NameNotFoundException e) { 2137 throw new RuntimeException( 2138 "Unable to find android system package", e); 2139 } 2140 } 2141 2142 public void setWindowManager(WindowManagerService wm) { 2143 mWindowManager = wm; 2144 mStackSupervisor.setWindowManager(wm); 2145 } 2146 2147 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2148 mUsageStatsService = usageStatsManager; 2149 } 2150 2151 public void startObservingNativeCrashes() { 2152 final NativeCrashListener ncl = new NativeCrashListener(this); 2153 ncl.start(); 2154 } 2155 2156 public IAppOpsService getAppOpsService() { 2157 return mAppOpsService; 2158 } 2159 2160 static class MemBinder extends Binder { 2161 ActivityManagerService mActivityManagerService; 2162 MemBinder(ActivityManagerService activityManagerService) { 2163 mActivityManagerService = activityManagerService; 2164 } 2165 2166 @Override 2167 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2168 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2169 != PackageManager.PERMISSION_GRANTED) { 2170 pw.println("Permission Denial: can't dump meminfo from from pid=" 2171 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2172 + " without permission " + android.Manifest.permission.DUMP); 2173 return; 2174 } 2175 2176 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2177 } 2178 } 2179 2180 static class GraphicsBinder extends Binder { 2181 ActivityManagerService mActivityManagerService; 2182 GraphicsBinder(ActivityManagerService activityManagerService) { 2183 mActivityManagerService = activityManagerService; 2184 } 2185 2186 @Override 2187 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2188 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2189 != PackageManager.PERMISSION_GRANTED) { 2190 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2191 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2192 + " without permission " + android.Manifest.permission.DUMP); 2193 return; 2194 } 2195 2196 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2197 } 2198 } 2199 2200 static class DbBinder extends Binder { 2201 ActivityManagerService mActivityManagerService; 2202 DbBinder(ActivityManagerService activityManagerService) { 2203 mActivityManagerService = activityManagerService; 2204 } 2205 2206 @Override 2207 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2208 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2209 != PackageManager.PERMISSION_GRANTED) { 2210 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2211 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2212 + " without permission " + android.Manifest.permission.DUMP); 2213 return; 2214 } 2215 2216 mActivityManagerService.dumpDbInfo(fd, pw, args); 2217 } 2218 } 2219 2220 static class CpuBinder extends Binder { 2221 ActivityManagerService mActivityManagerService; 2222 CpuBinder(ActivityManagerService activityManagerService) { 2223 mActivityManagerService = activityManagerService; 2224 } 2225 2226 @Override 2227 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2228 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2229 != PackageManager.PERMISSION_GRANTED) { 2230 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2231 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2232 + " without permission " + android.Manifest.permission.DUMP); 2233 return; 2234 } 2235 2236 synchronized (mActivityManagerService.mProcessCpuTracker) { 2237 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2238 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2239 SystemClock.uptimeMillis())); 2240 } 2241 } 2242 } 2243 2244 public static final class Lifecycle extends SystemService { 2245 private final ActivityManagerService mService; 2246 2247 public Lifecycle(Context context) { 2248 super(context); 2249 mService = new ActivityManagerService(context); 2250 } 2251 2252 @Override 2253 public void onStart() { 2254 mService.start(); 2255 } 2256 2257 public ActivityManagerService getService() { 2258 return mService; 2259 } 2260 } 2261 2262 // Note: This method is invoked on the main thread but may need to attach various 2263 // handlers to other threads. So take care to be explicit about the looper. 2264 public ActivityManagerService(Context systemContext) { 2265 mContext = systemContext; 2266 mFactoryTest = FactoryTest.getMode(); 2267 mSystemThread = ActivityThread.currentActivityThread(); 2268 2269 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2270 2271 mHandlerThread = new ServiceThread(TAG, 2272 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2273 mHandlerThread.start(); 2274 mHandler = new MainHandler(mHandlerThread.getLooper()); 2275 2276 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2277 "foreground", BROADCAST_FG_TIMEOUT, false); 2278 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2279 "background", BROADCAST_BG_TIMEOUT, true); 2280 mBroadcastQueues[0] = mFgBroadcastQueue; 2281 mBroadcastQueues[1] = mBgBroadcastQueue; 2282 2283 mServices = new ActiveServices(this); 2284 mProviderMap = new ProviderMap(this); 2285 2286 // TODO: Move creation of battery stats service outside of activity manager service. 2287 File dataDir = Environment.getDataDirectory(); 2288 File systemDir = new File(dataDir, "system"); 2289 systemDir.mkdirs(); 2290 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2291 mBatteryStatsService.getActiveStatistics().readLocked(); 2292 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2293 mOnBattery = DEBUG_POWER ? true 2294 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2295 mBatteryStatsService.getActiveStatistics().setCallback(this); 2296 2297 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2298 2299 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2300 2301 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2302 2303 // User 0 is the first and only user that runs at boot. 2304 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2305 mUserLru.add(Integer.valueOf(0)); 2306 updateStartedUserArrayLocked(); 2307 2308 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2309 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2310 2311 mConfiguration.setToDefaults(); 2312 mConfiguration.setLocale(Locale.getDefault()); 2313 2314 mConfigurationSeq = mConfiguration.seq = 1; 2315 mProcessCpuTracker.init(); 2316 2317 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2318 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2319 mStackSupervisor = new ActivityStackSupervisor(this); 2320 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2321 2322 mProcessCpuThread = new Thread("CpuTracker") { 2323 @Override 2324 public void run() { 2325 while (true) { 2326 try { 2327 try { 2328 synchronized(this) { 2329 final long now = SystemClock.uptimeMillis(); 2330 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2331 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2332 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2333 // + ", write delay=" + nextWriteDelay); 2334 if (nextWriteDelay < nextCpuDelay) { 2335 nextCpuDelay = nextWriteDelay; 2336 } 2337 if (nextCpuDelay > 0) { 2338 mProcessCpuMutexFree.set(true); 2339 this.wait(nextCpuDelay); 2340 } 2341 } 2342 } catch (InterruptedException e) { 2343 } 2344 updateCpuStatsNow(); 2345 } catch (Exception e) { 2346 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2347 } 2348 } 2349 } 2350 }; 2351 2352 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2353 2354 Watchdog.getInstance().addMonitor(this); 2355 Watchdog.getInstance().addThread(mHandler); 2356 } 2357 2358 public void setSystemServiceManager(SystemServiceManager mgr) { 2359 mSystemServiceManager = mgr; 2360 } 2361 2362 private void start() { 2363 Process.removeAllProcessGroups(); 2364 mProcessCpuThread.start(); 2365 2366 mBatteryStatsService.publish(mContext); 2367 mAppOpsService.publish(mContext); 2368 Slog.d("AppOps", "AppOpsService published"); 2369 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2370 } 2371 2372 public void initPowerManagement() { 2373 mStackSupervisor.initPowerManagement(); 2374 mBatteryStatsService.initPowerManagement(); 2375 } 2376 2377 @Override 2378 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2379 throws RemoteException { 2380 if (code == SYSPROPS_TRANSACTION) { 2381 // We need to tell all apps about the system property change. 2382 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2383 synchronized(this) { 2384 final int NP = mProcessNames.getMap().size(); 2385 for (int ip=0; ip<NP; ip++) { 2386 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2387 final int NA = apps.size(); 2388 for (int ia=0; ia<NA; ia++) { 2389 ProcessRecord app = apps.valueAt(ia); 2390 if (app.thread != null) { 2391 procs.add(app.thread.asBinder()); 2392 } 2393 } 2394 } 2395 } 2396 2397 int N = procs.size(); 2398 for (int i=0; i<N; i++) { 2399 Parcel data2 = Parcel.obtain(); 2400 try { 2401 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2402 } catch (RemoteException e) { 2403 } 2404 data2.recycle(); 2405 } 2406 } 2407 try { 2408 return super.onTransact(code, data, reply, flags); 2409 } catch (RuntimeException e) { 2410 // The activity manager only throws security exceptions, so let's 2411 // log all others. 2412 if (!(e instanceof SecurityException)) { 2413 Slog.wtf(TAG, "Activity Manager Crash", e); 2414 } 2415 throw e; 2416 } 2417 } 2418 2419 void updateCpuStats() { 2420 final long now = SystemClock.uptimeMillis(); 2421 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2422 return; 2423 } 2424 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2425 synchronized (mProcessCpuThread) { 2426 mProcessCpuThread.notify(); 2427 } 2428 } 2429 } 2430 2431 void updateCpuStatsNow() { 2432 synchronized (mProcessCpuTracker) { 2433 mProcessCpuMutexFree.set(false); 2434 final long now = SystemClock.uptimeMillis(); 2435 boolean haveNewCpuStats = false; 2436 2437 if (MONITOR_CPU_USAGE && 2438 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2439 mLastCpuTime.set(now); 2440 haveNewCpuStats = true; 2441 mProcessCpuTracker.update(); 2442 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2443 //Slog.i(TAG, "Total CPU usage: " 2444 // + mProcessCpu.getTotalCpuPercent() + "%"); 2445 2446 // Slog the cpu usage if the property is set. 2447 if ("true".equals(SystemProperties.get("events.cpu"))) { 2448 int user = mProcessCpuTracker.getLastUserTime(); 2449 int system = mProcessCpuTracker.getLastSystemTime(); 2450 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2451 int irq = mProcessCpuTracker.getLastIrqTime(); 2452 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2453 int idle = mProcessCpuTracker.getLastIdleTime(); 2454 2455 int total = user + system + iowait + irq + softIrq + idle; 2456 if (total == 0) total = 1; 2457 2458 EventLog.writeEvent(EventLogTags.CPU, 2459 ((user+system+iowait+irq+softIrq) * 100) / total, 2460 (user * 100) / total, 2461 (system * 100) / total, 2462 (iowait * 100) / total, 2463 (irq * 100) / total, 2464 (softIrq * 100) / total); 2465 } 2466 } 2467 2468 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2469 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2470 synchronized(bstats) { 2471 synchronized(mPidsSelfLocked) { 2472 if (haveNewCpuStats) { 2473 if (mOnBattery) { 2474 int perc = bstats.startAddingCpuLocked(); 2475 int totalUTime = 0; 2476 int totalSTime = 0; 2477 final int N = mProcessCpuTracker.countStats(); 2478 for (int i=0; i<N; i++) { 2479 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2480 if (!st.working) { 2481 continue; 2482 } 2483 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2484 int otherUTime = (st.rel_utime*perc)/100; 2485 int otherSTime = (st.rel_stime*perc)/100; 2486 totalUTime += otherUTime; 2487 totalSTime += otherSTime; 2488 if (pr != null) { 2489 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2490 if (ps == null || !ps.isActive()) { 2491 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2492 pr.info.uid, pr.processName); 2493 } 2494 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2495 st.rel_stime-otherSTime); 2496 ps.addSpeedStepTimes(cpuSpeedTimes); 2497 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2498 } else { 2499 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2500 if (ps == null || !ps.isActive()) { 2501 st.batteryStats = ps = bstats.getProcessStatsLocked( 2502 bstats.mapUid(st.uid), st.name); 2503 } 2504 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2505 st.rel_stime-otherSTime); 2506 ps.addSpeedStepTimes(cpuSpeedTimes); 2507 } 2508 } 2509 bstats.finishAddingCpuLocked(perc, totalUTime, 2510 totalSTime, cpuSpeedTimes); 2511 } 2512 } 2513 } 2514 2515 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2516 mLastWriteTime = now; 2517 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2518 } 2519 } 2520 } 2521 } 2522 2523 @Override 2524 public void batteryNeedsCpuUpdate() { 2525 updateCpuStatsNow(); 2526 } 2527 2528 @Override 2529 public void batteryPowerChanged(boolean onBattery) { 2530 // When plugging in, update the CPU stats first before changing 2531 // the plug state. 2532 updateCpuStatsNow(); 2533 synchronized (this) { 2534 synchronized(mPidsSelfLocked) { 2535 mOnBattery = DEBUG_POWER ? true : onBattery; 2536 } 2537 } 2538 } 2539 2540 /** 2541 * Initialize the application bind args. These are passed to each 2542 * process when the bindApplication() IPC is sent to the process. They're 2543 * lazily setup to make sure the services are running when they're asked for. 2544 */ 2545 private HashMap<String, IBinder> getCommonServicesLocked() { 2546 if (mAppBindArgs == null) { 2547 mAppBindArgs = new HashMap<String, IBinder>(); 2548 2549 // Setup the application init args 2550 mAppBindArgs.put("package", ServiceManager.getService("package")); 2551 mAppBindArgs.put("window", ServiceManager.getService("window")); 2552 mAppBindArgs.put(Context.ALARM_SERVICE, 2553 ServiceManager.getService(Context.ALARM_SERVICE)); 2554 } 2555 return mAppBindArgs; 2556 } 2557 2558 final void setFocusedActivityLocked(ActivityRecord r) { 2559 if (mFocusedActivity != r) { 2560 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2561 mFocusedActivity = r; 2562 if (r.task != null && r.task.voiceInteractor != null) { 2563 startRunningVoiceLocked(); 2564 } else { 2565 finishRunningVoiceLocked(); 2566 } 2567 mStackSupervisor.setFocusedStack(r); 2568 if (r != null) { 2569 mWindowManager.setFocusedApp(r.appToken, true); 2570 } 2571 applyUpdateLockStateLocked(r); 2572 } 2573 } 2574 2575 final void clearFocusedActivity(ActivityRecord r) { 2576 if (mFocusedActivity == r) { 2577 mFocusedActivity = null; 2578 } 2579 } 2580 2581 @Override 2582 public void setFocusedStack(int stackId) { 2583 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2584 synchronized (ActivityManagerService.this) { 2585 ActivityStack stack = mStackSupervisor.getStack(stackId); 2586 if (stack != null) { 2587 ActivityRecord r = stack.topRunningActivityLocked(null); 2588 if (r != null) { 2589 setFocusedActivityLocked(r); 2590 } 2591 } 2592 } 2593 } 2594 2595 @Override 2596 public void notifyActivityDrawn(IBinder token) { 2597 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2598 synchronized (this) { 2599 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2600 if (r != null) { 2601 r.task.stack.notifyActivityDrawnLocked(r); 2602 } 2603 } 2604 } 2605 2606 final void applyUpdateLockStateLocked(ActivityRecord r) { 2607 // Modifications to the UpdateLock state are done on our handler, outside 2608 // the activity manager's locks. The new state is determined based on the 2609 // state *now* of the relevant activity record. The object is passed to 2610 // the handler solely for logging detail, not to be consulted/modified. 2611 final boolean nextState = r != null && r.immersive; 2612 mHandler.sendMessage( 2613 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2614 } 2615 2616 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2617 Message msg = Message.obtain(); 2618 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2619 msg.obj = r.task.askedCompatMode ? null : r; 2620 mHandler.sendMessage(msg); 2621 } 2622 2623 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2624 String what, Object obj, ProcessRecord srcApp) { 2625 app.lastActivityTime = now; 2626 2627 if (app.activities.size() > 0) { 2628 // Don't want to touch dependent processes that are hosting activities. 2629 return index; 2630 } 2631 2632 int lrui = mLruProcesses.lastIndexOf(app); 2633 if (lrui < 0) { 2634 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2635 + what + " " + obj + " from " + srcApp); 2636 return index; 2637 } 2638 2639 if (lrui >= index) { 2640 // Don't want to cause this to move dependent processes *back* in the 2641 // list as if they were less frequently used. 2642 return index; 2643 } 2644 2645 if (lrui >= mLruProcessActivityStart) { 2646 // Don't want to touch dependent processes that are hosting activities. 2647 return index; 2648 } 2649 2650 mLruProcesses.remove(lrui); 2651 if (index > 0) { 2652 index--; 2653 } 2654 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2655 + " in LRU list: " + app); 2656 mLruProcesses.add(index, app); 2657 return index; 2658 } 2659 2660 final void removeLruProcessLocked(ProcessRecord app) { 2661 int lrui = mLruProcesses.lastIndexOf(app); 2662 if (lrui >= 0) { 2663 if (!app.killed) { 2664 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2665 Process.killProcessQuiet(app.pid); 2666 Process.killProcessGroup(app.uid, app.pid); 2667 } 2668 if (lrui <= mLruProcessActivityStart) { 2669 mLruProcessActivityStart--; 2670 } 2671 if (lrui <= mLruProcessServiceStart) { 2672 mLruProcessServiceStart--; 2673 } 2674 mLruProcesses.remove(lrui); 2675 } 2676 } 2677 2678 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2679 ProcessRecord client) { 2680 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2681 || app.treatLikeActivity; 2682 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2683 if (!activityChange && hasActivity) { 2684 // The process has activities, so we are only allowing activity-based adjustments 2685 // to move it. It should be kept in the front of the list with other 2686 // processes that have activities, and we don't want those to change their 2687 // order except due to activity operations. 2688 return; 2689 } 2690 2691 mLruSeq++; 2692 final long now = SystemClock.uptimeMillis(); 2693 app.lastActivityTime = now; 2694 2695 // First a quick reject: if the app is already at the position we will 2696 // put it, then there is nothing to do. 2697 if (hasActivity) { 2698 final int N = mLruProcesses.size(); 2699 if (N > 0 && mLruProcesses.get(N-1) == app) { 2700 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2701 return; 2702 } 2703 } else { 2704 if (mLruProcessServiceStart > 0 2705 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2706 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2707 return; 2708 } 2709 } 2710 2711 int lrui = mLruProcesses.lastIndexOf(app); 2712 2713 if (app.persistent && lrui >= 0) { 2714 // We don't care about the position of persistent processes, as long as 2715 // they are in the list. 2716 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2717 return; 2718 } 2719 2720 /* In progress: compute new position first, so we can avoid doing work 2721 if the process is not actually going to move. Not yet working. 2722 int addIndex; 2723 int nextIndex; 2724 boolean inActivity = false, inService = false; 2725 if (hasActivity) { 2726 // Process has activities, put it at the very tipsy-top. 2727 addIndex = mLruProcesses.size(); 2728 nextIndex = mLruProcessServiceStart; 2729 inActivity = true; 2730 } else if (hasService) { 2731 // Process has services, put it at the top of the service list. 2732 addIndex = mLruProcessActivityStart; 2733 nextIndex = mLruProcessServiceStart; 2734 inActivity = true; 2735 inService = true; 2736 } else { 2737 // Process not otherwise of interest, it goes to the top of the non-service area. 2738 addIndex = mLruProcessServiceStart; 2739 if (client != null) { 2740 int clientIndex = mLruProcesses.lastIndexOf(client); 2741 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2742 + app); 2743 if (clientIndex >= 0 && addIndex > clientIndex) { 2744 addIndex = clientIndex; 2745 } 2746 } 2747 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2748 } 2749 2750 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2751 + mLruProcessActivityStart + "): " + app); 2752 */ 2753 2754 if (lrui >= 0) { 2755 if (lrui < mLruProcessActivityStart) { 2756 mLruProcessActivityStart--; 2757 } 2758 if (lrui < mLruProcessServiceStart) { 2759 mLruProcessServiceStart--; 2760 } 2761 /* 2762 if (addIndex > lrui) { 2763 addIndex--; 2764 } 2765 if (nextIndex > lrui) { 2766 nextIndex--; 2767 } 2768 */ 2769 mLruProcesses.remove(lrui); 2770 } 2771 2772 /* 2773 mLruProcesses.add(addIndex, app); 2774 if (inActivity) { 2775 mLruProcessActivityStart++; 2776 } 2777 if (inService) { 2778 mLruProcessActivityStart++; 2779 } 2780 */ 2781 2782 int nextIndex; 2783 if (hasActivity) { 2784 final int N = mLruProcesses.size(); 2785 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2786 // Process doesn't have activities, but has clients with 2787 // activities... move it up, but one below the top (the top 2788 // should always have a real activity). 2789 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2790 mLruProcesses.add(N-1, app); 2791 // To keep it from spamming the LRU list (by making a bunch of clients), 2792 // we will push down any other entries owned by the app. 2793 final int uid = app.info.uid; 2794 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2795 ProcessRecord subProc = mLruProcesses.get(i); 2796 if (subProc.info.uid == uid) { 2797 // We want to push this one down the list. If the process after 2798 // it is for the same uid, however, don't do so, because we don't 2799 // want them internally to be re-ordered. 2800 if (mLruProcesses.get(i-1).info.uid != uid) { 2801 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2802 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2803 ProcessRecord tmp = mLruProcesses.get(i); 2804 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2805 mLruProcesses.set(i-1, tmp); 2806 i--; 2807 } 2808 } else { 2809 // A gap, we can stop here. 2810 break; 2811 } 2812 } 2813 } else { 2814 // Process has activities, put it at the very tipsy-top. 2815 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2816 mLruProcesses.add(app); 2817 } 2818 nextIndex = mLruProcessServiceStart; 2819 } else if (hasService) { 2820 // Process has services, put it at the top of the service list. 2821 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2822 mLruProcesses.add(mLruProcessActivityStart, app); 2823 nextIndex = mLruProcessServiceStart; 2824 mLruProcessActivityStart++; 2825 } else { 2826 // Process not otherwise of interest, it goes to the top of the non-service area. 2827 int index = mLruProcessServiceStart; 2828 if (client != null) { 2829 // If there is a client, don't allow the process to be moved up higher 2830 // in the list than that client. 2831 int clientIndex = mLruProcesses.lastIndexOf(client); 2832 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2833 + " when updating " + app); 2834 if (clientIndex <= lrui) { 2835 // Don't allow the client index restriction to push it down farther in the 2836 // list than it already is. 2837 clientIndex = lrui; 2838 } 2839 if (clientIndex >= 0 && index > clientIndex) { 2840 index = clientIndex; 2841 } 2842 } 2843 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2844 mLruProcesses.add(index, app); 2845 nextIndex = index-1; 2846 mLruProcessActivityStart++; 2847 mLruProcessServiceStart++; 2848 } 2849 2850 // If the app is currently using a content provider or service, 2851 // bump those processes as well. 2852 for (int j=app.connections.size()-1; j>=0; j--) { 2853 ConnectionRecord cr = app.connections.valueAt(j); 2854 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2855 && cr.binding.service.app != null 2856 && cr.binding.service.app.lruSeq != mLruSeq 2857 && !cr.binding.service.app.persistent) { 2858 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2859 "service connection", cr, app); 2860 } 2861 } 2862 for (int j=app.conProviders.size()-1; j>=0; j--) { 2863 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2864 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2865 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2866 "provider reference", cpr, app); 2867 } 2868 } 2869 } 2870 2871 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2872 if (uid == Process.SYSTEM_UID) { 2873 // The system gets to run in any process. If there are multiple 2874 // processes with the same uid, just pick the first (this 2875 // should never happen). 2876 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2877 if (procs == null) return null; 2878 final int procCount = procs.size(); 2879 for (int i = 0; i < procCount; i++) { 2880 final int procUid = procs.keyAt(i); 2881 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) { 2882 // Don't use an app process or different user process for system component. 2883 continue; 2884 } 2885 return procs.valueAt(i); 2886 } 2887 } 2888 ProcessRecord proc = mProcessNames.get(processName, uid); 2889 if (false && proc != null && !keepIfLarge 2890 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2891 && proc.lastCachedPss >= 4000) { 2892 // Turn this condition on to cause killing to happen regularly, for testing. 2893 if (proc.baseProcessTracker != null) { 2894 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2895 } 2896 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2897 } else if (proc != null && !keepIfLarge 2898 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2899 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2900 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2901 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2902 if (proc.baseProcessTracker != null) { 2903 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2904 } 2905 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2906 } 2907 } 2908 return proc; 2909 } 2910 2911 void ensurePackageDexOpt(String packageName) { 2912 IPackageManager pm = AppGlobals.getPackageManager(); 2913 try { 2914 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2915 mDidDexOpt = true; 2916 } 2917 } catch (RemoteException e) { 2918 } 2919 } 2920 2921 boolean isNextTransitionForward() { 2922 int transit = mWindowManager.getPendingAppTransition(); 2923 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2924 || transit == AppTransition.TRANSIT_TASK_OPEN 2925 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2926 } 2927 2928 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2929 String processName, String abiOverride, int uid, Runnable crashHandler) { 2930 synchronized(this) { 2931 ApplicationInfo info = new ApplicationInfo(); 2932 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2933 // For isolated processes, the former contains the parent's uid and the latter the 2934 // actual uid of the isolated process. 2935 // In the special case introduced by this method (which is, starting an isolated 2936 // process directly from the SystemServer without an actual parent app process) the 2937 // closest thing to a parent's uid is SYSTEM_UID. 2938 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2939 // the |isolated| logic in the ProcessRecord constructor. 2940 info.uid = Process.SYSTEM_UID; 2941 info.processName = processName; 2942 info.className = entryPoint; 2943 info.packageName = "android"; 2944 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2945 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2946 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2947 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2948 crashHandler); 2949 return proc != null ? proc.pid : 0; 2950 } 2951 } 2952 2953 final ProcessRecord startProcessLocked(String processName, 2954 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2955 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2956 boolean isolated, boolean keepIfLarge) { 2957 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2958 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2959 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2960 null /* crashHandler */); 2961 } 2962 2963 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2964 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2965 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2966 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2967 long startTime = SystemClock.elapsedRealtime(); 2968 ProcessRecord app; 2969 if (!isolated) { 2970 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2971 checkTime(startTime, "startProcess: after getProcessRecord"); 2972 } else { 2973 // If this is an isolated process, it can't re-use an existing process. 2974 app = null; 2975 } 2976 // We don't have to do anything more if: 2977 // (1) There is an existing application record; and 2978 // (2) The caller doesn't think it is dead, OR there is no thread 2979 // object attached to it so we know it couldn't have crashed; and 2980 // (3) There is a pid assigned to it, so it is either starting or 2981 // already running. 2982 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2983 + " app=" + app + " knownToBeDead=" + knownToBeDead 2984 + " thread=" + (app != null ? app.thread : null) 2985 + " pid=" + (app != null ? app.pid : -1)); 2986 if (app != null && app.pid > 0) { 2987 if (!knownToBeDead || app.thread == null) { 2988 // We already have the app running, or are waiting for it to 2989 // come up (we have a pid but not yet its thread), so keep it. 2990 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2991 // If this is a new package in the process, add the package to the list 2992 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2993 checkTime(startTime, "startProcess: done, added package to proc"); 2994 return app; 2995 } 2996 2997 // An application record is attached to a previous process, 2998 // clean it up now. 2999 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 3000 checkTime(startTime, "startProcess: bad proc running, killing"); 3001 Process.killProcessGroup(app.uid, app.pid); 3002 handleAppDiedLocked(app, true, true); 3003 checkTime(startTime, "startProcess: done killing old proc"); 3004 } 3005 3006 String hostingNameStr = hostingName != null 3007 ? hostingName.flattenToShortString() : null; 3008 3009 if (!isolated) { 3010 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 3011 // If we are in the background, then check to see if this process 3012 // is bad. If so, we will just silently fail. 3013 if (mBadProcesses.get(info.processName, info.uid) != null) { 3014 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3015 + "/" + info.processName); 3016 return null; 3017 } 3018 } else { 3019 // When the user is explicitly starting a process, then clear its 3020 // crash count so that we won't make it bad until they see at 3021 // least one crash dialog again, and make the process good again 3022 // if it had been bad. 3023 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3024 + "/" + info.processName); 3025 mProcessCrashTimes.remove(info.processName, info.uid); 3026 if (mBadProcesses.get(info.processName, info.uid) != null) { 3027 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3028 UserHandle.getUserId(info.uid), info.uid, 3029 info.processName); 3030 mBadProcesses.remove(info.processName, info.uid); 3031 if (app != null) { 3032 app.bad = false; 3033 } 3034 } 3035 } 3036 } 3037 3038 if (app == null) { 3039 checkTime(startTime, "startProcess: creating new process record"); 3040 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3041 app.crashHandler = crashHandler; 3042 if (app == null) { 3043 Slog.w(TAG, "Failed making new process record for " 3044 + processName + "/" + info.uid + " isolated=" + isolated); 3045 return null; 3046 } 3047 mProcessNames.put(processName, app.uid, app); 3048 if (isolated) { 3049 mIsolatedProcesses.put(app.uid, app); 3050 } 3051 checkTime(startTime, "startProcess: done creating new process record"); 3052 } else { 3053 // If this is a new package in the process, add the package to the list 3054 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3055 checkTime(startTime, "startProcess: added package to existing proc"); 3056 } 3057 3058 // If the system is not ready yet, then hold off on starting this 3059 // process until it is. 3060 if (!mProcessesReady 3061 && !isAllowedWhileBooting(info) 3062 && !allowWhileBooting) { 3063 if (!mProcessesOnHold.contains(app)) { 3064 mProcessesOnHold.add(app); 3065 } 3066 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3067 checkTime(startTime, "startProcess: returning with proc on hold"); 3068 return app; 3069 } 3070 3071 checkTime(startTime, "startProcess: stepping in to startProcess"); 3072 startProcessLocked( 3073 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3074 checkTime(startTime, "startProcess: done starting proc!"); 3075 return (app.pid != 0) ? app : null; 3076 } 3077 3078 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3079 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3080 } 3081 3082 private final void startProcessLocked(ProcessRecord app, 3083 String hostingType, String hostingNameStr) { 3084 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3085 null /* entryPoint */, null /* entryPointArgs */); 3086 } 3087 3088 private final void startProcessLocked(ProcessRecord app, String hostingType, 3089 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3090 long startTime = SystemClock.elapsedRealtime(); 3091 if (app.pid > 0 && app.pid != MY_PID) { 3092 checkTime(startTime, "startProcess: removing from pids map"); 3093 synchronized (mPidsSelfLocked) { 3094 mPidsSelfLocked.remove(app.pid); 3095 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3096 } 3097 checkTime(startTime, "startProcess: done removing from pids map"); 3098 app.setPid(0); 3099 } 3100 3101 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3102 "startProcessLocked removing on hold: " + app); 3103 mProcessesOnHold.remove(app); 3104 3105 checkTime(startTime, "startProcess: starting to update cpu stats"); 3106 updateCpuStats(); 3107 checkTime(startTime, "startProcess: done updating cpu stats"); 3108 3109 try { 3110 int uid = app.uid; 3111 3112 int[] gids = null; 3113 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3114 if (!app.isolated) { 3115 int[] permGids = null; 3116 try { 3117 checkTime(startTime, "startProcess: getting gids from package manager"); 3118 final PackageManager pm = mContext.getPackageManager(); 3119 permGids = pm.getPackageGids(app.info.packageName); 3120 3121 if (Environment.isExternalStorageEmulated()) { 3122 checkTime(startTime, "startProcess: checking external storage perm"); 3123 if (pm.checkPermission( 3124 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3125 app.info.packageName) == PERMISSION_GRANTED) { 3126 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3127 } else { 3128 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3129 } 3130 } 3131 } catch (PackageManager.NameNotFoundException e) { 3132 Slog.w(TAG, "Unable to retrieve gids", e); 3133 } 3134 3135 /* 3136 * Add shared application and profile GIDs so applications can share some 3137 * resources like shared libraries and access user-wide resources 3138 */ 3139 if (permGids == null) { 3140 gids = new int[2]; 3141 } else { 3142 gids = new int[permGids.length + 2]; 3143 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3144 } 3145 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3146 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3147 } 3148 checkTime(startTime, "startProcess: building args"); 3149 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3150 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3151 && mTopComponent != null 3152 && app.processName.equals(mTopComponent.getPackageName())) { 3153 uid = 0; 3154 } 3155 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3156 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3157 uid = 0; 3158 } 3159 } 3160 int debugFlags = 0; 3161 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3162 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3163 // Also turn on CheckJNI for debuggable apps. It's quite 3164 // awkward to turn on otherwise. 3165 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3166 } 3167 // Run the app in safe mode if its manifest requests so or the 3168 // system is booted in safe mode. 3169 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3170 mSafeMode == true) { 3171 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3172 } 3173 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3174 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3175 } 3176 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3177 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3178 } 3179 if ("1".equals(SystemProperties.get("debug.assert"))) { 3180 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3181 } 3182 3183 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3184 if (requiredAbi == null) { 3185 requiredAbi = Build.SUPPORTED_ABIS[0]; 3186 } 3187 3188 String instructionSet = null; 3189 if (app.info.primaryCpuAbi != null) { 3190 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3191 } 3192 3193 // Start the process. It will either succeed and return a result containing 3194 // the PID of the new process, or else throw a RuntimeException. 3195 boolean isActivityProcess = (entryPoint == null); 3196 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3197 checkTime(startTime, "startProcess: asking zygote to start proc"); 3198 Process.ProcessStartResult startResult = Process.start(entryPoint, 3199 app.processName, uid, uid, gids, debugFlags, mountExternal, 3200 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3201 app.info.dataDir, entryPointArgs); 3202 checkTime(startTime, "startProcess: returned from zygote!"); 3203 3204 if (app.isolated) { 3205 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3206 } 3207 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3208 checkTime(startTime, "startProcess: done updating battery stats"); 3209 3210 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3211 UserHandle.getUserId(uid), startResult.pid, uid, 3212 app.processName, hostingType, 3213 hostingNameStr != null ? hostingNameStr : ""); 3214 3215 if (app.persistent) { 3216 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3217 } 3218 3219 checkTime(startTime, "startProcess: building log message"); 3220 StringBuilder buf = mStringBuilder; 3221 buf.setLength(0); 3222 buf.append("Start proc "); 3223 buf.append(app.processName); 3224 if (!isActivityProcess) { 3225 buf.append(" ["); 3226 buf.append(entryPoint); 3227 buf.append("]"); 3228 } 3229 buf.append(" for "); 3230 buf.append(hostingType); 3231 if (hostingNameStr != null) { 3232 buf.append(" "); 3233 buf.append(hostingNameStr); 3234 } 3235 buf.append(": pid="); 3236 buf.append(startResult.pid); 3237 buf.append(" uid="); 3238 buf.append(uid); 3239 buf.append(" gids={"); 3240 if (gids != null) { 3241 for (int gi=0; gi<gids.length; gi++) { 3242 if (gi != 0) buf.append(", "); 3243 buf.append(gids[gi]); 3244 3245 } 3246 } 3247 buf.append("}"); 3248 if (requiredAbi != null) { 3249 buf.append(" abi="); 3250 buf.append(requiredAbi); 3251 } 3252 Slog.i(TAG, buf.toString()); 3253 app.setPid(startResult.pid); 3254 app.usingWrapper = startResult.usingWrapper; 3255 app.removed = false; 3256 app.killed = false; 3257 app.killedByAm = false; 3258 checkTime(startTime, "startProcess: starting to update pids map"); 3259 synchronized (mPidsSelfLocked) { 3260 this.mPidsSelfLocked.put(startResult.pid, app); 3261 if (isActivityProcess) { 3262 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3263 msg.obj = app; 3264 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3265 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3266 } 3267 } 3268 checkTime(startTime, "startProcess: done updating pids map"); 3269 } catch (RuntimeException e) { 3270 // XXX do better error recovery. 3271 app.setPid(0); 3272 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3273 if (app.isolated) { 3274 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3275 } 3276 Slog.e(TAG, "Failure starting process " + app.processName, e); 3277 } 3278 } 3279 3280 void updateUsageStats(ActivityRecord component, boolean resumed) { 3281 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3282 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3283 if (resumed) { 3284 if (mUsageStatsService != null) { 3285 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3286 UsageEvents.Event.MOVE_TO_FOREGROUND); 3287 } 3288 synchronized (stats) { 3289 stats.noteActivityResumedLocked(component.app.uid); 3290 } 3291 } else { 3292 if (mUsageStatsService != null) { 3293 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3294 UsageEvents.Event.MOVE_TO_BACKGROUND); 3295 } 3296 synchronized (stats) { 3297 stats.noteActivityPausedLocked(component.app.uid); 3298 } 3299 } 3300 } 3301 3302 Intent getHomeIntent() { 3303 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3304 intent.setComponent(mTopComponent); 3305 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3306 intent.addCategory(Intent.CATEGORY_HOME); 3307 } 3308 return intent; 3309 } 3310 3311 boolean startHomeActivityLocked(int userId) { 3312 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3313 && mTopAction == null) { 3314 // We are running in factory test mode, but unable to find 3315 // the factory test app, so just sit around displaying the 3316 // error message and don't try to start anything. 3317 return false; 3318 } 3319 Intent intent = getHomeIntent(); 3320 ActivityInfo aInfo = 3321 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3322 if (aInfo != null) { 3323 intent.setComponent(new ComponentName( 3324 aInfo.applicationInfo.packageName, aInfo.name)); 3325 // Don't do this if the home app is currently being 3326 // instrumented. 3327 aInfo = new ActivityInfo(aInfo); 3328 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3329 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3330 aInfo.applicationInfo.uid, true); 3331 if (app == null || app.instrumentationClass == null) { 3332 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3333 mStackSupervisor.startHomeActivity(intent, aInfo); 3334 } 3335 } 3336 3337 return true; 3338 } 3339 3340 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3341 ActivityInfo ai = null; 3342 ComponentName comp = intent.getComponent(); 3343 try { 3344 if (comp != null) { 3345 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3346 } else { 3347 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3348 intent, 3349 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3350 flags, userId); 3351 3352 if (info != null) { 3353 ai = info.activityInfo; 3354 } 3355 } 3356 } catch (RemoteException e) { 3357 // ignore 3358 } 3359 3360 return ai; 3361 } 3362 3363 /** 3364 * Starts the "new version setup screen" if appropriate. 3365 */ 3366 void startSetupActivityLocked() { 3367 // Only do this once per boot. 3368 if (mCheckedForSetup) { 3369 return; 3370 } 3371 3372 // We will show this screen if the current one is a different 3373 // version than the last one shown, and we are not running in 3374 // low-level factory test mode. 3375 final ContentResolver resolver = mContext.getContentResolver(); 3376 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3377 Settings.Global.getInt(resolver, 3378 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3379 mCheckedForSetup = true; 3380 3381 // See if we should be showing the platform update setup UI. 3382 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3383 List<ResolveInfo> ris = mContext.getPackageManager() 3384 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3385 3386 // We don't allow third party apps to replace this. 3387 ResolveInfo ri = null; 3388 for (int i=0; ris != null && i<ris.size(); i++) { 3389 if ((ris.get(i).activityInfo.applicationInfo.flags 3390 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3391 ri = ris.get(i); 3392 break; 3393 } 3394 } 3395 3396 if (ri != null) { 3397 String vers = ri.activityInfo.metaData != null 3398 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3399 : null; 3400 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3401 vers = ri.activityInfo.applicationInfo.metaData.getString( 3402 Intent.METADATA_SETUP_VERSION); 3403 } 3404 String lastVers = Settings.Secure.getString( 3405 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3406 if (vers != null && !vers.equals(lastVers)) { 3407 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3408 intent.setComponent(new ComponentName( 3409 ri.activityInfo.packageName, ri.activityInfo.name)); 3410 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3411 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3412 null); 3413 } 3414 } 3415 } 3416 } 3417 3418 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3419 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3420 } 3421 3422 void enforceNotIsolatedCaller(String caller) { 3423 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3424 throw new SecurityException("Isolated process not allowed to call " + caller); 3425 } 3426 } 3427 3428 void enforceShellRestriction(String restriction, int userHandle) { 3429 if (Binder.getCallingUid() == Process.SHELL_UID) { 3430 if (userHandle < 0 3431 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3432 throw new SecurityException("Shell does not have permission to access user " 3433 + userHandle); 3434 } 3435 } 3436 } 3437 3438 @Override 3439 public int getFrontActivityScreenCompatMode() { 3440 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3441 synchronized (this) { 3442 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3443 } 3444 } 3445 3446 @Override 3447 public void setFrontActivityScreenCompatMode(int mode) { 3448 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3449 "setFrontActivityScreenCompatMode"); 3450 synchronized (this) { 3451 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3452 } 3453 } 3454 3455 @Override 3456 public int getPackageScreenCompatMode(String packageName) { 3457 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3458 synchronized (this) { 3459 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3460 } 3461 } 3462 3463 @Override 3464 public void setPackageScreenCompatMode(String packageName, int mode) { 3465 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3466 "setPackageScreenCompatMode"); 3467 synchronized (this) { 3468 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3469 } 3470 } 3471 3472 @Override 3473 public boolean getPackageAskScreenCompat(String packageName) { 3474 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3475 synchronized (this) { 3476 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3477 } 3478 } 3479 3480 @Override 3481 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3482 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3483 "setPackageAskScreenCompat"); 3484 synchronized (this) { 3485 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3486 } 3487 } 3488 3489 private void dispatchProcessesChanged() { 3490 int N; 3491 synchronized (this) { 3492 N = mPendingProcessChanges.size(); 3493 if (mActiveProcessChanges.length < N) { 3494 mActiveProcessChanges = new ProcessChangeItem[N]; 3495 } 3496 mPendingProcessChanges.toArray(mActiveProcessChanges); 3497 mAvailProcessChanges.addAll(mPendingProcessChanges); 3498 mPendingProcessChanges.clear(); 3499 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3500 } 3501 3502 int i = mProcessObservers.beginBroadcast(); 3503 while (i > 0) { 3504 i--; 3505 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3506 if (observer != null) { 3507 try { 3508 for (int j=0; j<N; j++) { 3509 ProcessChangeItem item = mActiveProcessChanges[j]; 3510 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3511 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3512 + item.pid + " uid=" + item.uid + ": " 3513 + item.foregroundActivities); 3514 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3515 item.foregroundActivities); 3516 } 3517 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3518 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3519 + item.pid + " uid=" + item.uid + ": " + item.processState); 3520 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3521 } 3522 } 3523 } catch (RemoteException e) { 3524 } 3525 } 3526 } 3527 mProcessObservers.finishBroadcast(); 3528 } 3529 3530 private void dispatchProcessDied(int pid, int uid) { 3531 int i = mProcessObservers.beginBroadcast(); 3532 while (i > 0) { 3533 i--; 3534 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3535 if (observer != null) { 3536 try { 3537 observer.onProcessDied(pid, uid); 3538 } catch (RemoteException e) { 3539 } 3540 } 3541 } 3542 mProcessObservers.finishBroadcast(); 3543 } 3544 3545 @Override 3546 public final int startActivity(IApplicationThread caller, String callingPackage, 3547 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3548 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3549 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3550 resultWho, requestCode, startFlags, profilerInfo, options, 3551 UserHandle.getCallingUserId()); 3552 } 3553 3554 @Override 3555 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3556 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3557 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3558 enforceNotIsolatedCaller("startActivity"); 3559 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3560 false, ALLOW_FULL_ONLY, "startActivity", null); 3561 // TODO: Switch to user app stacks here. 3562 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3563 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3564 profilerInfo, null, null, options, userId, null, null); 3565 } 3566 3567 @Override 3568 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3569 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3570 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3571 3572 // This is very dangerous -- it allows you to perform a start activity (including 3573 // permission grants) as any app that may launch one of your own activities. So 3574 // we will only allow this to be done from activities that are part of the core framework, 3575 // and then only when they are running as the system. 3576 final ActivityRecord sourceRecord; 3577 final int targetUid; 3578 final String targetPackage; 3579 synchronized (this) { 3580 if (resultTo == null) { 3581 throw new SecurityException("Must be called from an activity"); 3582 } 3583 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3584 if (sourceRecord == null) { 3585 throw new SecurityException("Called with bad activity token: " + resultTo); 3586 } 3587 if (!sourceRecord.info.packageName.equals("android")) { 3588 throw new SecurityException( 3589 "Must be called from an activity that is declared in the android package"); 3590 } 3591 if (sourceRecord.app == null) { 3592 throw new SecurityException("Called without a process attached to activity"); 3593 } 3594 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3595 // This is still okay, as long as this activity is running under the 3596 // uid of the original calling activity. 3597 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3598 throw new SecurityException( 3599 "Calling activity in uid " + sourceRecord.app.uid 3600 + " must be system uid or original calling uid " 3601 + sourceRecord.launchedFromUid); 3602 } 3603 } 3604 targetUid = sourceRecord.launchedFromUid; 3605 targetPackage = sourceRecord.launchedFromPackage; 3606 } 3607 3608 if (userId == UserHandle.USER_NULL) { 3609 userId = UserHandle.getUserId(sourceRecord.app.uid); 3610 } 3611 3612 // TODO: Switch to user app stacks here. 3613 try { 3614 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3615 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3616 null, null, options, userId, null, null); 3617 return ret; 3618 } catch (SecurityException e) { 3619 // XXX need to figure out how to propagate to original app. 3620 // A SecurityException here is generally actually a fault of the original 3621 // calling activity (such as a fairly granting permissions), so propagate it 3622 // back to them. 3623 /* 3624 StringBuilder msg = new StringBuilder(); 3625 msg.append("While launching"); 3626 msg.append(intent.toString()); 3627 msg.append(": "); 3628 msg.append(e.getMessage()); 3629 */ 3630 throw e; 3631 } 3632 } 3633 3634 @Override 3635 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3636 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3637 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3638 enforceNotIsolatedCaller("startActivityAndWait"); 3639 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3640 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3641 WaitResult res = new WaitResult(); 3642 // TODO: Switch to user app stacks here. 3643 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3644 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3645 options, userId, null, null); 3646 return res; 3647 } 3648 3649 @Override 3650 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3651 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3652 int startFlags, Configuration config, Bundle options, int userId) { 3653 enforceNotIsolatedCaller("startActivityWithConfig"); 3654 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3655 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3656 // TODO: Switch to user app stacks here. 3657 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3658 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3659 null, null, config, options, userId, null, null); 3660 return ret; 3661 } 3662 3663 @Override 3664 public int startActivityIntentSender(IApplicationThread caller, 3665 IntentSender intent, Intent fillInIntent, String resolvedType, 3666 IBinder resultTo, String resultWho, int requestCode, 3667 int flagsMask, int flagsValues, Bundle options) { 3668 enforceNotIsolatedCaller("startActivityIntentSender"); 3669 // Refuse possible leaked file descriptors 3670 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3671 throw new IllegalArgumentException("File descriptors passed in Intent"); 3672 } 3673 3674 IIntentSender sender = intent.getTarget(); 3675 if (!(sender instanceof PendingIntentRecord)) { 3676 throw new IllegalArgumentException("Bad PendingIntent object"); 3677 } 3678 3679 PendingIntentRecord pir = (PendingIntentRecord)sender; 3680 3681 synchronized (this) { 3682 // If this is coming from the currently resumed activity, it is 3683 // effectively saying that app switches are allowed at this point. 3684 final ActivityStack stack = getFocusedStack(); 3685 if (stack.mResumedActivity != null && 3686 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3687 mAppSwitchesAllowedTime = 0; 3688 } 3689 } 3690 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3691 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3692 return ret; 3693 } 3694 3695 @Override 3696 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3697 Intent intent, String resolvedType, IVoiceInteractionSession session, 3698 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3699 Bundle options, int userId) { 3700 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3701 != PackageManager.PERMISSION_GRANTED) { 3702 String msg = "Permission Denial: startVoiceActivity() from pid=" 3703 + Binder.getCallingPid() 3704 + ", uid=" + Binder.getCallingUid() 3705 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3706 Slog.w(TAG, msg); 3707 throw new SecurityException(msg); 3708 } 3709 if (session == null || interactor == null) { 3710 throw new NullPointerException("null session or interactor"); 3711 } 3712 userId = handleIncomingUser(callingPid, callingUid, userId, 3713 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3714 // TODO: Switch to user app stacks here. 3715 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3716 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3717 null, options, userId, null, null); 3718 } 3719 3720 @Override 3721 public boolean startNextMatchingActivity(IBinder callingActivity, 3722 Intent intent, Bundle options) { 3723 // Refuse possible leaked file descriptors 3724 if (intent != null && intent.hasFileDescriptors() == true) { 3725 throw new IllegalArgumentException("File descriptors passed in Intent"); 3726 } 3727 3728 synchronized (this) { 3729 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3730 if (r == null) { 3731 ActivityOptions.abort(options); 3732 return false; 3733 } 3734 if (r.app == null || r.app.thread == null) { 3735 // The caller is not running... d'oh! 3736 ActivityOptions.abort(options); 3737 return false; 3738 } 3739 intent = new Intent(intent); 3740 // The caller is not allowed to change the data. 3741 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3742 // And we are resetting to find the next component... 3743 intent.setComponent(null); 3744 3745 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3746 3747 ActivityInfo aInfo = null; 3748 try { 3749 List<ResolveInfo> resolves = 3750 AppGlobals.getPackageManager().queryIntentActivities( 3751 intent, r.resolvedType, 3752 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3753 UserHandle.getCallingUserId()); 3754 3755 // Look for the original activity in the list... 3756 final int N = resolves != null ? resolves.size() : 0; 3757 for (int i=0; i<N; i++) { 3758 ResolveInfo rInfo = resolves.get(i); 3759 if (rInfo.activityInfo.packageName.equals(r.packageName) 3760 && rInfo.activityInfo.name.equals(r.info.name)) { 3761 // We found the current one... the next matching is 3762 // after it. 3763 i++; 3764 if (i<N) { 3765 aInfo = resolves.get(i).activityInfo; 3766 } 3767 if (debug) { 3768 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3769 + "/" + r.info.name); 3770 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3771 + "/" + aInfo.name); 3772 } 3773 break; 3774 } 3775 } 3776 } catch (RemoteException e) { 3777 } 3778 3779 if (aInfo == null) { 3780 // Nobody who is next! 3781 ActivityOptions.abort(options); 3782 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3783 return false; 3784 } 3785 3786 intent.setComponent(new ComponentName( 3787 aInfo.applicationInfo.packageName, aInfo.name)); 3788 intent.setFlags(intent.getFlags()&~( 3789 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3790 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3791 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3792 Intent.FLAG_ACTIVITY_NEW_TASK)); 3793 3794 // Okay now we need to start the new activity, replacing the 3795 // currently running activity. This is a little tricky because 3796 // we want to start the new one as if the current one is finished, 3797 // but not finish the current one first so that there is no flicker. 3798 // And thus... 3799 final boolean wasFinishing = r.finishing; 3800 r.finishing = true; 3801 3802 // Propagate reply information over to the new activity. 3803 final ActivityRecord resultTo = r.resultTo; 3804 final String resultWho = r.resultWho; 3805 final int requestCode = r.requestCode; 3806 r.resultTo = null; 3807 if (resultTo != null) { 3808 resultTo.removeResultsLocked(r, resultWho, requestCode); 3809 } 3810 3811 final long origId = Binder.clearCallingIdentity(); 3812 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3813 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3814 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3815 -1, r.launchedFromUid, 0, options, false, null, null, null); 3816 Binder.restoreCallingIdentity(origId); 3817 3818 r.finishing = wasFinishing; 3819 if (res != ActivityManager.START_SUCCESS) { 3820 return false; 3821 } 3822 return true; 3823 } 3824 } 3825 3826 @Override 3827 public final int startActivityFromRecents(int taskId, Bundle options) { 3828 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3829 String msg = "Permission Denial: startActivityFromRecents called without " + 3830 START_TASKS_FROM_RECENTS; 3831 Slog.w(TAG, msg); 3832 throw new SecurityException(msg); 3833 } 3834 return startActivityFromRecentsInner(taskId, options); 3835 } 3836 3837 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3838 final TaskRecord task; 3839 final int callingUid; 3840 final String callingPackage; 3841 final Intent intent; 3842 final int userId; 3843 synchronized (this) { 3844 task = recentTaskForIdLocked(taskId); 3845 if (task == null) { 3846 throw new IllegalArgumentException("Task " + taskId + " not found."); 3847 } 3848 callingUid = task.mCallingUid; 3849 callingPackage = task.mCallingPackage; 3850 intent = task.intent; 3851 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3852 userId = task.userId; 3853 } 3854 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3855 options, userId, null, task); 3856 } 3857 3858 final int startActivityInPackage(int uid, String callingPackage, 3859 Intent intent, String resolvedType, IBinder resultTo, 3860 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3861 IActivityContainer container, TaskRecord inTask) { 3862 3863 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3864 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3865 3866 // TODO: Switch to user app stacks here. 3867 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3868 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3869 null, null, null, options, userId, container, inTask); 3870 return ret; 3871 } 3872 3873 @Override 3874 public final int startActivities(IApplicationThread caller, String callingPackage, 3875 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3876 int userId) { 3877 enforceNotIsolatedCaller("startActivities"); 3878 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3879 false, ALLOW_FULL_ONLY, "startActivity", null); 3880 // TODO: Switch to user app stacks here. 3881 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3882 resolvedTypes, resultTo, options, userId); 3883 return ret; 3884 } 3885 3886 final int startActivitiesInPackage(int uid, String callingPackage, 3887 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3888 Bundle options, int userId) { 3889 3890 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3891 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3892 // TODO: Switch to user app stacks here. 3893 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3894 resultTo, options, userId); 3895 return ret; 3896 } 3897 3898 //explicitly remove thd old information in mRecentTasks when removing existing user. 3899 private void removeRecentTasksForUserLocked(int userId) { 3900 if(userId <= 0) { 3901 Slog.i(TAG, "Can't remove recent task on user " + userId); 3902 return; 3903 } 3904 3905 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3906 TaskRecord tr = mRecentTasks.get(i); 3907 if (tr.userId == userId) { 3908 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3909 + " when finishing user" + userId); 3910 mRecentTasks.remove(i); 3911 tr.removedFromRecents(mTaskPersister); 3912 } 3913 } 3914 3915 // Remove tasks from persistent storage. 3916 mTaskPersister.wakeup(null, true); 3917 } 3918 3919 // Sort by taskId 3920 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3921 @Override 3922 public int compare(TaskRecord lhs, TaskRecord rhs) { 3923 return rhs.taskId - lhs.taskId; 3924 } 3925 }; 3926 3927 // Extract the affiliates of the chain containing mRecentTasks[start]. 3928 private int processNextAffiliateChain(int start) { 3929 final TaskRecord startTask = mRecentTasks.get(start); 3930 final int affiliateId = startTask.mAffiliatedTaskId; 3931 3932 // Quick identification of isolated tasks. I.e. those not launched behind. 3933 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3934 startTask.mNextAffiliate == null) { 3935 // There is still a slim chance that there are other tasks that point to this task 3936 // and that the chain is so messed up that this task no longer points to them but 3937 // the gain of this optimization outweighs the risk. 3938 startTask.inRecents = true; 3939 return start + 1; 3940 } 3941 3942 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3943 mTmpRecents.clear(); 3944 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3945 final TaskRecord task = mRecentTasks.get(i); 3946 if (task.mAffiliatedTaskId == affiliateId) { 3947 mRecentTasks.remove(i); 3948 mTmpRecents.add(task); 3949 } 3950 } 3951 3952 // Sort them all by taskId. That is the order they were create in and that order will 3953 // always be correct. 3954 Collections.sort(mTmpRecents, mTaskRecordComparator); 3955 3956 // Go through and fix up the linked list. 3957 // The first one is the end of the chain and has no next. 3958 final TaskRecord first = mTmpRecents.get(0); 3959 first.inRecents = true; 3960 if (first.mNextAffiliate != null) { 3961 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3962 first.setNextAffiliate(null); 3963 mTaskPersister.wakeup(first, false); 3964 } 3965 // Everything in the middle is doubly linked from next to prev. 3966 final int tmpSize = mTmpRecents.size(); 3967 for (int i = 0; i < tmpSize - 1; ++i) { 3968 final TaskRecord next = mTmpRecents.get(i); 3969 final TaskRecord prev = mTmpRecents.get(i + 1); 3970 if (next.mPrevAffiliate != prev) { 3971 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3972 " setting prev=" + prev); 3973 next.setPrevAffiliate(prev); 3974 mTaskPersister.wakeup(next, false); 3975 } 3976 if (prev.mNextAffiliate != next) { 3977 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3978 " setting next=" + next); 3979 prev.setNextAffiliate(next); 3980 mTaskPersister.wakeup(prev, false); 3981 } 3982 prev.inRecents = true; 3983 } 3984 // The last one is the beginning of the list and has no prev. 3985 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3986 if (last.mPrevAffiliate != null) { 3987 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3988 last.setPrevAffiliate(null); 3989 mTaskPersister.wakeup(last, false); 3990 } 3991 3992 // Insert the group back into mRecentTasks at start. 3993 mRecentTasks.addAll(start, mTmpRecents); 3994 3995 // Let the caller know where we left off. 3996 return start + tmpSize; 3997 } 3998 3999 /** 4000 * Update the recent tasks lists: make sure tasks should still be here (their 4001 * applications / activities still exist), update their availability, fixup ordering 4002 * of affiliations. 4003 */ 4004 void cleanupRecentTasksLocked(int userId) { 4005 if (mRecentTasks == null) { 4006 // Happens when called from the packagemanager broadcast before boot. 4007 return; 4008 } 4009 4010 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 4011 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 4012 final IPackageManager pm = AppGlobals.getPackageManager(); 4013 final ActivityInfo dummyAct = new ActivityInfo(); 4014 final ApplicationInfo dummyApp = new ApplicationInfo(); 4015 4016 int N = mRecentTasks.size(); 4017 4018 int[] users = userId == UserHandle.USER_ALL 4019 ? getUsersLocked() : new int[] { userId }; 4020 for (int user : users) { 4021 for (int i = 0; i < N; i++) { 4022 TaskRecord task = mRecentTasks.get(i); 4023 if (task.userId != user) { 4024 // Only look at tasks for the user ID of interest. 4025 continue; 4026 } 4027 if (task.autoRemoveRecents && task.getTopActivity() == null) { 4028 // This situation is broken, and we should just get rid of it now. 4029 mRecentTasks.remove(i); 4030 task.removedFromRecents(mTaskPersister); 4031 i--; 4032 N--; 4033 Slog.w(TAG, "Removing auto-remove without activity: " + task); 4034 continue; 4035 } 4036 // Check whether this activity is currently available. 4037 if (task.realActivity != null) { 4038 ActivityInfo ai = availActCache.get(task.realActivity); 4039 if (ai == null) { 4040 try { 4041 ai = pm.getActivityInfo(task.realActivity, 4042 PackageManager.GET_UNINSTALLED_PACKAGES 4043 | PackageManager.GET_DISABLED_COMPONENTS, user); 4044 } catch (RemoteException e) { 4045 // Will never happen. 4046 continue; 4047 } 4048 if (ai == null) { 4049 ai = dummyAct; 4050 } 4051 availActCache.put(task.realActivity, ai); 4052 } 4053 if (ai == dummyAct) { 4054 // This could be either because the activity no longer exists, or the 4055 // app is temporarily gone. For the former we want to remove the recents 4056 // entry; for the latter we want to mark it as unavailable. 4057 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4058 if (app == null) { 4059 try { 4060 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4061 PackageManager.GET_UNINSTALLED_PACKAGES 4062 | PackageManager.GET_DISABLED_COMPONENTS, user); 4063 } catch (RemoteException e) { 4064 // Will never happen. 4065 continue; 4066 } 4067 if (app == null) { 4068 app = dummyApp; 4069 } 4070 availAppCache.put(task.realActivity.getPackageName(), app); 4071 } 4072 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4073 // Doesn't exist any more! Good-bye. 4074 mRecentTasks.remove(i); 4075 task.removedFromRecents(mTaskPersister); 4076 i--; 4077 N--; 4078 Slog.w(TAG, "Removing no longer valid recent: " + task); 4079 continue; 4080 } else { 4081 // Otherwise just not available for now. 4082 if (task.isAvailable) { 4083 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4084 + task); 4085 } 4086 task.isAvailable = false; 4087 } 4088 } else { 4089 if (!ai.enabled || !ai.applicationInfo.enabled 4090 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4091 if (task.isAvailable) { 4092 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4093 + task + " (enabled=" + ai.enabled + "/" 4094 + ai.applicationInfo.enabled + " flags=" 4095 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4096 } 4097 task.isAvailable = false; 4098 } else { 4099 if (!task.isAvailable) { 4100 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4101 + task); 4102 } 4103 task.isAvailable = true; 4104 } 4105 } 4106 } 4107 } 4108 } 4109 4110 // Verify the affiliate chain for each task. 4111 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4112 } 4113 4114 mTmpRecents.clear(); 4115 // mRecentTasks is now in sorted, affiliated order. 4116 } 4117 4118 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4119 int N = mRecentTasks.size(); 4120 TaskRecord top = task; 4121 int topIndex = taskIndex; 4122 while (top.mNextAffiliate != null && topIndex > 0) { 4123 top = top.mNextAffiliate; 4124 topIndex--; 4125 } 4126 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4127 + topIndex + " from intial " + taskIndex); 4128 // Find the end of the chain, doing a sanity check along the way. 4129 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4130 int endIndex = topIndex; 4131 TaskRecord prev = top; 4132 while (endIndex < N) { 4133 TaskRecord cur = mRecentTasks.get(endIndex); 4134 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4135 + endIndex + " " + cur); 4136 if (cur == top) { 4137 // Verify start of the chain. 4138 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4139 Slog.wtf(TAG, "Bad chain @" + endIndex 4140 + ": first task has next affiliate: " + prev); 4141 sane = false; 4142 break; 4143 } 4144 } else { 4145 // Verify middle of the chain's next points back to the one before. 4146 if (cur.mNextAffiliate != prev 4147 || cur.mNextAffiliateTaskId != prev.taskId) { 4148 Slog.wtf(TAG, "Bad chain @" + endIndex 4149 + ": middle task " + cur + " @" + endIndex 4150 + " has bad next affiliate " 4151 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4152 + ", expected " + prev); 4153 sane = false; 4154 break; 4155 } 4156 } 4157 if (cur.mPrevAffiliateTaskId == -1) { 4158 // Chain ends here. 4159 if (cur.mPrevAffiliate != null) { 4160 Slog.wtf(TAG, "Bad chain @" + endIndex 4161 + ": last task " + cur + " has previous affiliate " 4162 + cur.mPrevAffiliate); 4163 sane = false; 4164 } 4165 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4166 break; 4167 } else { 4168 // Verify middle of the chain's prev points to a valid item. 4169 if (cur.mPrevAffiliate == null) { 4170 Slog.wtf(TAG, "Bad chain @" + endIndex 4171 + ": task " + cur + " has previous affiliate " 4172 + cur.mPrevAffiliate + " but should be id " 4173 + cur.mPrevAffiliate); 4174 sane = false; 4175 break; 4176 } 4177 } 4178 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4179 Slog.wtf(TAG, "Bad chain @" + endIndex 4180 + ": task " + cur + " has affiliated id " 4181 + cur.mAffiliatedTaskId + " but should be " 4182 + task.mAffiliatedTaskId); 4183 sane = false; 4184 break; 4185 } 4186 prev = cur; 4187 endIndex++; 4188 if (endIndex >= N) { 4189 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4190 + ": last task " + prev); 4191 sane = false; 4192 break; 4193 } 4194 } 4195 if (sane) { 4196 if (endIndex < taskIndex) { 4197 Slog.wtf(TAG, "Bad chain @" + endIndex 4198 + ": did not extend to task " + task + " @" + taskIndex); 4199 sane = false; 4200 } 4201 } 4202 if (sane) { 4203 // All looks good, we can just move all of the affiliated tasks 4204 // to the top. 4205 for (int i=topIndex; i<=endIndex; i++) { 4206 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4207 + " from " + i + " to " + (i-topIndex)); 4208 TaskRecord cur = mRecentTasks.remove(i); 4209 mRecentTasks.add(i-topIndex, cur); 4210 } 4211 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4212 + " to " + endIndex); 4213 return true; 4214 } 4215 4216 // Whoops, couldn't do it. 4217 return false; 4218 } 4219 4220 final void addRecentTaskLocked(TaskRecord task) { 4221 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4222 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4223 4224 int N = mRecentTasks.size(); 4225 // Quick case: check if the top-most recent task is the same. 4226 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4227 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4228 return; 4229 } 4230 // Another quick case: check if this is part of a set of affiliated 4231 // tasks that are at the top. 4232 if (isAffiliated && N > 0 && task.inRecents 4233 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4234 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4235 + " at top when adding " + task); 4236 return; 4237 } 4238 // Another quick case: never add voice sessions. 4239 if (task.voiceSession != null) { 4240 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4241 return; 4242 } 4243 4244 boolean needAffiliationFix = false; 4245 4246 // Slightly less quick case: the task is already in recents, so all we need 4247 // to do is move it. 4248 if (task.inRecents) { 4249 int taskIndex = mRecentTasks.indexOf(task); 4250 if (taskIndex >= 0) { 4251 if (!isAffiliated) { 4252 // Simple case: this is not an affiliated task, so we just move it to the front. 4253 mRecentTasks.remove(taskIndex); 4254 mRecentTasks.add(0, task); 4255 notifyTaskPersisterLocked(task, false); 4256 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4257 + " from " + taskIndex); 4258 return; 4259 } else { 4260 // More complicated: need to keep all affiliated tasks together. 4261 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4262 // All went well. 4263 return; 4264 } 4265 4266 // Uh oh... something bad in the affiliation chain, try to rebuild 4267 // everything and then go through our general path of adding a new task. 4268 needAffiliationFix = true; 4269 } 4270 } else { 4271 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4272 needAffiliationFix = true; 4273 } 4274 } 4275 4276 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4277 trimRecentsForTask(task, true); 4278 4279 N = mRecentTasks.size(); 4280 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4281 final TaskRecord tr = mRecentTasks.remove(N - 1); 4282 tr.removedFromRecents(mTaskPersister); 4283 N--; 4284 } 4285 task.inRecents = true; 4286 if (!isAffiliated || needAffiliationFix) { 4287 // If this is a simple non-affiliated task, or we had some failure trying to 4288 // handle it as part of an affilated task, then just place it at the top. 4289 mRecentTasks.add(0, task); 4290 } else if (isAffiliated) { 4291 // If this is a new affiliated task, then move all of the affiliated tasks 4292 // to the front and insert this new one. 4293 TaskRecord other = task.mNextAffiliate; 4294 if (other == null) { 4295 other = task.mPrevAffiliate; 4296 } 4297 if (other != null) { 4298 int otherIndex = mRecentTasks.indexOf(other); 4299 if (otherIndex >= 0) { 4300 // Insert new task at appropriate location. 4301 int taskIndex; 4302 if (other == task.mNextAffiliate) { 4303 // We found the index of our next affiliation, which is who is 4304 // before us in the list, so add after that point. 4305 taskIndex = otherIndex+1; 4306 } else { 4307 // We found the index of our previous affiliation, which is who is 4308 // after us in the list, so add at their position. 4309 taskIndex = otherIndex; 4310 } 4311 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4312 + taskIndex + ": " + task); 4313 mRecentTasks.add(taskIndex, task); 4314 4315 // Now move everything to the front. 4316 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4317 // All went well. 4318 return; 4319 } 4320 4321 // Uh oh... something bad in the affiliation chain, try to rebuild 4322 // everything and then go through our general path of adding a new task. 4323 needAffiliationFix = true; 4324 } else { 4325 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4326 + other); 4327 needAffiliationFix = true; 4328 } 4329 } else { 4330 if (DEBUG_RECENTS) Slog.d(TAG, 4331 "addRecent: adding affiliated task without next/prev:" + task); 4332 needAffiliationFix = true; 4333 } 4334 } 4335 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4336 4337 if (needAffiliationFix) { 4338 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4339 cleanupRecentTasksLocked(task.userId); 4340 } 4341 } 4342 4343 /** 4344 * If needed, remove oldest existing entries in recents that are for the same kind 4345 * of task as the given one. 4346 */ 4347 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4348 int N = mRecentTasks.size(); 4349 final Intent intent = task.intent; 4350 final boolean document = intent != null && intent.isDocument(); 4351 4352 int maxRecents = task.maxRecents - 1; 4353 for (int i=0; i<N; i++) { 4354 final TaskRecord tr = mRecentTasks.get(i); 4355 if (task != tr) { 4356 if (task.userId != tr.userId) { 4357 continue; 4358 } 4359 if (i > MAX_RECENT_BITMAPS) { 4360 tr.freeLastThumbnail(); 4361 } 4362 final Intent trIntent = tr.intent; 4363 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4364 (intent == null || !intent.filterEquals(trIntent))) { 4365 continue; 4366 } 4367 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4368 if (document && trIsDocument) { 4369 // These are the same document activity (not necessarily the same doc). 4370 if (maxRecents > 0) { 4371 --maxRecents; 4372 continue; 4373 } 4374 // Hit the maximum number of documents for this task. Fall through 4375 // and remove this document from recents. 4376 } else if (document || trIsDocument) { 4377 // Only one of these is a document. Not the droid we're looking for. 4378 continue; 4379 } 4380 } 4381 4382 if (!doTrim) { 4383 // If the caller is not actually asking for a trim, just tell them we reached 4384 // a point where the trim would happen. 4385 return i; 4386 } 4387 4388 // Either task and tr are the same or, their affinities match or their intents match 4389 // and neither of them is a document, or they are documents using the same activity 4390 // and their maxRecents has been reached. 4391 tr.disposeThumbnail(); 4392 mRecentTasks.remove(i); 4393 if (task != tr) { 4394 tr.removedFromRecents(mTaskPersister); 4395 } 4396 i--; 4397 N--; 4398 if (task.intent == null) { 4399 // If the new recent task we are adding is not fully 4400 // specified, then replace it with the existing recent task. 4401 task = tr; 4402 } 4403 notifyTaskPersisterLocked(tr, false); 4404 } 4405 4406 return -1; 4407 } 4408 4409 @Override 4410 public void reportActivityFullyDrawn(IBinder token) { 4411 synchronized (this) { 4412 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4413 if (r == null) { 4414 return; 4415 } 4416 r.reportFullyDrawnLocked(); 4417 } 4418 } 4419 4420 @Override 4421 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4422 synchronized (this) { 4423 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4424 if (r == null) { 4425 return; 4426 } 4427 final long origId = Binder.clearCallingIdentity(); 4428 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4429 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4430 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4431 if (config != null) { 4432 r.frozenBeforeDestroy = true; 4433 if (!updateConfigurationLocked(config, r, false, false)) { 4434 mStackSupervisor.resumeTopActivitiesLocked(); 4435 } 4436 } 4437 Binder.restoreCallingIdentity(origId); 4438 } 4439 } 4440 4441 @Override 4442 public int getRequestedOrientation(IBinder token) { 4443 synchronized (this) { 4444 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4445 if (r == null) { 4446 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4447 } 4448 return mWindowManager.getAppOrientation(r.appToken); 4449 } 4450 } 4451 4452 /** 4453 * This is the internal entry point for handling Activity.finish(). 4454 * 4455 * @param token The Binder token referencing the Activity we want to finish. 4456 * @param resultCode Result code, if any, from this Activity. 4457 * @param resultData Result data (Intent), if any, from this Activity. 4458 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4459 * the root Activity in the task. 4460 * 4461 * @return Returns true if the activity successfully finished, or false if it is still running. 4462 */ 4463 @Override 4464 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4465 boolean finishTask) { 4466 // Refuse possible leaked file descriptors 4467 if (resultData != null && resultData.hasFileDescriptors() == true) { 4468 throw new IllegalArgumentException("File descriptors passed in Intent"); 4469 } 4470 4471 synchronized(this) { 4472 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4473 if (r == null) { 4474 return true; 4475 } 4476 // Keep track of the root activity of the task before we finish it 4477 TaskRecord tr = r.task; 4478 ActivityRecord rootR = tr.getRootActivity(); 4479 // Do not allow task to finish in Lock Task mode. 4480 if (tr == mStackSupervisor.mLockTaskModeTask) { 4481 if (rootR == r) { 4482 mStackSupervisor.showLockTaskToast(); 4483 return false; 4484 } 4485 } 4486 if (mController != null) { 4487 // Find the first activity that is not finishing. 4488 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4489 if (next != null) { 4490 // ask watcher if this is allowed 4491 boolean resumeOK = true; 4492 try { 4493 resumeOK = mController.activityResuming(next.packageName); 4494 } catch (RemoteException e) { 4495 mController = null; 4496 Watchdog.getInstance().setActivityController(null); 4497 } 4498 4499 if (!resumeOK) { 4500 return false; 4501 } 4502 } 4503 } 4504 final long origId = Binder.clearCallingIdentity(); 4505 try { 4506 boolean res; 4507 if (finishTask && r == rootR) { 4508 // If requested, remove the task that is associated to this activity only if it 4509 // was the root activity in the task. The result code and data is ignored because 4510 // we don't support returning them across task boundaries. 4511 res = removeTaskByIdLocked(tr.taskId, 0); 4512 } else { 4513 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4514 resultData, "app-request", true); 4515 } 4516 return res; 4517 } finally { 4518 Binder.restoreCallingIdentity(origId); 4519 } 4520 } 4521 } 4522 4523 @Override 4524 public final void finishHeavyWeightApp() { 4525 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4526 != PackageManager.PERMISSION_GRANTED) { 4527 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4528 + Binder.getCallingPid() 4529 + ", uid=" + Binder.getCallingUid() 4530 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4531 Slog.w(TAG, msg); 4532 throw new SecurityException(msg); 4533 } 4534 4535 synchronized(this) { 4536 if (mHeavyWeightProcess == null) { 4537 return; 4538 } 4539 4540 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4541 mHeavyWeightProcess.activities); 4542 for (int i=0; i<activities.size(); i++) { 4543 ActivityRecord r = activities.get(i); 4544 if (!r.finishing) { 4545 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4546 null, "finish-heavy", true); 4547 } 4548 } 4549 4550 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4551 mHeavyWeightProcess.userId, 0)); 4552 mHeavyWeightProcess = null; 4553 } 4554 } 4555 4556 @Override 4557 public void crashApplication(int uid, int initialPid, String packageName, 4558 String message) { 4559 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4560 != PackageManager.PERMISSION_GRANTED) { 4561 String msg = "Permission Denial: crashApplication() from pid=" 4562 + Binder.getCallingPid() 4563 + ", uid=" + Binder.getCallingUid() 4564 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4565 Slog.w(TAG, msg); 4566 throw new SecurityException(msg); 4567 } 4568 4569 synchronized(this) { 4570 ProcessRecord proc = null; 4571 4572 // Figure out which process to kill. We don't trust that initialPid 4573 // still has any relation to current pids, so must scan through the 4574 // list. 4575 synchronized (mPidsSelfLocked) { 4576 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4577 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4578 if (p.uid != uid) { 4579 continue; 4580 } 4581 if (p.pid == initialPid) { 4582 proc = p; 4583 break; 4584 } 4585 if (p.pkgList.containsKey(packageName)) { 4586 proc = p; 4587 } 4588 } 4589 } 4590 4591 if (proc == null) { 4592 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4593 + " initialPid=" + initialPid 4594 + " packageName=" + packageName); 4595 return; 4596 } 4597 4598 if (proc.thread != null) { 4599 if (proc.pid == Process.myPid()) { 4600 Log.w(TAG, "crashApplication: trying to crash self!"); 4601 return; 4602 } 4603 long ident = Binder.clearCallingIdentity(); 4604 try { 4605 proc.thread.scheduleCrash(message); 4606 } catch (RemoteException e) { 4607 } 4608 Binder.restoreCallingIdentity(ident); 4609 } 4610 } 4611 } 4612 4613 @Override 4614 public final void finishSubActivity(IBinder token, String resultWho, 4615 int requestCode) { 4616 synchronized(this) { 4617 final long origId = Binder.clearCallingIdentity(); 4618 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4619 if (r != null) { 4620 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4621 } 4622 Binder.restoreCallingIdentity(origId); 4623 } 4624 } 4625 4626 @Override 4627 public boolean finishActivityAffinity(IBinder token) { 4628 synchronized(this) { 4629 final long origId = Binder.clearCallingIdentity(); 4630 try { 4631 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4632 4633 ActivityRecord rootR = r.task.getRootActivity(); 4634 // Do not allow task to finish in Lock Task mode. 4635 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4636 if (rootR == r) { 4637 mStackSupervisor.showLockTaskToast(); 4638 return false; 4639 } 4640 } 4641 boolean res = false; 4642 if (r != null) { 4643 res = r.task.stack.finishActivityAffinityLocked(r); 4644 } 4645 return res; 4646 } finally { 4647 Binder.restoreCallingIdentity(origId); 4648 } 4649 } 4650 } 4651 4652 @Override 4653 public void finishVoiceTask(IVoiceInteractionSession session) { 4654 synchronized(this) { 4655 final long origId = Binder.clearCallingIdentity(); 4656 try { 4657 mStackSupervisor.finishVoiceTask(session); 4658 } finally { 4659 Binder.restoreCallingIdentity(origId); 4660 } 4661 } 4662 4663 } 4664 4665 @Override 4666 public boolean releaseActivityInstance(IBinder token) { 4667 synchronized(this) { 4668 final long origId = Binder.clearCallingIdentity(); 4669 try { 4670 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4671 if (r.task == null || r.task.stack == null) { 4672 return false; 4673 } 4674 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4675 } finally { 4676 Binder.restoreCallingIdentity(origId); 4677 } 4678 } 4679 } 4680 4681 @Override 4682 public void releaseSomeActivities(IApplicationThread appInt) { 4683 synchronized(this) { 4684 final long origId = Binder.clearCallingIdentity(); 4685 try { 4686 ProcessRecord app = getRecordForAppLocked(appInt); 4687 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4688 } finally { 4689 Binder.restoreCallingIdentity(origId); 4690 } 4691 } 4692 } 4693 4694 @Override 4695 public boolean willActivityBeVisible(IBinder token) { 4696 synchronized(this) { 4697 ActivityStack stack = ActivityRecord.getStackLocked(token); 4698 if (stack != null) { 4699 return stack.willActivityBeVisibleLocked(token); 4700 } 4701 return false; 4702 } 4703 } 4704 4705 @Override 4706 public void overridePendingTransition(IBinder token, String packageName, 4707 int enterAnim, int exitAnim) { 4708 synchronized(this) { 4709 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4710 if (self == null) { 4711 return; 4712 } 4713 4714 final long origId = Binder.clearCallingIdentity(); 4715 4716 if (self.state == ActivityState.RESUMED 4717 || self.state == ActivityState.PAUSING) { 4718 mWindowManager.overridePendingAppTransition(packageName, 4719 enterAnim, exitAnim, null); 4720 } 4721 4722 Binder.restoreCallingIdentity(origId); 4723 } 4724 } 4725 4726 /** 4727 * Main function for removing an existing process from the activity manager 4728 * as a result of that process going away. Clears out all connections 4729 * to the process. 4730 */ 4731 private final void handleAppDiedLocked(ProcessRecord app, 4732 boolean restarting, boolean allowRestart) { 4733 int pid = app.pid; 4734 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4735 if (!kept && !restarting) { 4736 removeLruProcessLocked(app); 4737 if (pid > 0) { 4738 ProcessList.remove(pid); 4739 } 4740 } 4741 4742 if (mProfileProc == app) { 4743 clearProfilerLocked(); 4744 } 4745 4746 // Remove this application's activities from active lists. 4747 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4748 4749 app.activities.clear(); 4750 4751 if (app.instrumentationClass != null) { 4752 Slog.w(TAG, "Crash of app " + app.processName 4753 + " running instrumentation " + app.instrumentationClass); 4754 Bundle info = new Bundle(); 4755 info.putString("shortMsg", "Process crashed."); 4756 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4757 } 4758 4759 if (!restarting) { 4760 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4761 // If there was nothing to resume, and we are not already 4762 // restarting this process, but there is a visible activity that 4763 // is hosted by the process... then make sure all visible 4764 // activities are running, taking care of restarting this 4765 // process. 4766 if (hasVisibleActivities) { 4767 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4768 } 4769 } 4770 } 4771 } 4772 4773 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4774 IBinder threadBinder = thread.asBinder(); 4775 // Find the application record. 4776 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4777 ProcessRecord rec = mLruProcesses.get(i); 4778 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4779 return i; 4780 } 4781 } 4782 return -1; 4783 } 4784 4785 final ProcessRecord getRecordForAppLocked( 4786 IApplicationThread thread) { 4787 if (thread == null) { 4788 return null; 4789 } 4790 4791 int appIndex = getLRURecordIndexForAppLocked(thread); 4792 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4793 } 4794 4795 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4796 // If there are no longer any background processes running, 4797 // and the app that died was not running instrumentation, 4798 // then tell everyone we are now low on memory. 4799 boolean haveBg = false; 4800 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4801 ProcessRecord rec = mLruProcesses.get(i); 4802 if (rec.thread != null 4803 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4804 haveBg = true; 4805 break; 4806 } 4807 } 4808 4809 if (!haveBg) { 4810 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4811 if (doReport) { 4812 long now = SystemClock.uptimeMillis(); 4813 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4814 doReport = false; 4815 } else { 4816 mLastMemUsageReportTime = now; 4817 } 4818 } 4819 final ArrayList<ProcessMemInfo> memInfos 4820 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4821 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4822 long now = SystemClock.uptimeMillis(); 4823 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4824 ProcessRecord rec = mLruProcesses.get(i); 4825 if (rec == dyingProc || rec.thread == null) { 4826 continue; 4827 } 4828 if (doReport) { 4829 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4830 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4831 } 4832 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4833 // The low memory report is overriding any current 4834 // state for a GC request. Make sure to do 4835 // heavy/important/visible/foreground processes first. 4836 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4837 rec.lastRequestedGc = 0; 4838 } else { 4839 rec.lastRequestedGc = rec.lastLowMemory; 4840 } 4841 rec.reportLowMemory = true; 4842 rec.lastLowMemory = now; 4843 mProcessesToGc.remove(rec); 4844 addProcessToGcListLocked(rec); 4845 } 4846 } 4847 if (doReport) { 4848 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4849 mHandler.sendMessage(msg); 4850 } 4851 scheduleAppGcsLocked(); 4852 } 4853 } 4854 4855 final void appDiedLocked(ProcessRecord app) { 4856 appDiedLocked(app, app.pid, app.thread); 4857 } 4858 4859 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4860 // First check if this ProcessRecord is actually active for the pid. 4861 synchronized (mPidsSelfLocked) { 4862 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4863 if (curProc != app) { 4864 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4865 return; 4866 } 4867 } 4868 4869 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4870 synchronized (stats) { 4871 stats.noteProcessDiedLocked(app.info.uid, pid); 4872 } 4873 4874 Process.killProcessQuiet(pid); 4875 Process.killProcessGroup(app.uid, pid); 4876 app.killed = true; 4877 4878 // Clean up already done if the process has been re-started. 4879 if (app.pid == pid && app.thread != null && 4880 app.thread.asBinder() == thread.asBinder()) { 4881 boolean doLowMem = app.instrumentationClass == null; 4882 boolean doOomAdj = doLowMem; 4883 if (!app.killedByAm) { 4884 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4885 + ") has died"); 4886 mAllowLowerMemLevel = true; 4887 } else { 4888 // Note that we always want to do oom adj to update our state with the 4889 // new number of procs. 4890 mAllowLowerMemLevel = false; 4891 doLowMem = false; 4892 } 4893 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4894 if (DEBUG_CLEANUP) Slog.v( 4895 TAG, "Dying app: " + app + ", pid: " + pid 4896 + ", thread: " + thread.asBinder()); 4897 handleAppDiedLocked(app, false, true); 4898 4899 if (doOomAdj) { 4900 updateOomAdjLocked(); 4901 } 4902 if (doLowMem) { 4903 doLowMemReportIfNeededLocked(app); 4904 } 4905 } else if (app.pid != pid) { 4906 // A new process has already been started. 4907 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4908 + ") has died and restarted (pid " + app.pid + ")."); 4909 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4910 } else if (DEBUG_PROCESSES) { 4911 Slog.d(TAG, "Received spurious death notification for thread " 4912 + thread.asBinder()); 4913 } 4914 } 4915 4916 /** 4917 * If a stack trace dump file is configured, dump process stack traces. 4918 * @param clearTraces causes the dump file to be erased prior to the new 4919 * traces being written, if true; when false, the new traces will be 4920 * appended to any existing file content. 4921 * @param firstPids of dalvik VM processes to dump stack traces for first 4922 * @param lastPids of dalvik VM processes to dump stack traces for last 4923 * @param nativeProcs optional list of native process names to dump stack crawls 4924 * @return file containing stack traces, or null if no dump file is configured 4925 */ 4926 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4927 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4928 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4929 if (tracesPath == null || tracesPath.length() == 0) { 4930 return null; 4931 } 4932 4933 File tracesFile = new File(tracesPath); 4934 try { 4935 File tracesDir = tracesFile.getParentFile(); 4936 if (!tracesDir.exists()) { 4937 tracesDir.mkdirs(); 4938 if (!SELinux.restorecon(tracesDir)) { 4939 return null; 4940 } 4941 } 4942 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4943 4944 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4945 tracesFile.createNewFile(); 4946 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4947 } catch (IOException e) { 4948 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4949 return null; 4950 } 4951 4952 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4953 return tracesFile; 4954 } 4955 4956 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4957 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4958 // Use a FileObserver to detect when traces finish writing. 4959 // The order of traces is considered important to maintain for legibility. 4960 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4961 @Override 4962 public synchronized void onEvent(int event, String path) { notify(); } 4963 }; 4964 4965 try { 4966 observer.startWatching(); 4967 4968 // First collect all of the stacks of the most important pids. 4969 if (firstPids != null) { 4970 try { 4971 int num = firstPids.size(); 4972 for (int i = 0; i < num; i++) { 4973 synchronized (observer) { 4974 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4975 observer.wait(200); // Wait for write-close, give up after 200msec 4976 } 4977 } 4978 } catch (InterruptedException e) { 4979 Slog.wtf(TAG, e); 4980 } 4981 } 4982 4983 // Next collect the stacks of the native pids 4984 if (nativeProcs != null) { 4985 int[] pids = Process.getPidsForCommands(nativeProcs); 4986 if (pids != null) { 4987 for (int pid : pids) { 4988 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4989 } 4990 } 4991 } 4992 4993 // Lastly, measure CPU usage. 4994 if (processCpuTracker != null) { 4995 processCpuTracker.init(); 4996 System.gc(); 4997 processCpuTracker.update(); 4998 try { 4999 synchronized (processCpuTracker) { 5000 processCpuTracker.wait(500); // measure over 1/2 second. 5001 } 5002 } catch (InterruptedException e) { 5003 } 5004 processCpuTracker.update(); 5005 5006 // We'll take the stack crawls of just the top apps using CPU. 5007 final int N = processCpuTracker.countWorkingStats(); 5008 int numProcs = 0; 5009 for (int i=0; i<N && numProcs<5; i++) { 5010 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5011 if (lastPids.indexOfKey(stats.pid) >= 0) { 5012 numProcs++; 5013 try { 5014 synchronized (observer) { 5015 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 5016 observer.wait(200); // Wait for write-close, give up after 200msec 5017 } 5018 } catch (InterruptedException e) { 5019 Slog.wtf(TAG, e); 5020 } 5021 5022 } 5023 } 5024 } 5025 } finally { 5026 observer.stopWatching(); 5027 } 5028 } 5029 5030 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5031 if (true || IS_USER_BUILD) { 5032 return; 5033 } 5034 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5035 if (tracesPath == null || tracesPath.length() == 0) { 5036 return; 5037 } 5038 5039 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5040 StrictMode.allowThreadDiskWrites(); 5041 try { 5042 final File tracesFile = new File(tracesPath); 5043 final File tracesDir = tracesFile.getParentFile(); 5044 final File tracesTmp = new File(tracesDir, "__tmp__"); 5045 try { 5046 if (!tracesDir.exists()) { 5047 tracesDir.mkdirs(); 5048 if (!SELinux.restorecon(tracesDir.getPath())) { 5049 return; 5050 } 5051 } 5052 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5053 5054 if (tracesFile.exists()) { 5055 tracesTmp.delete(); 5056 tracesFile.renameTo(tracesTmp); 5057 } 5058 StringBuilder sb = new StringBuilder(); 5059 Time tobj = new Time(); 5060 tobj.set(System.currentTimeMillis()); 5061 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5062 sb.append(": "); 5063 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5064 sb.append(" since "); 5065 sb.append(msg); 5066 FileOutputStream fos = new FileOutputStream(tracesFile); 5067 fos.write(sb.toString().getBytes()); 5068 if (app == null) { 5069 fos.write("\n*** No application process!".getBytes()); 5070 } 5071 fos.close(); 5072 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5073 } catch (IOException e) { 5074 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5075 return; 5076 } 5077 5078 if (app != null) { 5079 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5080 firstPids.add(app.pid); 5081 dumpStackTraces(tracesPath, firstPids, null, null, null); 5082 } 5083 5084 File lastTracesFile = null; 5085 File curTracesFile = null; 5086 for (int i=9; i>=0; i--) { 5087 String name = String.format(Locale.US, "slow%02d.txt", i); 5088 curTracesFile = new File(tracesDir, name); 5089 if (curTracesFile.exists()) { 5090 if (lastTracesFile != null) { 5091 curTracesFile.renameTo(lastTracesFile); 5092 } else { 5093 curTracesFile.delete(); 5094 } 5095 } 5096 lastTracesFile = curTracesFile; 5097 } 5098 tracesFile.renameTo(curTracesFile); 5099 if (tracesTmp.exists()) { 5100 tracesTmp.renameTo(tracesFile); 5101 } 5102 } finally { 5103 StrictMode.setThreadPolicy(oldPolicy); 5104 } 5105 } 5106 5107 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5108 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5109 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5110 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5111 5112 if (mController != null) { 5113 try { 5114 // 0 == continue, -1 = kill process immediately 5115 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5116 if (res < 0 && app.pid != MY_PID) { 5117 app.kill("anr", true); 5118 } 5119 } catch (RemoteException e) { 5120 mController = null; 5121 Watchdog.getInstance().setActivityController(null); 5122 } 5123 } 5124 5125 long anrTime = SystemClock.uptimeMillis(); 5126 if (MONITOR_CPU_USAGE) { 5127 updateCpuStatsNow(); 5128 } 5129 5130 synchronized (this) { 5131 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5132 if (mShuttingDown) { 5133 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5134 return; 5135 } else if (app.notResponding) { 5136 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5137 return; 5138 } else if (app.crashing) { 5139 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5140 return; 5141 } 5142 5143 // In case we come through here for the same app before completing 5144 // this one, mark as anring now so we will bail out. 5145 app.notResponding = true; 5146 5147 // Log the ANR to the event log. 5148 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5149 app.processName, app.info.flags, annotation); 5150 5151 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5152 firstPids.add(app.pid); 5153 5154 int parentPid = app.pid; 5155 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5156 if (parentPid != app.pid) firstPids.add(parentPid); 5157 5158 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5159 5160 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5161 ProcessRecord r = mLruProcesses.get(i); 5162 if (r != null && r.thread != null) { 5163 int pid = r.pid; 5164 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5165 if (r.persistent) { 5166 firstPids.add(pid); 5167 } else { 5168 lastPids.put(pid, Boolean.TRUE); 5169 } 5170 } 5171 } 5172 } 5173 } 5174 5175 // Log the ANR to the main log. 5176 StringBuilder info = new StringBuilder(); 5177 info.setLength(0); 5178 info.append("ANR in ").append(app.processName); 5179 if (activity != null && activity.shortComponentName != null) { 5180 info.append(" (").append(activity.shortComponentName).append(")"); 5181 } 5182 info.append("\n"); 5183 info.append("PID: ").append(app.pid).append("\n"); 5184 if (annotation != null) { 5185 info.append("Reason: ").append(annotation).append("\n"); 5186 } 5187 if (parent != null && parent != activity) { 5188 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5189 } 5190 5191 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5192 5193 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5194 NATIVE_STACKS_OF_INTEREST); 5195 5196 String cpuInfo = null; 5197 if (MONITOR_CPU_USAGE) { 5198 updateCpuStatsNow(); 5199 synchronized (mProcessCpuTracker) { 5200 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5201 } 5202 info.append(processCpuTracker.printCurrentLoad()); 5203 info.append(cpuInfo); 5204 } 5205 5206 info.append(processCpuTracker.printCurrentState(anrTime)); 5207 5208 Slog.e(TAG, info.toString()); 5209 if (tracesFile == null) { 5210 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5211 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5212 } 5213 5214 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5215 cpuInfo, tracesFile, null); 5216 5217 if (mController != null) { 5218 try { 5219 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5220 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5221 if (res != 0) { 5222 if (res < 0 && app.pid != MY_PID) { 5223 app.kill("anr", true); 5224 } else { 5225 synchronized (this) { 5226 mServices.scheduleServiceTimeoutLocked(app); 5227 } 5228 } 5229 return; 5230 } 5231 } catch (RemoteException e) { 5232 mController = null; 5233 Watchdog.getInstance().setActivityController(null); 5234 } 5235 } 5236 5237 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5238 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5239 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5240 5241 synchronized (this) { 5242 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5243 app.kill("bg anr", true); 5244 return; 5245 } 5246 5247 // Set the app's notResponding state, and look up the errorReportReceiver 5248 makeAppNotRespondingLocked(app, 5249 activity != null ? activity.shortComponentName : null, 5250 annotation != null ? "ANR " + annotation : "ANR", 5251 info.toString()); 5252 5253 // Bring up the infamous App Not Responding dialog 5254 Message msg = Message.obtain(); 5255 HashMap<String, Object> map = new HashMap<String, Object>(); 5256 msg.what = SHOW_NOT_RESPONDING_MSG; 5257 msg.obj = map; 5258 msg.arg1 = aboveSystem ? 1 : 0; 5259 map.put("app", app); 5260 if (activity != null) { 5261 map.put("activity", activity); 5262 } 5263 5264 mHandler.sendMessage(msg); 5265 } 5266 } 5267 5268 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5269 if (!mLaunchWarningShown) { 5270 mLaunchWarningShown = true; 5271 mHandler.post(new Runnable() { 5272 @Override 5273 public void run() { 5274 synchronized (ActivityManagerService.this) { 5275 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5276 d.show(); 5277 mHandler.postDelayed(new Runnable() { 5278 @Override 5279 public void run() { 5280 synchronized (ActivityManagerService.this) { 5281 d.dismiss(); 5282 mLaunchWarningShown = false; 5283 } 5284 } 5285 }, 4000); 5286 } 5287 } 5288 }); 5289 } 5290 } 5291 5292 @Override 5293 public boolean clearApplicationUserData(final String packageName, 5294 final IPackageDataObserver observer, int userId) { 5295 enforceNotIsolatedCaller("clearApplicationUserData"); 5296 int uid = Binder.getCallingUid(); 5297 int pid = Binder.getCallingPid(); 5298 userId = handleIncomingUser(pid, uid, 5299 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5300 long callingId = Binder.clearCallingIdentity(); 5301 try { 5302 IPackageManager pm = AppGlobals.getPackageManager(); 5303 int pkgUid = -1; 5304 synchronized(this) { 5305 try { 5306 pkgUid = pm.getPackageUid(packageName, userId); 5307 } catch (RemoteException e) { 5308 } 5309 if (pkgUid == -1) { 5310 Slog.w(TAG, "Invalid packageName: " + packageName); 5311 if (observer != null) { 5312 try { 5313 observer.onRemoveCompleted(packageName, false); 5314 } catch (RemoteException e) { 5315 Slog.i(TAG, "Observer no longer exists."); 5316 } 5317 } 5318 return false; 5319 } 5320 if (uid == pkgUid || checkComponentPermission( 5321 android.Manifest.permission.CLEAR_APP_USER_DATA, 5322 pid, uid, -1, true) 5323 == PackageManager.PERMISSION_GRANTED) { 5324 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5325 } else { 5326 throw new SecurityException("PID " + pid + " does not have permission " 5327 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5328 + " of package " + packageName); 5329 } 5330 5331 // Remove all tasks match the cleared application package and user 5332 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5333 final TaskRecord tr = mRecentTasks.get(i); 5334 final String taskPackageName = 5335 tr.getBaseIntent().getComponent().getPackageName(); 5336 if (tr.userId != userId) continue; 5337 if (!taskPackageName.equals(packageName)) continue; 5338 removeTaskByIdLocked(tr.taskId, 0); 5339 } 5340 } 5341 5342 try { 5343 // Clear application user data 5344 pm.clearApplicationUserData(packageName, observer, userId); 5345 5346 synchronized(this) { 5347 // Remove all permissions granted from/to this package 5348 removeUriPermissionsForPackageLocked(packageName, userId, true); 5349 } 5350 5351 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5352 Uri.fromParts("package", packageName, null)); 5353 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5354 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5355 null, null, 0, null, null, null, false, false, userId); 5356 } catch (RemoteException e) { 5357 } 5358 } finally { 5359 Binder.restoreCallingIdentity(callingId); 5360 } 5361 return true; 5362 } 5363 5364 @Override 5365 public void killBackgroundProcesses(final String packageName, int userId) { 5366 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5367 != PackageManager.PERMISSION_GRANTED && 5368 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5369 != PackageManager.PERMISSION_GRANTED) { 5370 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5371 + Binder.getCallingPid() 5372 + ", uid=" + Binder.getCallingUid() 5373 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5374 Slog.w(TAG, msg); 5375 throw new SecurityException(msg); 5376 } 5377 5378 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5379 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5380 long callingId = Binder.clearCallingIdentity(); 5381 try { 5382 IPackageManager pm = AppGlobals.getPackageManager(); 5383 synchronized(this) { 5384 int appId = -1; 5385 try { 5386 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5387 } catch (RemoteException e) { 5388 } 5389 if (appId == -1) { 5390 Slog.w(TAG, "Invalid packageName: " + packageName); 5391 return; 5392 } 5393 killPackageProcessesLocked(packageName, appId, userId, 5394 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5395 } 5396 } finally { 5397 Binder.restoreCallingIdentity(callingId); 5398 } 5399 } 5400 5401 @Override 5402 public void killAllBackgroundProcesses() { 5403 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5404 != PackageManager.PERMISSION_GRANTED) { 5405 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5406 + Binder.getCallingPid() 5407 + ", uid=" + Binder.getCallingUid() 5408 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5409 Slog.w(TAG, msg); 5410 throw new SecurityException(msg); 5411 } 5412 5413 long callingId = Binder.clearCallingIdentity(); 5414 try { 5415 synchronized(this) { 5416 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5417 final int NP = mProcessNames.getMap().size(); 5418 for (int ip=0; ip<NP; ip++) { 5419 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5420 final int NA = apps.size(); 5421 for (int ia=0; ia<NA; ia++) { 5422 ProcessRecord app = apps.valueAt(ia); 5423 if (app.persistent) { 5424 // we don't kill persistent processes 5425 continue; 5426 } 5427 if (app.removed) { 5428 procs.add(app); 5429 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5430 app.removed = true; 5431 procs.add(app); 5432 } 5433 } 5434 } 5435 5436 int N = procs.size(); 5437 for (int i=0; i<N; i++) { 5438 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5439 } 5440 mAllowLowerMemLevel = true; 5441 updateOomAdjLocked(); 5442 doLowMemReportIfNeededLocked(null); 5443 } 5444 } finally { 5445 Binder.restoreCallingIdentity(callingId); 5446 } 5447 } 5448 5449 @Override 5450 public void forceStopPackage(final String packageName, int userId) { 5451 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5452 != PackageManager.PERMISSION_GRANTED) { 5453 String msg = "Permission Denial: forceStopPackage() from pid=" 5454 + Binder.getCallingPid() 5455 + ", uid=" + Binder.getCallingUid() 5456 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5457 Slog.w(TAG, msg); 5458 throw new SecurityException(msg); 5459 } 5460 final int callingPid = Binder.getCallingPid(); 5461 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5462 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5463 long callingId = Binder.clearCallingIdentity(); 5464 try { 5465 IPackageManager pm = AppGlobals.getPackageManager(); 5466 synchronized(this) { 5467 int[] users = userId == UserHandle.USER_ALL 5468 ? getUsersLocked() : new int[] { userId }; 5469 for (int user : users) { 5470 int pkgUid = -1; 5471 try { 5472 pkgUid = pm.getPackageUid(packageName, user); 5473 } catch (RemoteException e) { 5474 } 5475 if (pkgUid == -1) { 5476 Slog.w(TAG, "Invalid packageName: " + packageName); 5477 continue; 5478 } 5479 try { 5480 pm.setPackageStoppedState(packageName, true, user); 5481 } catch (RemoteException e) { 5482 } catch (IllegalArgumentException e) { 5483 Slog.w(TAG, "Failed trying to unstop package " 5484 + packageName + ": " + e); 5485 } 5486 if (isUserRunningLocked(user, false)) { 5487 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5488 } 5489 } 5490 } 5491 } finally { 5492 Binder.restoreCallingIdentity(callingId); 5493 } 5494 } 5495 5496 @Override 5497 public void addPackageDependency(String packageName) { 5498 synchronized (this) { 5499 int callingPid = Binder.getCallingPid(); 5500 if (callingPid == Process.myPid()) { 5501 // Yeah, um, no. 5502 Slog.w(TAG, "Can't addPackageDependency on system process"); 5503 return; 5504 } 5505 ProcessRecord proc; 5506 synchronized (mPidsSelfLocked) { 5507 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5508 } 5509 if (proc != null) { 5510 if (proc.pkgDeps == null) { 5511 proc.pkgDeps = new ArraySet<String>(1); 5512 } 5513 proc.pkgDeps.add(packageName); 5514 } 5515 } 5516 } 5517 5518 /* 5519 * The pkg name and app id have to be specified. 5520 */ 5521 @Override 5522 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5523 if (pkg == null) { 5524 return; 5525 } 5526 // Make sure the uid is valid. 5527 if (appid < 0) { 5528 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5529 return; 5530 } 5531 int callerUid = Binder.getCallingUid(); 5532 // Only the system server can kill an application 5533 if (callerUid == Process.SYSTEM_UID) { 5534 // Post an aysnc message to kill the application 5535 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5536 msg.arg1 = appid; 5537 msg.arg2 = 0; 5538 Bundle bundle = new Bundle(); 5539 bundle.putString("pkg", pkg); 5540 bundle.putString("reason", reason); 5541 msg.obj = bundle; 5542 mHandler.sendMessage(msg); 5543 } else { 5544 throw new SecurityException(callerUid + " cannot kill pkg: " + 5545 pkg); 5546 } 5547 } 5548 5549 @Override 5550 public void closeSystemDialogs(String reason) { 5551 enforceNotIsolatedCaller("closeSystemDialogs"); 5552 5553 final int pid = Binder.getCallingPid(); 5554 final int uid = Binder.getCallingUid(); 5555 final long origId = Binder.clearCallingIdentity(); 5556 try { 5557 synchronized (this) { 5558 // Only allow this from foreground processes, so that background 5559 // applications can't abuse it to prevent system UI from being shown. 5560 if (uid >= Process.FIRST_APPLICATION_UID) { 5561 ProcessRecord proc; 5562 synchronized (mPidsSelfLocked) { 5563 proc = mPidsSelfLocked.get(pid); 5564 } 5565 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5566 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5567 + " from background process " + proc); 5568 return; 5569 } 5570 } 5571 closeSystemDialogsLocked(reason); 5572 } 5573 } finally { 5574 Binder.restoreCallingIdentity(origId); 5575 } 5576 } 5577 5578 void closeSystemDialogsLocked(String reason) { 5579 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5580 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5581 | Intent.FLAG_RECEIVER_FOREGROUND); 5582 if (reason != null) { 5583 intent.putExtra("reason", reason); 5584 } 5585 mWindowManager.closeSystemDialogs(reason); 5586 5587 mStackSupervisor.closeSystemDialogsLocked(); 5588 5589 broadcastIntentLocked(null, null, intent, null, 5590 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5591 Process.SYSTEM_UID, UserHandle.USER_ALL); 5592 } 5593 5594 @Override 5595 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5596 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5597 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5598 for (int i=pids.length-1; i>=0; i--) { 5599 ProcessRecord proc; 5600 int oomAdj; 5601 synchronized (this) { 5602 synchronized (mPidsSelfLocked) { 5603 proc = mPidsSelfLocked.get(pids[i]); 5604 oomAdj = proc != null ? proc.setAdj : 0; 5605 } 5606 } 5607 infos[i] = new Debug.MemoryInfo(); 5608 Debug.getMemoryInfo(pids[i], infos[i]); 5609 if (proc != null) { 5610 synchronized (this) { 5611 if (proc.thread != null && proc.setAdj == oomAdj) { 5612 // Record this for posterity if the process has been stable. 5613 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5614 infos[i].getTotalUss(), false, proc.pkgList); 5615 } 5616 } 5617 } 5618 } 5619 return infos; 5620 } 5621 5622 @Override 5623 public long[] getProcessPss(int[] pids) { 5624 enforceNotIsolatedCaller("getProcessPss"); 5625 long[] pss = new long[pids.length]; 5626 for (int i=pids.length-1; i>=0; i--) { 5627 ProcessRecord proc; 5628 int oomAdj; 5629 synchronized (this) { 5630 synchronized (mPidsSelfLocked) { 5631 proc = mPidsSelfLocked.get(pids[i]); 5632 oomAdj = proc != null ? proc.setAdj : 0; 5633 } 5634 } 5635 long[] tmpUss = new long[1]; 5636 pss[i] = Debug.getPss(pids[i], tmpUss); 5637 if (proc != null) { 5638 synchronized (this) { 5639 if (proc.thread != null && proc.setAdj == oomAdj) { 5640 // Record this for posterity if the process has been stable. 5641 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5642 } 5643 } 5644 } 5645 } 5646 return pss; 5647 } 5648 5649 @Override 5650 public void killApplicationProcess(String processName, int uid) { 5651 if (processName == null) { 5652 return; 5653 } 5654 5655 int callerUid = Binder.getCallingUid(); 5656 // Only the system server can kill an application 5657 if (callerUid == Process.SYSTEM_UID) { 5658 synchronized (this) { 5659 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5660 if (app != null && app.thread != null) { 5661 try { 5662 app.thread.scheduleSuicide(); 5663 } catch (RemoteException e) { 5664 // If the other end already died, then our work here is done. 5665 } 5666 } else { 5667 Slog.w(TAG, "Process/uid not found attempting kill of " 5668 + processName + " / " + uid); 5669 } 5670 } 5671 } else { 5672 throw new SecurityException(callerUid + " cannot kill app process: " + 5673 processName); 5674 } 5675 } 5676 5677 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5678 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5679 false, true, false, false, UserHandle.getUserId(uid), reason); 5680 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5681 Uri.fromParts("package", packageName, null)); 5682 if (!mProcessesReady) { 5683 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5684 | Intent.FLAG_RECEIVER_FOREGROUND); 5685 } 5686 intent.putExtra(Intent.EXTRA_UID, uid); 5687 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5688 broadcastIntentLocked(null, null, intent, 5689 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5690 false, false, 5691 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5692 } 5693 5694 private void forceStopUserLocked(int userId, String reason) { 5695 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5696 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5697 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5698 | Intent.FLAG_RECEIVER_FOREGROUND); 5699 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5700 broadcastIntentLocked(null, null, intent, 5701 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5702 false, false, 5703 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5704 } 5705 5706 private final boolean killPackageProcessesLocked(String packageName, int appId, 5707 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5708 boolean doit, boolean evenPersistent, String reason) { 5709 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5710 5711 // Remove all processes this package may have touched: all with the 5712 // same UID (except for the system or root user), and all whose name 5713 // matches the package name. 5714 final int NP = mProcessNames.getMap().size(); 5715 for (int ip=0; ip<NP; ip++) { 5716 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5717 final int NA = apps.size(); 5718 for (int ia=0; ia<NA; ia++) { 5719 ProcessRecord app = apps.valueAt(ia); 5720 if (app.persistent && !evenPersistent) { 5721 // we don't kill persistent processes 5722 continue; 5723 } 5724 if (app.removed) { 5725 if (doit) { 5726 procs.add(app); 5727 } 5728 continue; 5729 } 5730 5731 // Skip process if it doesn't meet our oom adj requirement. 5732 if (app.setAdj < minOomAdj) { 5733 continue; 5734 } 5735 5736 // If no package is specified, we call all processes under the 5737 // give user id. 5738 if (packageName == null) { 5739 if (app.userId != userId) { 5740 continue; 5741 } 5742 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5743 continue; 5744 } 5745 // Package has been specified, we want to hit all processes 5746 // that match it. We need to qualify this by the processes 5747 // that are running under the specified app and user ID. 5748 } else { 5749 final boolean isDep = app.pkgDeps != null 5750 && app.pkgDeps.contains(packageName); 5751 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5752 continue; 5753 } 5754 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5755 continue; 5756 } 5757 if (!app.pkgList.containsKey(packageName) && !isDep) { 5758 continue; 5759 } 5760 } 5761 5762 // Process has passed all conditions, kill it! 5763 if (!doit) { 5764 return true; 5765 } 5766 app.removed = true; 5767 procs.add(app); 5768 } 5769 } 5770 5771 int N = procs.size(); 5772 for (int i=0; i<N; i++) { 5773 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5774 } 5775 updateOomAdjLocked(); 5776 return N > 0; 5777 } 5778 5779 private final boolean forceStopPackageLocked(String name, int appId, 5780 boolean callerWillRestart, boolean purgeCache, boolean doit, 5781 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5782 int i; 5783 int N; 5784 5785 if (userId == UserHandle.USER_ALL && name == null) { 5786 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5787 } 5788 5789 if (appId < 0 && name != null) { 5790 try { 5791 appId = UserHandle.getAppId( 5792 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5793 } catch (RemoteException e) { 5794 } 5795 } 5796 5797 if (doit) { 5798 if (name != null) { 5799 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5800 + " user=" + userId + ": " + reason); 5801 } else { 5802 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5803 } 5804 5805 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5806 for (int ip=pmap.size()-1; ip>=0; ip--) { 5807 SparseArray<Long> ba = pmap.valueAt(ip); 5808 for (i=ba.size()-1; i>=0; i--) { 5809 boolean remove = false; 5810 final int entUid = ba.keyAt(i); 5811 if (name != null) { 5812 if (userId == UserHandle.USER_ALL) { 5813 if (UserHandle.getAppId(entUid) == appId) { 5814 remove = true; 5815 } 5816 } else { 5817 if (entUid == UserHandle.getUid(userId, appId)) { 5818 remove = true; 5819 } 5820 } 5821 } else if (UserHandle.getUserId(entUid) == userId) { 5822 remove = true; 5823 } 5824 if (remove) { 5825 ba.removeAt(i); 5826 } 5827 } 5828 if (ba.size() == 0) { 5829 pmap.removeAt(ip); 5830 } 5831 } 5832 } 5833 5834 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5835 -100, callerWillRestart, true, doit, evenPersistent, 5836 name == null ? ("stop user " + userId) : ("stop " + name)); 5837 5838 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5839 if (!doit) { 5840 return true; 5841 } 5842 didSomething = true; 5843 } 5844 5845 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5846 if (!doit) { 5847 return true; 5848 } 5849 didSomething = true; 5850 } 5851 5852 if (name == null) { 5853 // Remove all sticky broadcasts from this user. 5854 mStickyBroadcasts.remove(userId); 5855 } 5856 5857 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5858 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5859 userId, providers)) { 5860 if (!doit) { 5861 return true; 5862 } 5863 didSomething = true; 5864 } 5865 N = providers.size(); 5866 for (i=0; i<N; i++) { 5867 removeDyingProviderLocked(null, providers.get(i), true); 5868 } 5869 5870 // Remove transient permissions granted from/to this package/user 5871 removeUriPermissionsForPackageLocked(name, userId, false); 5872 5873 if (name == null || uninstalling) { 5874 // Remove pending intents. For now we only do this when force 5875 // stopping users, because we have some problems when doing this 5876 // for packages -- app widgets are not currently cleaned up for 5877 // such packages, so they can be left with bad pending intents. 5878 if (mIntentSenderRecords.size() > 0) { 5879 Iterator<WeakReference<PendingIntentRecord>> it 5880 = mIntentSenderRecords.values().iterator(); 5881 while (it.hasNext()) { 5882 WeakReference<PendingIntentRecord> wpir = it.next(); 5883 if (wpir == null) { 5884 it.remove(); 5885 continue; 5886 } 5887 PendingIntentRecord pir = wpir.get(); 5888 if (pir == null) { 5889 it.remove(); 5890 continue; 5891 } 5892 if (name == null) { 5893 // Stopping user, remove all objects for the user. 5894 if (pir.key.userId != userId) { 5895 // Not the same user, skip it. 5896 continue; 5897 } 5898 } else { 5899 if (UserHandle.getAppId(pir.uid) != appId) { 5900 // Different app id, skip it. 5901 continue; 5902 } 5903 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5904 // Different user, skip it. 5905 continue; 5906 } 5907 if (!pir.key.packageName.equals(name)) { 5908 // Different package, skip it. 5909 continue; 5910 } 5911 } 5912 if (!doit) { 5913 return true; 5914 } 5915 didSomething = true; 5916 it.remove(); 5917 pir.canceled = true; 5918 if (pir.key.activity != null) { 5919 pir.key.activity.pendingResults.remove(pir.ref); 5920 } 5921 } 5922 } 5923 } 5924 5925 if (doit) { 5926 if (purgeCache && name != null) { 5927 AttributeCache ac = AttributeCache.instance(); 5928 if (ac != null) { 5929 ac.removePackage(name); 5930 } 5931 } 5932 if (mBooted) { 5933 mStackSupervisor.resumeTopActivitiesLocked(); 5934 mStackSupervisor.scheduleIdleLocked(); 5935 } 5936 } 5937 5938 return didSomething; 5939 } 5940 5941 private final boolean removeProcessLocked(ProcessRecord app, 5942 boolean callerWillRestart, boolean allowRestart, String reason) { 5943 final String name = app.processName; 5944 final int uid = app.uid; 5945 if (DEBUG_PROCESSES) Slog.d( 5946 TAG, "Force removing proc " + app.toShortString() + " (" + name 5947 + "/" + uid + ")"); 5948 5949 mProcessNames.remove(name, uid); 5950 mIsolatedProcesses.remove(app.uid); 5951 if (mHeavyWeightProcess == app) { 5952 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5953 mHeavyWeightProcess.userId, 0)); 5954 mHeavyWeightProcess = null; 5955 } 5956 boolean needRestart = false; 5957 if (app.pid > 0 && app.pid != MY_PID) { 5958 int pid = app.pid; 5959 synchronized (mPidsSelfLocked) { 5960 mPidsSelfLocked.remove(pid); 5961 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5962 } 5963 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5964 if (app.isolated) { 5965 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5966 } 5967 app.kill(reason, true); 5968 handleAppDiedLocked(app, true, allowRestart); 5969 removeLruProcessLocked(app); 5970 5971 if (app.persistent && !app.isolated) { 5972 if (!callerWillRestart) { 5973 addAppLocked(app.info, false, null /* ABI override */); 5974 } else { 5975 needRestart = true; 5976 } 5977 } 5978 } else { 5979 mRemovedProcesses.add(app); 5980 } 5981 5982 return needRestart; 5983 } 5984 5985 private final void processStartTimedOutLocked(ProcessRecord app) { 5986 final int pid = app.pid; 5987 boolean gone = false; 5988 synchronized (mPidsSelfLocked) { 5989 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5990 if (knownApp != null && knownApp.thread == null) { 5991 mPidsSelfLocked.remove(pid); 5992 gone = true; 5993 } 5994 } 5995 5996 if (gone) { 5997 Slog.w(TAG, "Process " + app + " failed to attach"); 5998 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5999 pid, app.uid, app.processName); 6000 mProcessNames.remove(app.processName, app.uid); 6001 mIsolatedProcesses.remove(app.uid); 6002 if (mHeavyWeightProcess == app) { 6003 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6004 mHeavyWeightProcess.userId, 0)); 6005 mHeavyWeightProcess = null; 6006 } 6007 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6008 if (app.isolated) { 6009 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6010 } 6011 // Take care of any launching providers waiting for this process. 6012 checkAppInLaunchingProvidersLocked(app, true); 6013 // Take care of any services that are waiting for the process. 6014 mServices.processStartTimedOutLocked(app); 6015 app.kill("start timeout", true); 6016 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6017 Slog.w(TAG, "Unattached app died before backup, skipping"); 6018 try { 6019 IBackupManager bm = IBackupManager.Stub.asInterface( 6020 ServiceManager.getService(Context.BACKUP_SERVICE)); 6021 bm.agentDisconnected(app.info.packageName); 6022 } catch (RemoteException e) { 6023 // Can't happen; the backup manager is local 6024 } 6025 } 6026 if (isPendingBroadcastProcessLocked(pid)) { 6027 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6028 skipPendingBroadcastLocked(pid); 6029 } 6030 } else { 6031 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6032 } 6033 } 6034 6035 private final boolean attachApplicationLocked(IApplicationThread thread, 6036 int pid) { 6037 6038 // Find the application record that is being attached... either via 6039 // the pid if we are running in multiple processes, or just pull the 6040 // next app record if we are emulating process with anonymous threads. 6041 ProcessRecord app; 6042 if (pid != MY_PID && pid >= 0) { 6043 synchronized (mPidsSelfLocked) { 6044 app = mPidsSelfLocked.get(pid); 6045 } 6046 } else { 6047 app = null; 6048 } 6049 6050 if (app == null) { 6051 Slog.w(TAG, "No pending application record for pid " + pid 6052 + " (IApplicationThread " + thread + "); dropping process"); 6053 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6054 if (pid > 0 && pid != MY_PID) { 6055 Process.killProcessQuiet(pid); 6056 //TODO: Process.killProcessGroup(app.info.uid, pid); 6057 } else { 6058 try { 6059 thread.scheduleExit(); 6060 } catch (Exception e) { 6061 // Ignore exceptions. 6062 } 6063 } 6064 return false; 6065 } 6066 6067 // If this application record is still attached to a previous 6068 // process, clean it up now. 6069 if (app.thread != null) { 6070 handleAppDiedLocked(app, true, true); 6071 } 6072 6073 // Tell the process all about itself. 6074 6075 if (localLOGV) Slog.v( 6076 TAG, "Binding process pid " + pid + " to record " + app); 6077 6078 final String processName = app.processName; 6079 try { 6080 AppDeathRecipient adr = new AppDeathRecipient( 6081 app, pid, thread); 6082 thread.asBinder().linkToDeath(adr, 0); 6083 app.deathRecipient = adr; 6084 } catch (RemoteException e) { 6085 app.resetPackageList(mProcessStats); 6086 startProcessLocked(app, "link fail", processName); 6087 return false; 6088 } 6089 6090 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6091 6092 app.makeActive(thread, mProcessStats); 6093 app.curAdj = app.setAdj = -100; 6094 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6095 app.forcingToForeground = null; 6096 updateProcessForegroundLocked(app, false, false); 6097 app.hasShownUi = false; 6098 app.debugging = false; 6099 app.cached = false; 6100 6101 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6102 6103 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6104 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6105 6106 if (!normalMode) { 6107 Slog.i(TAG, "Launching preboot mode app: " + app); 6108 } 6109 6110 if (localLOGV) Slog.v( 6111 TAG, "New app record " + app 6112 + " thread=" + thread.asBinder() + " pid=" + pid); 6113 try { 6114 int testMode = IApplicationThread.DEBUG_OFF; 6115 if (mDebugApp != null && mDebugApp.equals(processName)) { 6116 testMode = mWaitForDebugger 6117 ? IApplicationThread.DEBUG_WAIT 6118 : IApplicationThread.DEBUG_ON; 6119 app.debugging = true; 6120 if (mDebugTransient) { 6121 mDebugApp = mOrigDebugApp; 6122 mWaitForDebugger = mOrigWaitForDebugger; 6123 } 6124 } 6125 String profileFile = app.instrumentationProfileFile; 6126 ParcelFileDescriptor profileFd = null; 6127 int samplingInterval = 0; 6128 boolean profileAutoStop = false; 6129 if (mProfileApp != null && mProfileApp.equals(processName)) { 6130 mProfileProc = app; 6131 profileFile = mProfileFile; 6132 profileFd = mProfileFd; 6133 samplingInterval = mSamplingInterval; 6134 profileAutoStop = mAutoStopProfiler; 6135 } 6136 boolean enableOpenGlTrace = false; 6137 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6138 enableOpenGlTrace = true; 6139 mOpenGlTraceApp = null; 6140 } 6141 6142 // If the app is being launched for restore or full backup, set it up specially 6143 boolean isRestrictedBackupMode = false; 6144 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6145 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6146 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6147 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6148 } 6149 6150 ensurePackageDexOpt(app.instrumentationInfo != null 6151 ? app.instrumentationInfo.packageName 6152 : app.info.packageName); 6153 if (app.instrumentationClass != null) { 6154 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6155 } 6156 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6157 + processName + " with config " + mConfiguration); 6158 ApplicationInfo appInfo = app.instrumentationInfo != null 6159 ? app.instrumentationInfo : app.info; 6160 app.compat = compatibilityInfoForPackageLocked(appInfo); 6161 if (profileFd != null) { 6162 profileFd = profileFd.dup(); 6163 } 6164 ProfilerInfo profilerInfo = profileFile == null ? null 6165 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6166 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6167 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6168 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6169 isRestrictedBackupMode || !normalMode, app.persistent, 6170 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6171 mCoreSettingsObserver.getCoreSettingsLocked()); 6172 updateLruProcessLocked(app, false, null); 6173 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6174 } catch (Exception e) { 6175 // todo: Yikes! What should we do? For now we will try to 6176 // start another process, but that could easily get us in 6177 // an infinite loop of restarting processes... 6178 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6179 6180 app.resetPackageList(mProcessStats); 6181 app.unlinkDeathRecipient(); 6182 startProcessLocked(app, "bind fail", processName); 6183 return false; 6184 } 6185 6186 // Remove this record from the list of starting applications. 6187 mPersistentStartingProcesses.remove(app); 6188 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6189 "Attach application locked removing on hold: " + app); 6190 mProcessesOnHold.remove(app); 6191 6192 boolean badApp = false; 6193 boolean didSomething = false; 6194 6195 // See if the top visible activity is waiting to run in this process... 6196 if (normalMode) { 6197 try { 6198 if (mStackSupervisor.attachApplicationLocked(app)) { 6199 didSomething = true; 6200 } 6201 } catch (Exception e) { 6202 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6203 badApp = true; 6204 } 6205 } 6206 6207 // Find any services that should be running in this process... 6208 if (!badApp) { 6209 try { 6210 didSomething |= mServices.attachApplicationLocked(app, processName); 6211 } catch (Exception e) { 6212 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6213 badApp = true; 6214 } 6215 } 6216 6217 // Check if a next-broadcast receiver is in this process... 6218 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6219 try { 6220 didSomething |= sendPendingBroadcastsLocked(app); 6221 } catch (Exception e) { 6222 // If the app died trying to launch the receiver we declare it 'bad' 6223 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6224 badApp = true; 6225 } 6226 } 6227 6228 // Check whether the next backup agent is in this process... 6229 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6230 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6231 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6232 try { 6233 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6234 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6235 mBackupTarget.backupMode); 6236 } catch (Exception e) { 6237 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6238 badApp = true; 6239 } 6240 } 6241 6242 if (badApp) { 6243 app.kill("error during init", true); 6244 handleAppDiedLocked(app, false, true); 6245 return false; 6246 } 6247 6248 if (!didSomething) { 6249 updateOomAdjLocked(); 6250 } 6251 6252 return true; 6253 } 6254 6255 @Override 6256 public final void attachApplication(IApplicationThread thread) { 6257 synchronized (this) { 6258 int callingPid = Binder.getCallingPid(); 6259 final long origId = Binder.clearCallingIdentity(); 6260 attachApplicationLocked(thread, callingPid); 6261 Binder.restoreCallingIdentity(origId); 6262 } 6263 } 6264 6265 @Override 6266 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6267 final long origId = Binder.clearCallingIdentity(); 6268 synchronized (this) { 6269 ActivityStack stack = ActivityRecord.getStackLocked(token); 6270 if (stack != null) { 6271 ActivityRecord r = 6272 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6273 if (stopProfiling) { 6274 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6275 try { 6276 mProfileFd.close(); 6277 } catch (IOException e) { 6278 } 6279 clearProfilerLocked(); 6280 } 6281 } 6282 } 6283 } 6284 Binder.restoreCallingIdentity(origId); 6285 } 6286 6287 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6288 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6289 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6290 } 6291 6292 void enableScreenAfterBoot() { 6293 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6294 SystemClock.uptimeMillis()); 6295 mWindowManager.enableScreenAfterBoot(); 6296 6297 synchronized (this) { 6298 updateEventDispatchingLocked(); 6299 } 6300 } 6301 6302 @Override 6303 public void showBootMessage(final CharSequence msg, final boolean always) { 6304 enforceNotIsolatedCaller("showBootMessage"); 6305 mWindowManager.showBootMessage(msg, always); 6306 } 6307 6308 @Override 6309 public void keyguardWaitingForActivityDrawn() { 6310 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6311 final long token = Binder.clearCallingIdentity(); 6312 try { 6313 synchronized (this) { 6314 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6315 mWindowManager.keyguardWaitingForActivityDrawn(); 6316 if (mLockScreenShown) { 6317 mLockScreenShown = false; 6318 comeOutOfSleepIfNeededLocked(); 6319 } 6320 } 6321 } finally { 6322 Binder.restoreCallingIdentity(token); 6323 } 6324 } 6325 6326 final void finishBooting() { 6327 synchronized (this) { 6328 if (!mBootAnimationComplete) { 6329 mCallFinishBooting = true; 6330 return; 6331 } 6332 mCallFinishBooting = false; 6333 } 6334 6335 // Register receivers to handle package update events 6336 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6337 6338 // Let system services know. 6339 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6340 6341 synchronized (this) { 6342 // Ensure that any processes we had put on hold are now started 6343 // up. 6344 final int NP = mProcessesOnHold.size(); 6345 if (NP > 0) { 6346 ArrayList<ProcessRecord> procs = 6347 new ArrayList<ProcessRecord>(mProcessesOnHold); 6348 for (int ip=0; ip<NP; ip++) { 6349 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6350 + procs.get(ip)); 6351 startProcessLocked(procs.get(ip), "on-hold", null); 6352 } 6353 } 6354 6355 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6356 // Start looking for apps that are abusing wake locks. 6357 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6358 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6359 // Tell anyone interested that we are done booting! 6360 SystemProperties.set("sys.boot_completed", "1"); 6361 6362 // And trigger dev.bootcomplete if we are not showing encryption progress 6363 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6364 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6365 SystemProperties.set("dev.bootcomplete", "1"); 6366 } 6367 for (int i=0; i<mStartedUsers.size(); i++) { 6368 UserStartedState uss = mStartedUsers.valueAt(i); 6369 if (uss.mState == UserStartedState.STATE_BOOTING) { 6370 uss.mState = UserStartedState.STATE_RUNNING; 6371 final int userId = mStartedUsers.keyAt(i); 6372 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6373 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6374 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6375 broadcastIntentLocked(null, null, intent, null, 6376 new IIntentReceiver.Stub() { 6377 @Override 6378 public void performReceive(Intent intent, int resultCode, 6379 String data, Bundle extras, boolean ordered, 6380 boolean sticky, int sendingUser) { 6381 synchronized (ActivityManagerService.this) { 6382 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6383 true, false); 6384 } 6385 } 6386 }, 6387 0, null, null, 6388 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6389 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6390 userId); 6391 } 6392 } 6393 scheduleStartProfilesLocked(); 6394 } 6395 } 6396 } 6397 6398 @Override 6399 public void bootAnimationComplete() { 6400 final boolean callFinishBooting; 6401 synchronized (this) { 6402 callFinishBooting = mCallFinishBooting; 6403 mBootAnimationComplete = true; 6404 } 6405 if (callFinishBooting) { 6406 finishBooting(); 6407 } 6408 } 6409 6410 final void ensureBootCompleted() { 6411 boolean booting; 6412 boolean enableScreen; 6413 synchronized (this) { 6414 booting = mBooting; 6415 mBooting = false; 6416 enableScreen = !mBooted; 6417 mBooted = true; 6418 } 6419 6420 if (booting) { 6421 finishBooting(); 6422 } 6423 6424 if (enableScreen) { 6425 enableScreenAfterBoot(); 6426 } 6427 } 6428 6429 @Override 6430 public final void activityResumed(IBinder token) { 6431 final long origId = Binder.clearCallingIdentity(); 6432 synchronized(this) { 6433 ActivityStack stack = ActivityRecord.getStackLocked(token); 6434 if (stack != null) { 6435 ActivityRecord.activityResumedLocked(token); 6436 } 6437 } 6438 Binder.restoreCallingIdentity(origId); 6439 } 6440 6441 @Override 6442 public final void activityPaused(IBinder token) { 6443 final long origId = Binder.clearCallingIdentity(); 6444 synchronized(this) { 6445 ActivityStack stack = ActivityRecord.getStackLocked(token); 6446 if (stack != null) { 6447 stack.activityPausedLocked(token, false); 6448 } 6449 } 6450 Binder.restoreCallingIdentity(origId); 6451 } 6452 6453 @Override 6454 public final void activityStopped(IBinder token, Bundle icicle, 6455 PersistableBundle persistentState, CharSequence description) { 6456 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6457 6458 // Refuse possible leaked file descriptors 6459 if (icicle != null && icicle.hasFileDescriptors()) { 6460 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6461 } 6462 6463 final long origId = Binder.clearCallingIdentity(); 6464 6465 synchronized (this) { 6466 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6467 if (r != null) { 6468 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6469 } 6470 } 6471 6472 trimApplications(); 6473 6474 Binder.restoreCallingIdentity(origId); 6475 } 6476 6477 @Override 6478 public final void activityDestroyed(IBinder token) { 6479 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6480 synchronized (this) { 6481 ActivityStack stack = ActivityRecord.getStackLocked(token); 6482 if (stack != null) { 6483 stack.activityDestroyedLocked(token); 6484 } 6485 } 6486 } 6487 6488 @Override 6489 public final void backgroundResourcesReleased(IBinder token) { 6490 final long origId = Binder.clearCallingIdentity(); 6491 try { 6492 synchronized (this) { 6493 ActivityStack stack = ActivityRecord.getStackLocked(token); 6494 if (stack != null) { 6495 stack.backgroundResourcesReleased(token); 6496 } 6497 } 6498 } finally { 6499 Binder.restoreCallingIdentity(origId); 6500 } 6501 } 6502 6503 @Override 6504 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6505 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6506 } 6507 6508 @Override 6509 public final void notifyEnterAnimationComplete(IBinder token) { 6510 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6511 } 6512 6513 @Override 6514 public String getCallingPackage(IBinder token) { 6515 synchronized (this) { 6516 ActivityRecord r = getCallingRecordLocked(token); 6517 return r != null ? r.info.packageName : null; 6518 } 6519 } 6520 6521 @Override 6522 public ComponentName getCallingActivity(IBinder token) { 6523 synchronized (this) { 6524 ActivityRecord r = getCallingRecordLocked(token); 6525 return r != null ? r.intent.getComponent() : null; 6526 } 6527 } 6528 6529 private ActivityRecord getCallingRecordLocked(IBinder token) { 6530 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6531 if (r == null) { 6532 return null; 6533 } 6534 return r.resultTo; 6535 } 6536 6537 @Override 6538 public ComponentName getActivityClassForToken(IBinder token) { 6539 synchronized(this) { 6540 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6541 if (r == null) { 6542 return null; 6543 } 6544 return r.intent.getComponent(); 6545 } 6546 } 6547 6548 @Override 6549 public String getPackageForToken(IBinder token) { 6550 synchronized(this) { 6551 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6552 if (r == null) { 6553 return null; 6554 } 6555 return r.packageName; 6556 } 6557 } 6558 6559 @Override 6560 public IIntentSender getIntentSender(int type, 6561 String packageName, IBinder token, String resultWho, 6562 int requestCode, Intent[] intents, String[] resolvedTypes, 6563 int flags, Bundle options, int userId) { 6564 enforceNotIsolatedCaller("getIntentSender"); 6565 // Refuse possible leaked file descriptors 6566 if (intents != null) { 6567 if (intents.length < 1) { 6568 throw new IllegalArgumentException("Intents array length must be >= 1"); 6569 } 6570 for (int i=0; i<intents.length; i++) { 6571 Intent intent = intents[i]; 6572 if (intent != null) { 6573 if (intent.hasFileDescriptors()) { 6574 throw new IllegalArgumentException("File descriptors passed in Intent"); 6575 } 6576 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6577 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6578 throw new IllegalArgumentException( 6579 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6580 } 6581 intents[i] = new Intent(intent); 6582 } 6583 } 6584 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6585 throw new IllegalArgumentException( 6586 "Intent array length does not match resolvedTypes length"); 6587 } 6588 } 6589 if (options != null) { 6590 if (options.hasFileDescriptors()) { 6591 throw new IllegalArgumentException("File descriptors passed in options"); 6592 } 6593 } 6594 6595 synchronized(this) { 6596 int callingUid = Binder.getCallingUid(); 6597 int origUserId = userId; 6598 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6599 type == ActivityManager.INTENT_SENDER_BROADCAST, 6600 ALLOW_NON_FULL, "getIntentSender", null); 6601 if (origUserId == UserHandle.USER_CURRENT) { 6602 // We don't want to evaluate this until the pending intent is 6603 // actually executed. However, we do want to always do the 6604 // security checking for it above. 6605 userId = UserHandle.USER_CURRENT; 6606 } 6607 try { 6608 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6609 int uid = AppGlobals.getPackageManager() 6610 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6611 if (!UserHandle.isSameApp(callingUid, uid)) { 6612 String msg = "Permission Denial: getIntentSender() from pid=" 6613 + Binder.getCallingPid() 6614 + ", uid=" + Binder.getCallingUid() 6615 + ", (need uid=" + uid + ")" 6616 + " is not allowed to send as package " + packageName; 6617 Slog.w(TAG, msg); 6618 throw new SecurityException(msg); 6619 } 6620 } 6621 6622 return getIntentSenderLocked(type, packageName, callingUid, userId, 6623 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6624 6625 } catch (RemoteException e) { 6626 throw new SecurityException(e); 6627 } 6628 } 6629 } 6630 6631 IIntentSender getIntentSenderLocked(int type, String packageName, 6632 int callingUid, int userId, IBinder token, String resultWho, 6633 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6634 Bundle options) { 6635 if (DEBUG_MU) 6636 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6637 ActivityRecord activity = null; 6638 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6639 activity = ActivityRecord.isInStackLocked(token); 6640 if (activity == null) { 6641 return null; 6642 } 6643 if (activity.finishing) { 6644 return null; 6645 } 6646 } 6647 6648 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6649 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6650 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6651 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6652 |PendingIntent.FLAG_UPDATE_CURRENT); 6653 6654 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6655 type, packageName, activity, resultWho, 6656 requestCode, intents, resolvedTypes, flags, options, userId); 6657 WeakReference<PendingIntentRecord> ref; 6658 ref = mIntentSenderRecords.get(key); 6659 PendingIntentRecord rec = ref != null ? ref.get() : null; 6660 if (rec != null) { 6661 if (!cancelCurrent) { 6662 if (updateCurrent) { 6663 if (rec.key.requestIntent != null) { 6664 rec.key.requestIntent.replaceExtras(intents != null ? 6665 intents[intents.length - 1] : null); 6666 } 6667 if (intents != null) { 6668 intents[intents.length-1] = rec.key.requestIntent; 6669 rec.key.allIntents = intents; 6670 rec.key.allResolvedTypes = resolvedTypes; 6671 } else { 6672 rec.key.allIntents = null; 6673 rec.key.allResolvedTypes = null; 6674 } 6675 } 6676 return rec; 6677 } 6678 rec.canceled = true; 6679 mIntentSenderRecords.remove(key); 6680 } 6681 if (noCreate) { 6682 return rec; 6683 } 6684 rec = new PendingIntentRecord(this, key, callingUid); 6685 mIntentSenderRecords.put(key, rec.ref); 6686 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6687 if (activity.pendingResults == null) { 6688 activity.pendingResults 6689 = new HashSet<WeakReference<PendingIntentRecord>>(); 6690 } 6691 activity.pendingResults.add(rec.ref); 6692 } 6693 return rec; 6694 } 6695 6696 @Override 6697 public void cancelIntentSender(IIntentSender sender) { 6698 if (!(sender instanceof PendingIntentRecord)) { 6699 return; 6700 } 6701 synchronized(this) { 6702 PendingIntentRecord rec = (PendingIntentRecord)sender; 6703 try { 6704 int uid = AppGlobals.getPackageManager() 6705 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6706 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6707 String msg = "Permission Denial: cancelIntentSender() from pid=" 6708 + Binder.getCallingPid() 6709 + ", uid=" + Binder.getCallingUid() 6710 + " is not allowed to cancel packges " 6711 + rec.key.packageName; 6712 Slog.w(TAG, msg); 6713 throw new SecurityException(msg); 6714 } 6715 } catch (RemoteException e) { 6716 throw new SecurityException(e); 6717 } 6718 cancelIntentSenderLocked(rec, true); 6719 } 6720 } 6721 6722 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6723 rec.canceled = true; 6724 mIntentSenderRecords.remove(rec.key); 6725 if (cleanActivity && rec.key.activity != null) { 6726 rec.key.activity.pendingResults.remove(rec.ref); 6727 } 6728 } 6729 6730 @Override 6731 public String getPackageForIntentSender(IIntentSender pendingResult) { 6732 if (!(pendingResult instanceof PendingIntentRecord)) { 6733 return null; 6734 } 6735 try { 6736 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6737 return res.key.packageName; 6738 } catch (ClassCastException e) { 6739 } 6740 return null; 6741 } 6742 6743 @Override 6744 public int getUidForIntentSender(IIntentSender sender) { 6745 if (sender instanceof PendingIntentRecord) { 6746 try { 6747 PendingIntentRecord res = (PendingIntentRecord)sender; 6748 return res.uid; 6749 } catch (ClassCastException e) { 6750 } 6751 } 6752 return -1; 6753 } 6754 6755 @Override 6756 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6757 if (!(pendingResult instanceof PendingIntentRecord)) { 6758 return false; 6759 } 6760 try { 6761 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6762 if (res.key.allIntents == null) { 6763 return false; 6764 } 6765 for (int i=0; i<res.key.allIntents.length; i++) { 6766 Intent intent = res.key.allIntents[i]; 6767 if (intent.getPackage() != null && intent.getComponent() != null) { 6768 return false; 6769 } 6770 } 6771 return true; 6772 } catch (ClassCastException e) { 6773 } 6774 return false; 6775 } 6776 6777 @Override 6778 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6779 if (!(pendingResult instanceof PendingIntentRecord)) { 6780 return false; 6781 } 6782 try { 6783 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6784 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6785 return true; 6786 } 6787 return false; 6788 } catch (ClassCastException e) { 6789 } 6790 return false; 6791 } 6792 6793 @Override 6794 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6795 if (!(pendingResult instanceof PendingIntentRecord)) { 6796 return null; 6797 } 6798 try { 6799 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6800 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6801 } catch (ClassCastException e) { 6802 } 6803 return null; 6804 } 6805 6806 @Override 6807 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6808 if (!(pendingResult instanceof PendingIntentRecord)) { 6809 return null; 6810 } 6811 try { 6812 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6813 Intent intent = res.key.requestIntent; 6814 if (intent != null) { 6815 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6816 || res.lastTagPrefix.equals(prefix))) { 6817 return res.lastTag; 6818 } 6819 res.lastTagPrefix = prefix; 6820 StringBuilder sb = new StringBuilder(128); 6821 if (prefix != null) { 6822 sb.append(prefix); 6823 } 6824 if (intent.getAction() != null) { 6825 sb.append(intent.getAction()); 6826 } else if (intent.getComponent() != null) { 6827 intent.getComponent().appendShortString(sb); 6828 } else { 6829 sb.append("?"); 6830 } 6831 return res.lastTag = sb.toString(); 6832 } 6833 } catch (ClassCastException e) { 6834 } 6835 return null; 6836 } 6837 6838 @Override 6839 public void setProcessLimit(int max) { 6840 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6841 "setProcessLimit()"); 6842 synchronized (this) { 6843 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6844 mProcessLimitOverride = max; 6845 } 6846 trimApplications(); 6847 } 6848 6849 @Override 6850 public int getProcessLimit() { 6851 synchronized (this) { 6852 return mProcessLimitOverride; 6853 } 6854 } 6855 6856 void foregroundTokenDied(ForegroundToken token) { 6857 synchronized (ActivityManagerService.this) { 6858 synchronized (mPidsSelfLocked) { 6859 ForegroundToken cur 6860 = mForegroundProcesses.get(token.pid); 6861 if (cur != token) { 6862 return; 6863 } 6864 mForegroundProcesses.remove(token.pid); 6865 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6866 if (pr == null) { 6867 return; 6868 } 6869 pr.forcingToForeground = null; 6870 updateProcessForegroundLocked(pr, false, false); 6871 } 6872 updateOomAdjLocked(); 6873 } 6874 } 6875 6876 @Override 6877 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6878 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6879 "setProcessForeground()"); 6880 synchronized(this) { 6881 boolean changed = false; 6882 6883 synchronized (mPidsSelfLocked) { 6884 ProcessRecord pr = mPidsSelfLocked.get(pid); 6885 if (pr == null && isForeground) { 6886 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6887 return; 6888 } 6889 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6890 if (oldToken != null) { 6891 oldToken.token.unlinkToDeath(oldToken, 0); 6892 mForegroundProcesses.remove(pid); 6893 if (pr != null) { 6894 pr.forcingToForeground = null; 6895 } 6896 changed = true; 6897 } 6898 if (isForeground && token != null) { 6899 ForegroundToken newToken = new ForegroundToken() { 6900 @Override 6901 public void binderDied() { 6902 foregroundTokenDied(this); 6903 } 6904 }; 6905 newToken.pid = pid; 6906 newToken.token = token; 6907 try { 6908 token.linkToDeath(newToken, 0); 6909 mForegroundProcesses.put(pid, newToken); 6910 pr.forcingToForeground = token; 6911 changed = true; 6912 } catch (RemoteException e) { 6913 // If the process died while doing this, we will later 6914 // do the cleanup with the process death link. 6915 } 6916 } 6917 } 6918 6919 if (changed) { 6920 updateOomAdjLocked(); 6921 } 6922 } 6923 } 6924 6925 // ========================================================= 6926 // PERMISSIONS 6927 // ========================================================= 6928 6929 static class PermissionController extends IPermissionController.Stub { 6930 ActivityManagerService mActivityManagerService; 6931 PermissionController(ActivityManagerService activityManagerService) { 6932 mActivityManagerService = activityManagerService; 6933 } 6934 6935 @Override 6936 public boolean checkPermission(String permission, int pid, int uid) { 6937 return mActivityManagerService.checkPermission(permission, pid, 6938 uid) == PackageManager.PERMISSION_GRANTED; 6939 } 6940 } 6941 6942 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6943 @Override 6944 public int checkComponentPermission(String permission, int pid, int uid, 6945 int owningUid, boolean exported) { 6946 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6947 owningUid, exported); 6948 } 6949 6950 @Override 6951 public Object getAMSLock() { 6952 return ActivityManagerService.this; 6953 } 6954 } 6955 6956 /** 6957 * This can be called with or without the global lock held. 6958 */ 6959 int checkComponentPermission(String permission, int pid, int uid, 6960 int owningUid, boolean exported) { 6961 // We might be performing an operation on behalf of an indirect binder 6962 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6963 // client identity accordingly before proceeding. 6964 Identity tlsIdentity = sCallerIdentity.get(); 6965 if (tlsIdentity != null) { 6966 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6967 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6968 uid = tlsIdentity.uid; 6969 pid = tlsIdentity.pid; 6970 } 6971 6972 if (pid == MY_PID) { 6973 return PackageManager.PERMISSION_GRANTED; 6974 } 6975 6976 return ActivityManager.checkComponentPermission(permission, uid, 6977 owningUid, exported); 6978 } 6979 6980 /** 6981 * As the only public entry point for permissions checking, this method 6982 * can enforce the semantic that requesting a check on a null global 6983 * permission is automatically denied. (Internally a null permission 6984 * string is used when calling {@link #checkComponentPermission} in cases 6985 * when only uid-based security is needed.) 6986 * 6987 * This can be called with or without the global lock held. 6988 */ 6989 @Override 6990 public int checkPermission(String permission, int pid, int uid) { 6991 if (permission == null) { 6992 return PackageManager.PERMISSION_DENIED; 6993 } 6994 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6995 } 6996 6997 /** 6998 * Binder IPC calls go through the public entry point. 6999 * This can be called with or without the global lock held. 7000 */ 7001 int checkCallingPermission(String permission) { 7002 return checkPermission(permission, 7003 Binder.getCallingPid(), 7004 UserHandle.getAppId(Binder.getCallingUid())); 7005 } 7006 7007 /** 7008 * This can be called with or without the global lock held. 7009 */ 7010 void enforceCallingPermission(String permission, String func) { 7011 if (checkCallingPermission(permission) 7012 == PackageManager.PERMISSION_GRANTED) { 7013 return; 7014 } 7015 7016 String msg = "Permission Denial: " + func + " from pid=" 7017 + Binder.getCallingPid() 7018 + ", uid=" + Binder.getCallingUid() 7019 + " requires " + permission; 7020 Slog.w(TAG, msg); 7021 throw new SecurityException(msg); 7022 } 7023 7024 /** 7025 * Determine if UID is holding permissions required to access {@link Uri} in 7026 * the given {@link ProviderInfo}. Final permission checking is always done 7027 * in {@link ContentProvider}. 7028 */ 7029 private final boolean checkHoldingPermissionsLocked( 7030 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 7031 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7032 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 7033 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 7034 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 7035 != PERMISSION_GRANTED) { 7036 return false; 7037 } 7038 } 7039 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 7040 } 7041 7042 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 7043 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 7044 if (pi.applicationInfo.uid == uid) { 7045 return true; 7046 } else if (!pi.exported) { 7047 return false; 7048 } 7049 7050 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7051 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7052 try { 7053 // check if target holds top-level <provider> permissions 7054 if (!readMet && pi.readPermission != null && considerUidPermissions 7055 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7056 readMet = true; 7057 } 7058 if (!writeMet && pi.writePermission != null && considerUidPermissions 7059 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7060 writeMet = true; 7061 } 7062 7063 // track if unprotected read/write is allowed; any denied 7064 // <path-permission> below removes this ability 7065 boolean allowDefaultRead = pi.readPermission == null; 7066 boolean allowDefaultWrite = pi.writePermission == null; 7067 7068 // check if target holds any <path-permission> that match uri 7069 final PathPermission[] pps = pi.pathPermissions; 7070 if (pps != null) { 7071 final String path = grantUri.uri.getPath(); 7072 int i = pps.length; 7073 while (i > 0 && (!readMet || !writeMet)) { 7074 i--; 7075 PathPermission pp = pps[i]; 7076 if (pp.match(path)) { 7077 if (!readMet) { 7078 final String pprperm = pp.getReadPermission(); 7079 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7080 + pprperm + " for " + pp.getPath() 7081 + ": match=" + pp.match(path) 7082 + " check=" + pm.checkUidPermission(pprperm, uid)); 7083 if (pprperm != null) { 7084 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7085 == PERMISSION_GRANTED) { 7086 readMet = true; 7087 } else { 7088 allowDefaultRead = false; 7089 } 7090 } 7091 } 7092 if (!writeMet) { 7093 final String ppwperm = pp.getWritePermission(); 7094 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7095 + ppwperm + " for " + pp.getPath() 7096 + ": match=" + pp.match(path) 7097 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7098 if (ppwperm != null) { 7099 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7100 == PERMISSION_GRANTED) { 7101 writeMet = true; 7102 } else { 7103 allowDefaultWrite = false; 7104 } 7105 } 7106 } 7107 } 7108 } 7109 } 7110 7111 // grant unprotected <provider> read/write, if not blocked by 7112 // <path-permission> above 7113 if (allowDefaultRead) readMet = true; 7114 if (allowDefaultWrite) writeMet = true; 7115 7116 } catch (RemoteException e) { 7117 return false; 7118 } 7119 7120 return readMet && writeMet; 7121 } 7122 7123 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7124 ProviderInfo pi = null; 7125 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7126 if (cpr != null) { 7127 pi = cpr.info; 7128 } else { 7129 try { 7130 pi = AppGlobals.getPackageManager().resolveContentProvider( 7131 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7132 } catch (RemoteException ex) { 7133 } 7134 } 7135 return pi; 7136 } 7137 7138 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7139 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7140 if (targetUris != null) { 7141 return targetUris.get(grantUri); 7142 } 7143 return null; 7144 } 7145 7146 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7147 String targetPkg, int targetUid, GrantUri grantUri) { 7148 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7149 if (targetUris == null) { 7150 targetUris = Maps.newArrayMap(); 7151 mGrantedUriPermissions.put(targetUid, targetUris); 7152 } 7153 7154 UriPermission perm = targetUris.get(grantUri); 7155 if (perm == null) { 7156 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7157 targetUris.put(grantUri, perm); 7158 } 7159 7160 return perm; 7161 } 7162 7163 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7164 final int modeFlags) { 7165 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7166 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7167 : UriPermission.STRENGTH_OWNED; 7168 7169 // Root gets to do everything. 7170 if (uid == 0) { 7171 return true; 7172 } 7173 7174 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7175 if (perms == null) return false; 7176 7177 // First look for exact match 7178 final UriPermission exactPerm = perms.get(grantUri); 7179 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7180 return true; 7181 } 7182 7183 // No exact match, look for prefixes 7184 final int N = perms.size(); 7185 for (int i = 0; i < N; i++) { 7186 final UriPermission perm = perms.valueAt(i); 7187 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7188 && perm.getStrength(modeFlags) >= minStrength) { 7189 return true; 7190 } 7191 } 7192 7193 return false; 7194 } 7195 7196 /** 7197 * @param uri This uri must NOT contain an embedded userId. 7198 * @param userId The userId in which the uri is to be resolved. 7199 */ 7200 @Override 7201 public int checkUriPermission(Uri uri, int pid, int uid, 7202 final int modeFlags, int userId) { 7203 enforceNotIsolatedCaller("checkUriPermission"); 7204 7205 // Another redirected-binder-call permissions check as in 7206 // {@link checkComponentPermission}. 7207 Identity tlsIdentity = sCallerIdentity.get(); 7208 if (tlsIdentity != null) { 7209 uid = tlsIdentity.uid; 7210 pid = tlsIdentity.pid; 7211 } 7212 7213 // Our own process gets to do everything. 7214 if (pid == MY_PID) { 7215 return PackageManager.PERMISSION_GRANTED; 7216 } 7217 synchronized (this) { 7218 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7219 ? PackageManager.PERMISSION_GRANTED 7220 : PackageManager.PERMISSION_DENIED; 7221 } 7222 } 7223 7224 /** 7225 * Check if the targetPkg can be granted permission to access uri by 7226 * the callingUid using the given modeFlags. Throws a security exception 7227 * if callingUid is not allowed to do this. Returns the uid of the target 7228 * if the URI permission grant should be performed; returns -1 if it is not 7229 * needed (for example targetPkg already has permission to access the URI). 7230 * If you already know the uid of the target, you can supply it in 7231 * lastTargetUid else set that to -1. 7232 */ 7233 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7234 final int modeFlags, int lastTargetUid) { 7235 if (!Intent.isAccessUriMode(modeFlags)) { 7236 return -1; 7237 } 7238 7239 if (targetPkg != null) { 7240 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7241 "Checking grant " + targetPkg + " permission to " + grantUri); 7242 } 7243 7244 final IPackageManager pm = AppGlobals.getPackageManager(); 7245 7246 // If this is not a content: uri, we can't do anything with it. 7247 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7248 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7249 "Can't grant URI permission for non-content URI: " + grantUri); 7250 return -1; 7251 } 7252 7253 final String authority = grantUri.uri.getAuthority(); 7254 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7255 if (pi == null) { 7256 Slog.w(TAG, "No content provider found for permission check: " + 7257 grantUri.uri.toSafeString()); 7258 return -1; 7259 } 7260 7261 int targetUid = lastTargetUid; 7262 if (targetUid < 0 && targetPkg != null) { 7263 try { 7264 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7265 if (targetUid < 0) { 7266 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7267 "Can't grant URI permission no uid for: " + targetPkg); 7268 return -1; 7269 } 7270 } catch (RemoteException ex) { 7271 return -1; 7272 } 7273 } 7274 7275 if (targetUid >= 0) { 7276 // First... does the target actually need this permission? 7277 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7278 // No need to grant the target this permission. 7279 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7280 "Target " + targetPkg + " already has full permission to " + grantUri); 7281 return -1; 7282 } 7283 } else { 7284 // First... there is no target package, so can anyone access it? 7285 boolean allowed = pi.exported; 7286 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7287 if (pi.readPermission != null) { 7288 allowed = false; 7289 } 7290 } 7291 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7292 if (pi.writePermission != null) { 7293 allowed = false; 7294 } 7295 } 7296 if (allowed) { 7297 return -1; 7298 } 7299 } 7300 7301 /* There is a special cross user grant if: 7302 * - The target is on another user. 7303 * - Apps on the current user can access the uri without any uid permissions. 7304 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7305 * grant uri permissions. 7306 */ 7307 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7308 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7309 modeFlags, false /*without considering the uid permissions*/); 7310 7311 // Second... is the provider allowing granting of URI permissions? 7312 if (!specialCrossUserGrant) { 7313 if (!pi.grantUriPermissions) { 7314 throw new SecurityException("Provider " + pi.packageName 7315 + "/" + pi.name 7316 + " does not allow granting of Uri permissions (uri " 7317 + grantUri + ")"); 7318 } 7319 if (pi.uriPermissionPatterns != null) { 7320 final int N = pi.uriPermissionPatterns.length; 7321 boolean allowed = false; 7322 for (int i=0; i<N; i++) { 7323 if (pi.uriPermissionPatterns[i] != null 7324 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7325 allowed = true; 7326 break; 7327 } 7328 } 7329 if (!allowed) { 7330 throw new SecurityException("Provider " + pi.packageName 7331 + "/" + pi.name 7332 + " does not allow granting of permission to path of Uri " 7333 + grantUri); 7334 } 7335 } 7336 } 7337 7338 // Third... does the caller itself have permission to access 7339 // this uri? 7340 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7341 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7342 // Require they hold a strong enough Uri permission 7343 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7344 throw new SecurityException("Uid " + callingUid 7345 + " does not have permission to uri " + grantUri); 7346 } 7347 } 7348 } 7349 return targetUid; 7350 } 7351 7352 /** 7353 * @param uri This uri must NOT contain an embedded userId. 7354 * @param userId The userId in which the uri is to be resolved. 7355 */ 7356 @Override 7357 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7358 final int modeFlags, int userId) { 7359 enforceNotIsolatedCaller("checkGrantUriPermission"); 7360 synchronized(this) { 7361 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7362 new GrantUri(userId, uri, false), modeFlags, -1); 7363 } 7364 } 7365 7366 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7367 final int modeFlags, UriPermissionOwner owner) { 7368 if (!Intent.isAccessUriMode(modeFlags)) { 7369 return; 7370 } 7371 7372 // So here we are: the caller has the assumed permission 7373 // to the uri, and the target doesn't. Let's now give this to 7374 // the target. 7375 7376 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7377 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7378 7379 final String authority = grantUri.uri.getAuthority(); 7380 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7381 if (pi == null) { 7382 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7383 return; 7384 } 7385 7386 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7387 grantUri.prefix = true; 7388 } 7389 final UriPermission perm = findOrCreateUriPermissionLocked( 7390 pi.packageName, targetPkg, targetUid, grantUri); 7391 perm.grantModes(modeFlags, owner); 7392 } 7393 7394 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7395 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7396 if (targetPkg == null) { 7397 throw new NullPointerException("targetPkg"); 7398 } 7399 int targetUid; 7400 final IPackageManager pm = AppGlobals.getPackageManager(); 7401 try { 7402 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7403 } catch (RemoteException ex) { 7404 return; 7405 } 7406 7407 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7408 targetUid); 7409 if (targetUid < 0) { 7410 return; 7411 } 7412 7413 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7414 owner); 7415 } 7416 7417 static class NeededUriGrants extends ArrayList<GrantUri> { 7418 final String targetPkg; 7419 final int targetUid; 7420 final int flags; 7421 7422 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7423 this.targetPkg = targetPkg; 7424 this.targetUid = targetUid; 7425 this.flags = flags; 7426 } 7427 } 7428 7429 /** 7430 * Like checkGrantUriPermissionLocked, but takes an Intent. 7431 */ 7432 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7433 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7434 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7435 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7436 + " clip=" + (intent != null ? intent.getClipData() : null) 7437 + " from " + intent + "; flags=0x" 7438 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7439 7440 if (targetPkg == null) { 7441 throw new NullPointerException("targetPkg"); 7442 } 7443 7444 if (intent == null) { 7445 return null; 7446 } 7447 Uri data = intent.getData(); 7448 ClipData clip = intent.getClipData(); 7449 if (data == null && clip == null) { 7450 return null; 7451 } 7452 // Default userId for uris in the intent (if they don't specify it themselves) 7453 int contentUserHint = intent.getContentUserHint(); 7454 if (contentUserHint == UserHandle.USER_CURRENT) { 7455 contentUserHint = UserHandle.getUserId(callingUid); 7456 } 7457 final IPackageManager pm = AppGlobals.getPackageManager(); 7458 int targetUid; 7459 if (needed != null) { 7460 targetUid = needed.targetUid; 7461 } else { 7462 try { 7463 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7464 } catch (RemoteException ex) { 7465 return null; 7466 } 7467 if (targetUid < 0) { 7468 if (DEBUG_URI_PERMISSION) { 7469 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7470 + " on user " + targetUserId); 7471 } 7472 return null; 7473 } 7474 } 7475 if (data != null) { 7476 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7477 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7478 targetUid); 7479 if (targetUid > 0) { 7480 if (needed == null) { 7481 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7482 } 7483 needed.add(grantUri); 7484 } 7485 } 7486 if (clip != null) { 7487 for (int i=0; i<clip.getItemCount(); i++) { 7488 Uri uri = clip.getItemAt(i).getUri(); 7489 if (uri != null) { 7490 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7491 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7492 targetUid); 7493 if (targetUid > 0) { 7494 if (needed == null) { 7495 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7496 } 7497 needed.add(grantUri); 7498 } 7499 } else { 7500 Intent clipIntent = clip.getItemAt(i).getIntent(); 7501 if (clipIntent != null) { 7502 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7503 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7504 if (newNeeded != null) { 7505 needed = newNeeded; 7506 } 7507 } 7508 } 7509 } 7510 } 7511 7512 return needed; 7513 } 7514 7515 /** 7516 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7517 */ 7518 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7519 UriPermissionOwner owner) { 7520 if (needed != null) { 7521 for (int i=0; i<needed.size(); i++) { 7522 GrantUri grantUri = needed.get(i); 7523 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7524 grantUri, needed.flags, owner); 7525 } 7526 } 7527 } 7528 7529 void grantUriPermissionFromIntentLocked(int callingUid, 7530 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7531 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7532 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7533 if (needed == null) { 7534 return; 7535 } 7536 7537 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7538 } 7539 7540 /** 7541 * @param uri This uri must NOT contain an embedded userId. 7542 * @param userId The userId in which the uri is to be resolved. 7543 */ 7544 @Override 7545 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7546 final int modeFlags, int userId) { 7547 enforceNotIsolatedCaller("grantUriPermission"); 7548 GrantUri grantUri = new GrantUri(userId, uri, false); 7549 synchronized(this) { 7550 final ProcessRecord r = getRecordForAppLocked(caller); 7551 if (r == null) { 7552 throw new SecurityException("Unable to find app for caller " 7553 + caller 7554 + " when granting permission to uri " + grantUri); 7555 } 7556 if (targetPkg == null) { 7557 throw new IllegalArgumentException("null target"); 7558 } 7559 if (grantUri == null) { 7560 throw new IllegalArgumentException("null uri"); 7561 } 7562 7563 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7564 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7565 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7566 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7567 7568 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7569 UserHandle.getUserId(r.uid)); 7570 } 7571 } 7572 7573 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7574 if (perm.modeFlags == 0) { 7575 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7576 perm.targetUid); 7577 if (perms != null) { 7578 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7579 "Removing " + perm.targetUid + " permission to " + perm.uri); 7580 7581 perms.remove(perm.uri); 7582 if (perms.isEmpty()) { 7583 mGrantedUriPermissions.remove(perm.targetUid); 7584 } 7585 } 7586 } 7587 } 7588 7589 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7590 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7591 7592 final IPackageManager pm = AppGlobals.getPackageManager(); 7593 final String authority = grantUri.uri.getAuthority(); 7594 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7595 if (pi == null) { 7596 Slog.w(TAG, "No content provider found for permission revoke: " 7597 + grantUri.toSafeString()); 7598 return; 7599 } 7600 7601 // Does the caller have this permission on the URI? 7602 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7603 // If they don't have direct access to the URI, then revoke any 7604 // ownerless URI permissions that have been granted to them. 7605 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7606 if (perms != null) { 7607 boolean persistChanged = false; 7608 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7609 final UriPermission perm = it.next(); 7610 if (perm.uri.sourceUserId == grantUri.sourceUserId 7611 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7612 if (DEBUG_URI_PERMISSION) 7613 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7614 " permission to " + perm.uri); 7615 persistChanged |= perm.revokeModes( 7616 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7617 if (perm.modeFlags == 0) { 7618 it.remove(); 7619 } 7620 } 7621 } 7622 if (perms.isEmpty()) { 7623 mGrantedUriPermissions.remove(callingUid); 7624 } 7625 if (persistChanged) { 7626 schedulePersistUriGrants(); 7627 } 7628 } 7629 return; 7630 } 7631 7632 boolean persistChanged = false; 7633 7634 // Go through all of the permissions and remove any that match. 7635 int N = mGrantedUriPermissions.size(); 7636 for (int i = 0; i < N; i++) { 7637 final int targetUid = mGrantedUriPermissions.keyAt(i); 7638 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7639 7640 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7641 final UriPermission perm = it.next(); 7642 if (perm.uri.sourceUserId == grantUri.sourceUserId 7643 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7644 if (DEBUG_URI_PERMISSION) 7645 Slog.v(TAG, 7646 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7647 persistChanged |= perm.revokeModes( 7648 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7649 if (perm.modeFlags == 0) { 7650 it.remove(); 7651 } 7652 } 7653 } 7654 7655 if (perms.isEmpty()) { 7656 mGrantedUriPermissions.remove(targetUid); 7657 N--; 7658 i--; 7659 } 7660 } 7661 7662 if (persistChanged) { 7663 schedulePersistUriGrants(); 7664 } 7665 } 7666 7667 /** 7668 * @param uri This uri must NOT contain an embedded userId. 7669 * @param userId The userId in which the uri is to be resolved. 7670 */ 7671 @Override 7672 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7673 int userId) { 7674 enforceNotIsolatedCaller("revokeUriPermission"); 7675 synchronized(this) { 7676 final ProcessRecord r = getRecordForAppLocked(caller); 7677 if (r == null) { 7678 throw new SecurityException("Unable to find app for caller " 7679 + caller 7680 + " when revoking permission to uri " + uri); 7681 } 7682 if (uri == null) { 7683 Slog.w(TAG, "revokeUriPermission: null uri"); 7684 return; 7685 } 7686 7687 if (!Intent.isAccessUriMode(modeFlags)) { 7688 return; 7689 } 7690 7691 final IPackageManager pm = AppGlobals.getPackageManager(); 7692 final String authority = uri.getAuthority(); 7693 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7694 if (pi == null) { 7695 Slog.w(TAG, "No content provider found for permission revoke: " 7696 + uri.toSafeString()); 7697 return; 7698 } 7699 7700 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7701 } 7702 } 7703 7704 /** 7705 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7706 * given package. 7707 * 7708 * @param packageName Package name to match, or {@code null} to apply to all 7709 * packages. 7710 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7711 * to all users. 7712 * @param persistable If persistable grants should be removed. 7713 */ 7714 private void removeUriPermissionsForPackageLocked( 7715 String packageName, int userHandle, boolean persistable) { 7716 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7717 throw new IllegalArgumentException("Must narrow by either package or user"); 7718 } 7719 7720 boolean persistChanged = false; 7721 7722 int N = mGrantedUriPermissions.size(); 7723 for (int i = 0; i < N; i++) { 7724 final int targetUid = mGrantedUriPermissions.keyAt(i); 7725 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7726 7727 // Only inspect grants matching user 7728 if (userHandle == UserHandle.USER_ALL 7729 || userHandle == UserHandle.getUserId(targetUid)) { 7730 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7731 final UriPermission perm = it.next(); 7732 7733 // Only inspect grants matching package 7734 if (packageName == null || perm.sourcePkg.equals(packageName) 7735 || perm.targetPkg.equals(packageName)) { 7736 persistChanged |= perm.revokeModes(persistable 7737 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7738 7739 // Only remove when no modes remain; any persisted grants 7740 // will keep this alive. 7741 if (perm.modeFlags == 0) { 7742 it.remove(); 7743 } 7744 } 7745 } 7746 7747 if (perms.isEmpty()) { 7748 mGrantedUriPermissions.remove(targetUid); 7749 N--; 7750 i--; 7751 } 7752 } 7753 } 7754 7755 if (persistChanged) { 7756 schedulePersistUriGrants(); 7757 } 7758 } 7759 7760 @Override 7761 public IBinder newUriPermissionOwner(String name) { 7762 enforceNotIsolatedCaller("newUriPermissionOwner"); 7763 synchronized(this) { 7764 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7765 return owner.getExternalTokenLocked(); 7766 } 7767 } 7768 7769 /** 7770 * @param uri This uri must NOT contain an embedded userId. 7771 * @param sourceUserId The userId in which the uri is to be resolved. 7772 * @param targetUserId The userId of the app that receives the grant. 7773 */ 7774 @Override 7775 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7776 final int modeFlags, int sourceUserId, int targetUserId) { 7777 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7778 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7779 synchronized(this) { 7780 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7781 if (owner == null) { 7782 throw new IllegalArgumentException("Unknown owner: " + token); 7783 } 7784 if (fromUid != Binder.getCallingUid()) { 7785 if (Binder.getCallingUid() != Process.myUid()) { 7786 // Only system code can grant URI permissions on behalf 7787 // of other users. 7788 throw new SecurityException("nice try"); 7789 } 7790 } 7791 if (targetPkg == null) { 7792 throw new IllegalArgumentException("null target"); 7793 } 7794 if (uri == null) { 7795 throw new IllegalArgumentException("null uri"); 7796 } 7797 7798 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7799 modeFlags, owner, targetUserId); 7800 } 7801 } 7802 7803 /** 7804 * @param uri This uri must NOT contain an embedded userId. 7805 * @param userId The userId in which the uri is to be resolved. 7806 */ 7807 @Override 7808 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7809 synchronized(this) { 7810 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7811 if (owner == null) { 7812 throw new IllegalArgumentException("Unknown owner: " + token); 7813 } 7814 7815 if (uri == null) { 7816 owner.removeUriPermissionsLocked(mode); 7817 } else { 7818 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7819 } 7820 } 7821 } 7822 7823 private void schedulePersistUriGrants() { 7824 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7825 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7826 10 * DateUtils.SECOND_IN_MILLIS); 7827 } 7828 } 7829 7830 private void writeGrantedUriPermissions() { 7831 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7832 7833 // Snapshot permissions so we can persist without lock 7834 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7835 synchronized (this) { 7836 final int size = mGrantedUriPermissions.size(); 7837 for (int i = 0; i < size; i++) { 7838 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7839 for (UriPermission perm : perms.values()) { 7840 if (perm.persistedModeFlags != 0) { 7841 persist.add(perm.snapshot()); 7842 } 7843 } 7844 } 7845 } 7846 7847 FileOutputStream fos = null; 7848 try { 7849 fos = mGrantFile.startWrite(); 7850 7851 XmlSerializer out = new FastXmlSerializer(); 7852 out.setOutput(fos, "utf-8"); 7853 out.startDocument(null, true); 7854 out.startTag(null, TAG_URI_GRANTS); 7855 for (UriPermission.Snapshot perm : persist) { 7856 out.startTag(null, TAG_URI_GRANT); 7857 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7858 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7859 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7860 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7861 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7862 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7863 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7864 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7865 out.endTag(null, TAG_URI_GRANT); 7866 } 7867 out.endTag(null, TAG_URI_GRANTS); 7868 out.endDocument(); 7869 7870 mGrantFile.finishWrite(fos); 7871 } catch (IOException e) { 7872 if (fos != null) { 7873 mGrantFile.failWrite(fos); 7874 } 7875 } 7876 } 7877 7878 private void readGrantedUriPermissionsLocked() { 7879 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7880 7881 final long now = System.currentTimeMillis(); 7882 7883 FileInputStream fis = null; 7884 try { 7885 fis = mGrantFile.openRead(); 7886 final XmlPullParser in = Xml.newPullParser(); 7887 in.setInput(fis, null); 7888 7889 int type; 7890 while ((type = in.next()) != END_DOCUMENT) { 7891 final String tag = in.getName(); 7892 if (type == START_TAG) { 7893 if (TAG_URI_GRANT.equals(tag)) { 7894 final int sourceUserId; 7895 final int targetUserId; 7896 final int userHandle = readIntAttribute(in, 7897 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7898 if (userHandle != UserHandle.USER_NULL) { 7899 // For backwards compatibility. 7900 sourceUserId = userHandle; 7901 targetUserId = userHandle; 7902 } else { 7903 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7904 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7905 } 7906 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7907 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7908 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7909 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7910 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7911 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7912 7913 // Sanity check that provider still belongs to source package 7914 final ProviderInfo pi = getProviderInfoLocked( 7915 uri.getAuthority(), sourceUserId); 7916 if (pi != null && sourcePkg.equals(pi.packageName)) { 7917 int targetUid = -1; 7918 try { 7919 targetUid = AppGlobals.getPackageManager() 7920 .getPackageUid(targetPkg, targetUserId); 7921 } catch (RemoteException e) { 7922 } 7923 if (targetUid != -1) { 7924 final UriPermission perm = findOrCreateUriPermissionLocked( 7925 sourcePkg, targetPkg, targetUid, 7926 new GrantUri(sourceUserId, uri, prefix)); 7927 perm.initPersistedModes(modeFlags, createdTime); 7928 } 7929 } else { 7930 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7931 + " but instead found " + pi); 7932 } 7933 } 7934 } 7935 } 7936 } catch (FileNotFoundException e) { 7937 // Missing grants is okay 7938 } catch (IOException e) { 7939 Slog.wtf(TAG, "Failed reading Uri grants", e); 7940 } catch (XmlPullParserException e) { 7941 Slog.wtf(TAG, "Failed reading Uri grants", e); 7942 } finally { 7943 IoUtils.closeQuietly(fis); 7944 } 7945 } 7946 7947 /** 7948 * @param uri This uri must NOT contain an embedded userId. 7949 * @param userId The userId in which the uri is to be resolved. 7950 */ 7951 @Override 7952 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7953 enforceNotIsolatedCaller("takePersistableUriPermission"); 7954 7955 Preconditions.checkFlagsArgument(modeFlags, 7956 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7957 7958 synchronized (this) { 7959 final int callingUid = Binder.getCallingUid(); 7960 boolean persistChanged = false; 7961 GrantUri grantUri = new GrantUri(userId, uri, false); 7962 7963 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7964 new GrantUri(userId, uri, false)); 7965 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7966 new GrantUri(userId, uri, true)); 7967 7968 final boolean exactValid = (exactPerm != null) 7969 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7970 final boolean prefixValid = (prefixPerm != null) 7971 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7972 7973 if (!(exactValid || prefixValid)) { 7974 throw new SecurityException("No persistable permission grants found for UID " 7975 + callingUid + " and Uri " + grantUri.toSafeString()); 7976 } 7977 7978 if (exactValid) { 7979 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7980 } 7981 if (prefixValid) { 7982 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7983 } 7984 7985 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7986 7987 if (persistChanged) { 7988 schedulePersistUriGrants(); 7989 } 7990 } 7991 } 7992 7993 /** 7994 * @param uri This uri must NOT contain an embedded userId. 7995 * @param userId The userId in which the uri is to be resolved. 7996 */ 7997 @Override 7998 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7999 enforceNotIsolatedCaller("releasePersistableUriPermission"); 8000 8001 Preconditions.checkFlagsArgument(modeFlags, 8002 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 8003 8004 synchronized (this) { 8005 final int callingUid = Binder.getCallingUid(); 8006 boolean persistChanged = false; 8007 8008 UriPermission exactPerm = findUriPermissionLocked(callingUid, 8009 new GrantUri(userId, uri, false)); 8010 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 8011 new GrantUri(userId, uri, true)); 8012 if (exactPerm == null && prefixPerm == null) { 8013 throw new SecurityException("No permission grants found for UID " + callingUid 8014 + " and Uri " + uri.toSafeString()); 8015 } 8016 8017 if (exactPerm != null) { 8018 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 8019 removeUriPermissionIfNeededLocked(exactPerm); 8020 } 8021 if (prefixPerm != null) { 8022 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 8023 removeUriPermissionIfNeededLocked(prefixPerm); 8024 } 8025 8026 if (persistChanged) { 8027 schedulePersistUriGrants(); 8028 } 8029 } 8030 } 8031 8032 /** 8033 * Prune any older {@link UriPermission} for the given UID until outstanding 8034 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 8035 * 8036 * @return if any mutations occured that require persisting. 8037 */ 8038 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 8039 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8040 if (perms == null) return false; 8041 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 8042 8043 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 8044 for (UriPermission perm : perms.values()) { 8045 if (perm.persistedModeFlags != 0) { 8046 persisted.add(perm); 8047 } 8048 } 8049 8050 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8051 if (trimCount <= 0) return false; 8052 8053 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8054 for (int i = 0; i < trimCount; i++) { 8055 final UriPermission perm = persisted.get(i); 8056 8057 if (DEBUG_URI_PERMISSION) { 8058 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8059 } 8060 8061 perm.releasePersistableModes(~0); 8062 removeUriPermissionIfNeededLocked(perm); 8063 } 8064 8065 return true; 8066 } 8067 8068 @Override 8069 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8070 String packageName, boolean incoming) { 8071 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8072 Preconditions.checkNotNull(packageName, "packageName"); 8073 8074 final int callingUid = Binder.getCallingUid(); 8075 final IPackageManager pm = AppGlobals.getPackageManager(); 8076 try { 8077 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8078 if (packageUid != callingUid) { 8079 throw new SecurityException( 8080 "Package " + packageName + " does not belong to calling UID " + callingUid); 8081 } 8082 } catch (RemoteException e) { 8083 throw new SecurityException("Failed to verify package name ownership"); 8084 } 8085 8086 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8087 synchronized (this) { 8088 if (incoming) { 8089 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8090 callingUid); 8091 if (perms == null) { 8092 Slog.w(TAG, "No permission grants found for " + packageName); 8093 } else { 8094 for (UriPermission perm : perms.values()) { 8095 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8096 result.add(perm.buildPersistedPublicApiObject()); 8097 } 8098 } 8099 } 8100 } else { 8101 final int size = mGrantedUriPermissions.size(); 8102 for (int i = 0; i < size; i++) { 8103 final ArrayMap<GrantUri, UriPermission> perms = 8104 mGrantedUriPermissions.valueAt(i); 8105 for (UriPermission perm : perms.values()) { 8106 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8107 result.add(perm.buildPersistedPublicApiObject()); 8108 } 8109 } 8110 } 8111 } 8112 } 8113 return new ParceledListSlice<android.content.UriPermission>(result); 8114 } 8115 8116 @Override 8117 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8118 synchronized (this) { 8119 ProcessRecord app = 8120 who != null ? getRecordForAppLocked(who) : null; 8121 if (app == null) return; 8122 8123 Message msg = Message.obtain(); 8124 msg.what = WAIT_FOR_DEBUGGER_MSG; 8125 msg.obj = app; 8126 msg.arg1 = waiting ? 1 : 0; 8127 mHandler.sendMessage(msg); 8128 } 8129 } 8130 8131 @Override 8132 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8133 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8134 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8135 outInfo.availMem = Process.getFreeMemory(); 8136 outInfo.totalMem = Process.getTotalMemory(); 8137 outInfo.threshold = homeAppMem; 8138 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8139 outInfo.hiddenAppThreshold = cachedAppMem; 8140 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8141 ProcessList.SERVICE_ADJ); 8142 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8143 ProcessList.VISIBLE_APP_ADJ); 8144 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8145 ProcessList.FOREGROUND_APP_ADJ); 8146 } 8147 8148 // ========================================================= 8149 // TASK MANAGEMENT 8150 // ========================================================= 8151 8152 @Override 8153 public List<IAppTask> getAppTasks(String callingPackage) { 8154 int callingUid = Binder.getCallingUid(); 8155 long ident = Binder.clearCallingIdentity(); 8156 8157 synchronized(this) { 8158 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8159 try { 8160 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8161 8162 final int N = mRecentTasks.size(); 8163 for (int i = 0; i < N; i++) { 8164 TaskRecord tr = mRecentTasks.get(i); 8165 // Skip tasks that do not match the caller. We don't need to verify 8166 // callingPackage, because we are also limiting to callingUid and know 8167 // that will limit to the correct security sandbox. 8168 if (tr.effectiveUid != callingUid) { 8169 continue; 8170 } 8171 Intent intent = tr.getBaseIntent(); 8172 if (intent == null || 8173 !callingPackage.equals(intent.getComponent().getPackageName())) { 8174 continue; 8175 } 8176 ActivityManager.RecentTaskInfo taskInfo = 8177 createRecentTaskInfoFromTaskRecord(tr); 8178 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8179 list.add(taskImpl); 8180 } 8181 } finally { 8182 Binder.restoreCallingIdentity(ident); 8183 } 8184 return list; 8185 } 8186 } 8187 8188 @Override 8189 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8190 final int callingUid = Binder.getCallingUid(); 8191 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8192 8193 synchronized(this) { 8194 if (localLOGV) Slog.v( 8195 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8196 8197 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8198 callingUid); 8199 8200 // TODO: Improve with MRU list from all ActivityStacks. 8201 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8202 } 8203 8204 return list; 8205 } 8206 8207 TaskRecord getMostRecentTask() { 8208 return mRecentTasks.get(0); 8209 } 8210 8211 /** 8212 * Creates a new RecentTaskInfo from a TaskRecord. 8213 */ 8214 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8215 // Update the task description to reflect any changes in the task stack 8216 tr.updateTaskDescription(); 8217 8218 // Compose the recent task info 8219 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8220 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8221 rti.persistentId = tr.taskId; 8222 rti.baseIntent = new Intent(tr.getBaseIntent()); 8223 rti.origActivity = tr.origActivity; 8224 rti.description = tr.lastDescription; 8225 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8226 rti.userId = tr.userId; 8227 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8228 rti.firstActiveTime = tr.firstActiveTime; 8229 rti.lastActiveTime = tr.lastActiveTime; 8230 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8231 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8232 return rti; 8233 } 8234 8235 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8236 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8237 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8238 if (!allowed) { 8239 if (checkPermission(android.Manifest.permission.GET_TASKS, 8240 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8241 // Temporary compatibility: some existing apps on the system image may 8242 // still be requesting the old permission and not switched to the new 8243 // one; if so, we'll still allow them full access. This means we need 8244 // to see if they are holding the old permission and are a system app. 8245 try { 8246 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8247 allowed = true; 8248 Slog.w(TAG, caller + ": caller " + callingUid 8249 + " is using old GET_TASKS but privileged; allowing"); 8250 } 8251 } catch (RemoteException e) { 8252 } 8253 } 8254 } 8255 if (!allowed) { 8256 Slog.w(TAG, caller + ": caller " + callingUid 8257 + " does not hold REAL_GET_TASKS; limiting output"); 8258 } 8259 return allowed; 8260 } 8261 8262 @Override 8263 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8264 final int callingUid = Binder.getCallingUid(); 8265 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8266 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8267 8268 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8269 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8270 synchronized (this) { 8271 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8272 callingUid); 8273 final boolean detailed = checkCallingPermission( 8274 android.Manifest.permission.GET_DETAILED_TASKS) 8275 == PackageManager.PERMISSION_GRANTED; 8276 8277 final int N = mRecentTasks.size(); 8278 ArrayList<ActivityManager.RecentTaskInfo> res 8279 = new ArrayList<ActivityManager.RecentTaskInfo>( 8280 maxNum < N ? maxNum : N); 8281 8282 final Set<Integer> includedUsers; 8283 if (includeProfiles) { 8284 includedUsers = getProfileIdsLocked(userId); 8285 } else { 8286 includedUsers = new HashSet<Integer>(); 8287 } 8288 includedUsers.add(Integer.valueOf(userId)); 8289 8290 for (int i=0; i<N && maxNum > 0; i++) { 8291 TaskRecord tr = mRecentTasks.get(i); 8292 // Only add calling user or related users recent tasks 8293 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8294 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8295 continue; 8296 } 8297 8298 // Return the entry if desired by the caller. We always return 8299 // the first entry, because callers always expect this to be the 8300 // foreground app. We may filter others if the caller has 8301 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8302 // we should exclude the entry. 8303 8304 if (i == 0 8305 || withExcluded 8306 || (tr.intent == null) 8307 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8308 == 0)) { 8309 if (!allowed) { 8310 // If the caller doesn't have the GET_TASKS permission, then only 8311 // allow them to see a small subset of tasks -- their own and home. 8312 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8313 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8314 continue; 8315 } 8316 } 8317 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8318 if (tr.stack != null && tr.stack.isHomeStack()) { 8319 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8320 continue; 8321 } 8322 } 8323 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8324 // Don't include auto remove tasks that are finished or finishing. 8325 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8326 + tr); 8327 continue; 8328 } 8329 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8330 && !tr.isAvailable) { 8331 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8332 continue; 8333 } 8334 8335 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8336 if (!detailed) { 8337 rti.baseIntent.replaceExtras((Bundle)null); 8338 } 8339 8340 res.add(rti); 8341 maxNum--; 8342 } 8343 } 8344 return res; 8345 } 8346 } 8347 8348 private TaskRecord recentTaskForIdLocked(int id) { 8349 final int N = mRecentTasks.size(); 8350 for (int i=0; i<N; i++) { 8351 TaskRecord tr = mRecentTasks.get(i); 8352 if (tr.taskId == id) { 8353 return tr; 8354 } 8355 } 8356 return null; 8357 } 8358 8359 @Override 8360 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8361 synchronized (this) { 8362 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8363 "getTaskThumbnail()"); 8364 TaskRecord tr = recentTaskForIdLocked(id); 8365 if (tr != null) { 8366 return tr.getTaskThumbnailLocked(); 8367 } 8368 } 8369 return null; 8370 } 8371 8372 @Override 8373 public int addAppTask(IBinder activityToken, Intent intent, 8374 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8375 final int callingUid = Binder.getCallingUid(); 8376 final long callingIdent = Binder.clearCallingIdentity(); 8377 8378 try { 8379 synchronized (this) { 8380 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8381 if (r == null) { 8382 throw new IllegalArgumentException("Activity does not exist; token=" 8383 + activityToken); 8384 } 8385 ComponentName comp = intent.getComponent(); 8386 if (comp == null) { 8387 throw new IllegalArgumentException("Intent " + intent 8388 + " must specify explicit component"); 8389 } 8390 if (thumbnail.getWidth() != mThumbnailWidth 8391 || thumbnail.getHeight() != mThumbnailHeight) { 8392 throw new IllegalArgumentException("Bad thumbnail size: got " 8393 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8394 + mThumbnailWidth + "x" + mThumbnailHeight); 8395 } 8396 if (intent.getSelector() != null) { 8397 intent.setSelector(null); 8398 } 8399 if (intent.getSourceBounds() != null) { 8400 intent.setSourceBounds(null); 8401 } 8402 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8403 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8404 // The caller has added this as an auto-remove task... that makes no 8405 // sense, so turn off auto-remove. 8406 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8407 } 8408 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8409 // Must be a new task. 8410 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8411 } 8412 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8413 mLastAddedTaskActivity = null; 8414 } 8415 ActivityInfo ainfo = mLastAddedTaskActivity; 8416 if (ainfo == null) { 8417 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8418 comp, 0, UserHandle.getUserId(callingUid)); 8419 if (ainfo.applicationInfo.uid != callingUid) { 8420 throw new SecurityException( 8421 "Can't add task for another application: target uid=" 8422 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8423 } 8424 } 8425 8426 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8427 intent, description); 8428 8429 int trimIdx = trimRecentsForTask(task, false); 8430 if (trimIdx >= 0) { 8431 // If this would have caused a trim, then we'll abort because that 8432 // means it would be added at the end of the list but then just removed. 8433 return -1; 8434 } 8435 8436 final int N = mRecentTasks.size(); 8437 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8438 final TaskRecord tr = mRecentTasks.remove(N - 1); 8439 tr.removedFromRecents(mTaskPersister); 8440 } 8441 8442 task.inRecents = true; 8443 mRecentTasks.add(task); 8444 r.task.stack.addTask(task, false, false); 8445 8446 task.setLastThumbnail(thumbnail); 8447 task.freeLastThumbnail(); 8448 8449 return task.taskId; 8450 } 8451 } finally { 8452 Binder.restoreCallingIdentity(callingIdent); 8453 } 8454 } 8455 8456 @Override 8457 public Point getAppTaskThumbnailSize() { 8458 synchronized (this) { 8459 return new Point(mThumbnailWidth, mThumbnailHeight); 8460 } 8461 } 8462 8463 @Override 8464 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8465 synchronized (this) { 8466 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8467 if (r != null) { 8468 r.setTaskDescription(td); 8469 r.task.updateTaskDescription(); 8470 } 8471 } 8472 } 8473 8474 @Override 8475 public Bitmap getTaskDescriptionIcon(String filename) { 8476 if (!FileUtils.isValidExtFilename(filename) 8477 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8478 throw new IllegalArgumentException("Bad filename: " + filename); 8479 } 8480 return mTaskPersister.getTaskDescriptionIcon(filename); 8481 } 8482 8483 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8484 mRecentTasks.remove(tr); 8485 tr.removedFromRecents(mTaskPersister); 8486 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8487 Intent baseIntent = new Intent( 8488 tr.intent != null ? tr.intent : tr.affinityIntent); 8489 ComponentName component = baseIntent.getComponent(); 8490 if (component == null) { 8491 Slog.w(TAG, "Now component for base intent of task: " + tr); 8492 return; 8493 } 8494 8495 // Find any running services associated with this app. 8496 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8497 8498 if (killProcesses) { 8499 // Find any running processes associated with this app. 8500 final String pkg = component.getPackageName(); 8501 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8502 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8503 for (int i=0; i<pmap.size(); i++) { 8504 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8505 for (int j=0; j<uids.size(); j++) { 8506 ProcessRecord proc = uids.valueAt(j); 8507 if (proc.userId != tr.userId) { 8508 continue; 8509 } 8510 if (!proc.pkgList.containsKey(pkg)) { 8511 continue; 8512 } 8513 procs.add(proc); 8514 } 8515 } 8516 8517 // Kill the running processes. 8518 for (int i=0; i<procs.size(); i++) { 8519 ProcessRecord pr = procs.get(i); 8520 if (pr == mHomeProcess) { 8521 // Don't kill the home process along with tasks from the same package. 8522 continue; 8523 } 8524 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8525 pr.kill("remove task", true); 8526 } else { 8527 pr.waitingToKill = "remove task"; 8528 } 8529 } 8530 } 8531 } 8532 8533 /** 8534 * Removes the task with the specified task id. 8535 * 8536 * @param taskId Identifier of the task to be removed. 8537 * @param flags Additional operational flags. May be 0 or 8538 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8539 * @return Returns true if the given task was found and removed. 8540 */ 8541 private boolean removeTaskByIdLocked(int taskId, int flags) { 8542 TaskRecord tr = recentTaskForIdLocked(taskId); 8543 if (tr != null) { 8544 tr.removeTaskActivitiesLocked(); 8545 cleanUpRemovedTaskLocked(tr, flags); 8546 if (tr.isPersistable) { 8547 notifyTaskPersisterLocked(null, true); 8548 } 8549 return true; 8550 } 8551 return false; 8552 } 8553 8554 @Override 8555 public boolean removeTask(int taskId, int flags) { 8556 synchronized (this) { 8557 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8558 "removeTask()"); 8559 long ident = Binder.clearCallingIdentity(); 8560 try { 8561 return removeTaskByIdLocked(taskId, flags); 8562 } finally { 8563 Binder.restoreCallingIdentity(ident); 8564 } 8565 } 8566 } 8567 8568 /** 8569 * TODO: Add mController hook 8570 */ 8571 @Override 8572 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8573 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8574 "moveTaskToFront()"); 8575 8576 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8577 synchronized(this) { 8578 moveTaskToFrontLocked(taskId, flags, options); 8579 } 8580 } 8581 8582 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8583 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8584 Binder.getCallingUid(), -1, -1, "Task to front")) { 8585 ActivityOptions.abort(options); 8586 return; 8587 } 8588 final long origId = Binder.clearCallingIdentity(); 8589 try { 8590 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8591 if (task == null) { 8592 return; 8593 } 8594 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8595 mStackSupervisor.showLockTaskToast(); 8596 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8597 return; 8598 } 8599 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8600 if (prev != null && prev.isRecentsActivity()) { 8601 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8602 } 8603 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8604 } finally { 8605 Binder.restoreCallingIdentity(origId); 8606 } 8607 ActivityOptions.abort(options); 8608 } 8609 8610 @Override 8611 public void moveTaskToBack(int taskId) { 8612 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8613 "moveTaskToBack()"); 8614 8615 synchronized(this) { 8616 TaskRecord tr = recentTaskForIdLocked(taskId); 8617 if (tr != null) { 8618 if (tr == mStackSupervisor.mLockTaskModeTask) { 8619 mStackSupervisor.showLockTaskToast(); 8620 return; 8621 } 8622 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8623 ActivityStack stack = tr.stack; 8624 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8625 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8626 Binder.getCallingUid(), -1, -1, "Task to back")) { 8627 return; 8628 } 8629 } 8630 final long origId = Binder.clearCallingIdentity(); 8631 try { 8632 stack.moveTaskToBackLocked(taskId, null); 8633 } finally { 8634 Binder.restoreCallingIdentity(origId); 8635 } 8636 } 8637 } 8638 } 8639 8640 /** 8641 * Moves an activity, and all of the other activities within the same task, to the bottom 8642 * of the history stack. The activity's order within the task is unchanged. 8643 * 8644 * @param token A reference to the activity we wish to move 8645 * @param nonRoot If false then this only works if the activity is the root 8646 * of a task; if true it will work for any activity in a task. 8647 * @return Returns true if the move completed, false if not. 8648 */ 8649 @Override 8650 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8651 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8652 synchronized(this) { 8653 final long origId = Binder.clearCallingIdentity(); 8654 try { 8655 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8656 if (taskId >= 0) { 8657 if ((mStackSupervisor.mLockTaskModeTask != null) 8658 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8659 mStackSupervisor.showLockTaskToast(); 8660 return false; 8661 } 8662 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8663 } 8664 } finally { 8665 Binder.restoreCallingIdentity(origId); 8666 } 8667 } 8668 return false; 8669 } 8670 8671 @Override 8672 public void moveTaskBackwards(int task) { 8673 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8674 "moveTaskBackwards()"); 8675 8676 synchronized(this) { 8677 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8678 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8679 return; 8680 } 8681 final long origId = Binder.clearCallingIdentity(); 8682 moveTaskBackwardsLocked(task); 8683 Binder.restoreCallingIdentity(origId); 8684 } 8685 } 8686 8687 private final void moveTaskBackwardsLocked(int task) { 8688 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8689 } 8690 8691 @Override 8692 public IBinder getHomeActivityToken() throws RemoteException { 8693 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8694 "getHomeActivityToken()"); 8695 synchronized (this) { 8696 return mStackSupervisor.getHomeActivityToken(); 8697 } 8698 } 8699 8700 @Override 8701 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8702 IActivityContainerCallback callback) throws RemoteException { 8703 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8704 "createActivityContainer()"); 8705 synchronized (this) { 8706 if (parentActivityToken == null) { 8707 throw new IllegalArgumentException("parent token must not be null"); 8708 } 8709 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8710 if (r == null) { 8711 return null; 8712 } 8713 if (callback == null) { 8714 throw new IllegalArgumentException("callback must not be null"); 8715 } 8716 return mStackSupervisor.createActivityContainer(r, callback); 8717 } 8718 } 8719 8720 @Override 8721 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8722 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8723 "deleteActivityContainer()"); 8724 synchronized (this) { 8725 mStackSupervisor.deleteActivityContainer(container); 8726 } 8727 } 8728 8729 @Override 8730 public int getActivityDisplayId(IBinder activityToken) throws RemoteException { 8731 synchronized (this) { 8732 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8733 if (stack != null && stack.mActivityContainer.isAttachedLocked()) { 8734 return stack.mActivityContainer.getDisplayId(); 8735 } 8736 return Display.DEFAULT_DISPLAY; 8737 } 8738 } 8739 8740 @Override 8741 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8742 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8743 "moveTaskToStack()"); 8744 if (stackId == HOME_STACK_ID) { 8745 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8746 new RuntimeException("here").fillInStackTrace()); 8747 } 8748 synchronized (this) { 8749 long ident = Binder.clearCallingIdentity(); 8750 try { 8751 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8752 + stackId + " toTop=" + toTop); 8753 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8754 } finally { 8755 Binder.restoreCallingIdentity(ident); 8756 } 8757 } 8758 } 8759 8760 @Override 8761 public void resizeStack(int stackBoxId, Rect bounds) { 8762 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8763 "resizeStackBox()"); 8764 long ident = Binder.clearCallingIdentity(); 8765 try { 8766 mWindowManager.resizeStack(stackBoxId, bounds); 8767 } finally { 8768 Binder.restoreCallingIdentity(ident); 8769 } 8770 } 8771 8772 @Override 8773 public List<StackInfo> getAllStackInfos() { 8774 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8775 "getAllStackInfos()"); 8776 long ident = Binder.clearCallingIdentity(); 8777 try { 8778 synchronized (this) { 8779 return mStackSupervisor.getAllStackInfosLocked(); 8780 } 8781 } finally { 8782 Binder.restoreCallingIdentity(ident); 8783 } 8784 } 8785 8786 @Override 8787 public StackInfo getStackInfo(int stackId) { 8788 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8789 "getStackInfo()"); 8790 long ident = Binder.clearCallingIdentity(); 8791 try { 8792 synchronized (this) { 8793 return mStackSupervisor.getStackInfoLocked(stackId); 8794 } 8795 } finally { 8796 Binder.restoreCallingIdentity(ident); 8797 } 8798 } 8799 8800 @Override 8801 public boolean isInHomeStack(int taskId) { 8802 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8803 "getStackInfo()"); 8804 long ident = Binder.clearCallingIdentity(); 8805 try { 8806 synchronized (this) { 8807 TaskRecord tr = recentTaskForIdLocked(taskId); 8808 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8809 } 8810 } finally { 8811 Binder.restoreCallingIdentity(ident); 8812 } 8813 } 8814 8815 @Override 8816 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8817 synchronized(this) { 8818 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8819 } 8820 } 8821 8822 private boolean isLockTaskAuthorized(String pkg) { 8823 final DevicePolicyManager dpm = (DevicePolicyManager) 8824 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8825 try { 8826 int uid = mContext.getPackageManager().getPackageUid(pkg, 8827 Binder.getCallingUserHandle().getIdentifier()); 8828 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8829 } catch (NameNotFoundException e) { 8830 return false; 8831 } 8832 } 8833 8834 void startLockTaskMode(TaskRecord task) { 8835 final String pkg; 8836 synchronized (this) { 8837 pkg = task.intent.getComponent().getPackageName(); 8838 } 8839 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8840 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8841 final TaskRecord taskRecord = task; 8842 mHandler.post(new Runnable() { 8843 @Override 8844 public void run() { 8845 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8846 } 8847 }); 8848 return; 8849 } 8850 long ident = Binder.clearCallingIdentity(); 8851 try { 8852 synchronized (this) { 8853 // Since we lost lock on task, make sure it is still there. 8854 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8855 if (task != null) { 8856 if (!isSystemInitiated 8857 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8858 throw new IllegalArgumentException("Invalid task, not in foreground"); 8859 } 8860 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8861 } 8862 } 8863 } finally { 8864 Binder.restoreCallingIdentity(ident); 8865 } 8866 } 8867 8868 @Override 8869 public void startLockTaskMode(int taskId) { 8870 final TaskRecord task; 8871 long ident = Binder.clearCallingIdentity(); 8872 try { 8873 synchronized (this) { 8874 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8875 } 8876 } finally { 8877 Binder.restoreCallingIdentity(ident); 8878 } 8879 if (task != null) { 8880 startLockTaskMode(task); 8881 } 8882 } 8883 8884 @Override 8885 public void startLockTaskMode(IBinder token) { 8886 final TaskRecord task; 8887 long ident = Binder.clearCallingIdentity(); 8888 try { 8889 synchronized (this) { 8890 final ActivityRecord r = ActivityRecord.forToken(token); 8891 if (r == null) { 8892 return; 8893 } 8894 task = r.task; 8895 } 8896 } finally { 8897 Binder.restoreCallingIdentity(ident); 8898 } 8899 if (task != null) { 8900 startLockTaskMode(task); 8901 } 8902 } 8903 8904 @Override 8905 public void startLockTaskModeOnCurrent() throws RemoteException { 8906 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8907 "startLockTaskModeOnCurrent"); 8908 ActivityRecord r = null; 8909 synchronized (this) { 8910 r = mStackSupervisor.topRunningActivityLocked(); 8911 } 8912 startLockTaskMode(r.task); 8913 } 8914 8915 @Override 8916 public void stopLockTaskMode() { 8917 // Verify that the user matches the package of the intent for the TaskRecord 8918 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8919 // and stopLockTaskMode. 8920 final int callingUid = Binder.getCallingUid(); 8921 if (callingUid != Process.SYSTEM_UID) { 8922 try { 8923 String pkg = 8924 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8925 int uid = mContext.getPackageManager().getPackageUid(pkg, 8926 Binder.getCallingUserHandle().getIdentifier()); 8927 if (uid != callingUid) { 8928 throw new SecurityException("Invalid uid, expected " + uid); 8929 } 8930 } catch (NameNotFoundException e) { 8931 Log.d(TAG, "stopLockTaskMode " + e); 8932 return; 8933 } 8934 } 8935 long ident = Binder.clearCallingIdentity(); 8936 try { 8937 Log.d(TAG, "stopLockTaskMode"); 8938 // Stop lock task 8939 synchronized (this) { 8940 mStackSupervisor.setLockTaskModeLocked(null, false); 8941 } 8942 } finally { 8943 Binder.restoreCallingIdentity(ident); 8944 } 8945 } 8946 8947 @Override 8948 public void stopLockTaskModeOnCurrent() throws RemoteException { 8949 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8950 "stopLockTaskModeOnCurrent"); 8951 long ident = Binder.clearCallingIdentity(); 8952 try { 8953 stopLockTaskMode(); 8954 } finally { 8955 Binder.restoreCallingIdentity(ident); 8956 } 8957 } 8958 8959 @Override 8960 public boolean isInLockTaskMode() { 8961 synchronized (this) { 8962 return mStackSupervisor.isInLockTaskMode(); 8963 } 8964 } 8965 8966 // ========================================================= 8967 // CONTENT PROVIDERS 8968 // ========================================================= 8969 8970 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8971 List<ProviderInfo> providers = null; 8972 try { 8973 providers = AppGlobals.getPackageManager(). 8974 queryContentProviders(app.processName, app.uid, 8975 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8976 } catch (RemoteException ex) { 8977 } 8978 if (DEBUG_MU) 8979 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8980 int userId = app.userId; 8981 if (providers != null) { 8982 int N = providers.size(); 8983 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8984 for (int i=0; i<N; i++) { 8985 ProviderInfo cpi = 8986 (ProviderInfo)providers.get(i); 8987 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8988 cpi.name, cpi.flags); 8989 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8990 // This is a singleton provider, but a user besides the 8991 // default user is asking to initialize a process it runs 8992 // in... well, no, it doesn't actually run in this process, 8993 // it runs in the process of the default user. Get rid of it. 8994 providers.remove(i); 8995 N--; 8996 i--; 8997 continue; 8998 } 8999 9000 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9001 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 9002 if (cpr == null) { 9003 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 9004 mProviderMap.putProviderByClass(comp, cpr); 9005 } 9006 if (DEBUG_MU) 9007 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 9008 app.pubProviders.put(cpi.name, cpr); 9009 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9010 // Don't add this if it is a platform component that is marked 9011 // to run in multiple processes, because this is actually 9012 // part of the framework so doesn't make sense to track as a 9013 // separate apk in the process. 9014 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9015 mProcessStats); 9016 } 9017 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9018 } 9019 } 9020 return providers; 9021 } 9022 9023 /** 9024 * Check if {@link ProcessRecord} has a possible chance at accessing the 9025 * given {@link ProviderInfo}. Final permission checking is always done 9026 * in {@link ContentProvider}. 9027 */ 9028 private final String checkContentProviderPermissionLocked( 9029 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9030 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9031 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9032 boolean checkedGrants = false; 9033 if (checkUser) { 9034 // Looking for cross-user grants before enforcing the typical cross-users permissions 9035 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9036 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9037 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9038 return null; 9039 } 9040 checkedGrants = true; 9041 } 9042 userId = handleIncomingUser(callingPid, callingUid, userId, 9043 false, ALLOW_NON_FULL, 9044 "checkContentProviderPermissionLocked " + cpi.authority, null); 9045 if (userId != tmpTargetUserId) { 9046 // When we actually went to determine the final targer user ID, this ended 9047 // up different than our initial check for the authority. This is because 9048 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9049 // SELF. So we need to re-check the grants again. 9050 checkedGrants = false; 9051 } 9052 } 9053 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9054 cpi.applicationInfo.uid, cpi.exported) 9055 == PackageManager.PERMISSION_GRANTED) { 9056 return null; 9057 } 9058 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9059 cpi.applicationInfo.uid, cpi.exported) 9060 == PackageManager.PERMISSION_GRANTED) { 9061 return null; 9062 } 9063 9064 PathPermission[] pps = cpi.pathPermissions; 9065 if (pps != null) { 9066 int i = pps.length; 9067 while (i > 0) { 9068 i--; 9069 PathPermission pp = pps[i]; 9070 String pprperm = pp.getReadPermission(); 9071 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9072 cpi.applicationInfo.uid, cpi.exported) 9073 == PackageManager.PERMISSION_GRANTED) { 9074 return null; 9075 } 9076 String ppwperm = pp.getWritePermission(); 9077 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9078 cpi.applicationInfo.uid, cpi.exported) 9079 == PackageManager.PERMISSION_GRANTED) { 9080 return null; 9081 } 9082 } 9083 } 9084 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9085 return null; 9086 } 9087 9088 String msg; 9089 if (!cpi.exported) { 9090 msg = "Permission Denial: opening provider " + cpi.name 9091 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9092 + ", uid=" + callingUid + ") that is not exported from uid " 9093 + cpi.applicationInfo.uid; 9094 } else { 9095 msg = "Permission Denial: opening provider " + cpi.name 9096 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9097 + ", uid=" + callingUid + ") requires " 9098 + cpi.readPermission + " or " + cpi.writePermission; 9099 } 9100 Slog.w(TAG, msg); 9101 return msg; 9102 } 9103 9104 /** 9105 * Returns if the ContentProvider has granted a uri to callingUid 9106 */ 9107 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9108 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9109 if (perms != null) { 9110 for (int i=perms.size()-1; i>=0; i--) { 9111 GrantUri grantUri = perms.keyAt(i); 9112 if (grantUri.sourceUserId == userId || !checkUser) { 9113 if (matchesProvider(grantUri.uri, cpi)) { 9114 return true; 9115 } 9116 } 9117 } 9118 } 9119 return false; 9120 } 9121 9122 /** 9123 * Returns true if the uri authority is one of the authorities specified in the provider. 9124 */ 9125 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9126 String uriAuth = uri.getAuthority(); 9127 String cpiAuth = cpi.authority; 9128 if (cpiAuth.indexOf(';') == -1) { 9129 return cpiAuth.equals(uriAuth); 9130 } 9131 String[] cpiAuths = cpiAuth.split(";"); 9132 int length = cpiAuths.length; 9133 for (int i = 0; i < length; i++) { 9134 if (cpiAuths[i].equals(uriAuth)) return true; 9135 } 9136 return false; 9137 } 9138 9139 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9140 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9141 if (r != null) { 9142 for (int i=0; i<r.conProviders.size(); i++) { 9143 ContentProviderConnection conn = r.conProviders.get(i); 9144 if (conn.provider == cpr) { 9145 if (DEBUG_PROVIDER) Slog.v(TAG, 9146 "Adding provider requested by " 9147 + r.processName + " from process " 9148 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9149 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9150 if (stable) { 9151 conn.stableCount++; 9152 conn.numStableIncs++; 9153 } else { 9154 conn.unstableCount++; 9155 conn.numUnstableIncs++; 9156 } 9157 return conn; 9158 } 9159 } 9160 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9161 if (stable) { 9162 conn.stableCount = 1; 9163 conn.numStableIncs = 1; 9164 } else { 9165 conn.unstableCount = 1; 9166 conn.numUnstableIncs = 1; 9167 } 9168 cpr.connections.add(conn); 9169 r.conProviders.add(conn); 9170 return conn; 9171 } 9172 cpr.addExternalProcessHandleLocked(externalProcessToken); 9173 return null; 9174 } 9175 9176 boolean decProviderCountLocked(ContentProviderConnection conn, 9177 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9178 if (conn != null) { 9179 cpr = conn.provider; 9180 if (DEBUG_PROVIDER) Slog.v(TAG, 9181 "Removing provider requested by " 9182 + conn.client.processName + " from process " 9183 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9184 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9185 if (stable) { 9186 conn.stableCount--; 9187 } else { 9188 conn.unstableCount--; 9189 } 9190 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9191 cpr.connections.remove(conn); 9192 conn.client.conProviders.remove(conn); 9193 return true; 9194 } 9195 return false; 9196 } 9197 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9198 return false; 9199 } 9200 9201 private void checkTime(long startTime, String where) { 9202 long now = SystemClock.elapsedRealtime(); 9203 if ((now-startTime) > 1000) { 9204 // If we are taking more than a second, log about it. 9205 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9206 } 9207 } 9208 9209 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9210 String name, IBinder token, boolean stable, int userId) { 9211 ContentProviderRecord cpr; 9212 ContentProviderConnection conn = null; 9213 ProviderInfo cpi = null; 9214 9215 synchronized(this) { 9216 long startTime = SystemClock.elapsedRealtime(); 9217 9218 ProcessRecord r = null; 9219 if (caller != null) { 9220 r = getRecordForAppLocked(caller); 9221 if (r == null) { 9222 throw new SecurityException( 9223 "Unable to find app for caller " + caller 9224 + " (pid=" + Binder.getCallingPid() 9225 + ") when getting content provider " + name); 9226 } 9227 } 9228 9229 boolean checkCrossUser = true; 9230 9231 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9232 9233 // First check if this content provider has been published... 9234 cpr = mProviderMap.getProviderByName(name, userId); 9235 // If that didn't work, check if it exists for user 0 and then 9236 // verify that it's a singleton provider before using it. 9237 if (cpr == null && userId != UserHandle.USER_OWNER) { 9238 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9239 if (cpr != null) { 9240 cpi = cpr.info; 9241 if (isSingleton(cpi.processName, cpi.applicationInfo, 9242 cpi.name, cpi.flags) 9243 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9244 userId = UserHandle.USER_OWNER; 9245 checkCrossUser = false; 9246 } else { 9247 cpr = null; 9248 cpi = null; 9249 } 9250 } 9251 } 9252 9253 boolean providerRunning = cpr != null; 9254 if (providerRunning) { 9255 cpi = cpr.info; 9256 String msg; 9257 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9258 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9259 != null) { 9260 throw new SecurityException(msg); 9261 } 9262 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9263 9264 if (r != null && cpr.canRunHere(r)) { 9265 // This provider has been published or is in the process 9266 // of being published... but it is also allowed to run 9267 // in the caller's process, so don't make a connection 9268 // and just let the caller instantiate its own instance. 9269 ContentProviderHolder holder = cpr.newHolder(null); 9270 // don't give caller the provider object, it needs 9271 // to make its own. 9272 holder.provider = null; 9273 return holder; 9274 } 9275 9276 final long origId = Binder.clearCallingIdentity(); 9277 9278 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9279 9280 // In this case the provider instance already exists, so we can 9281 // return it right away. 9282 conn = incProviderCountLocked(r, cpr, token, stable); 9283 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9284 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9285 // If this is a perceptible app accessing the provider, 9286 // make sure to count it as being accessed and thus 9287 // back up on the LRU list. This is good because 9288 // content providers are often expensive to start. 9289 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9290 updateLruProcessLocked(cpr.proc, false, null); 9291 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9292 } 9293 } 9294 9295 if (cpr.proc != null) { 9296 if (false) { 9297 if (cpr.name.flattenToShortString().equals( 9298 "com.android.providers.calendar/.CalendarProvider2")) { 9299 Slog.v(TAG, "****************** KILLING " 9300 + cpr.name.flattenToShortString()); 9301 Process.killProcess(cpr.proc.pid); 9302 } 9303 } 9304 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9305 boolean success = updateOomAdjLocked(cpr.proc); 9306 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9307 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9308 // NOTE: there is still a race here where a signal could be 9309 // pending on the process even though we managed to update its 9310 // adj level. Not sure what to do about this, but at least 9311 // the race is now smaller. 9312 if (!success) { 9313 // Uh oh... it looks like the provider's process 9314 // has been killed on us. We need to wait for a new 9315 // process to be started, and make sure its death 9316 // doesn't kill our process. 9317 Slog.i(TAG, 9318 "Existing provider " + cpr.name.flattenToShortString() 9319 + " is crashing; detaching " + r); 9320 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9321 checkTime(startTime, "getContentProviderImpl: before appDied"); 9322 appDiedLocked(cpr.proc); 9323 checkTime(startTime, "getContentProviderImpl: after appDied"); 9324 if (!lastRef) { 9325 // This wasn't the last ref our process had on 9326 // the provider... we have now been killed, bail. 9327 return null; 9328 } 9329 providerRunning = false; 9330 conn = null; 9331 } 9332 } 9333 9334 Binder.restoreCallingIdentity(origId); 9335 } 9336 9337 boolean singleton; 9338 if (!providerRunning) { 9339 try { 9340 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9341 cpi = AppGlobals.getPackageManager(). 9342 resolveContentProvider(name, 9343 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9344 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9345 } catch (RemoteException ex) { 9346 } 9347 if (cpi == null) { 9348 return null; 9349 } 9350 // If the provider is a singleton AND 9351 // (it's a call within the same user || the provider is a 9352 // privileged app) 9353 // Then allow connecting to the singleton provider 9354 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9355 cpi.name, cpi.flags) 9356 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9357 if (singleton) { 9358 userId = UserHandle.USER_OWNER; 9359 } 9360 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9361 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9362 9363 String msg; 9364 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9365 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9366 != null) { 9367 throw new SecurityException(msg); 9368 } 9369 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9370 9371 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9372 && !cpi.processName.equals("system")) { 9373 // If this content provider does not run in the system 9374 // process, and the system is not yet ready to run other 9375 // processes, then fail fast instead of hanging. 9376 throw new IllegalArgumentException( 9377 "Attempt to launch content provider before system ready"); 9378 } 9379 9380 // Make sure that the user who owns this provider is started. If not, 9381 // we don't want to allow it to run. 9382 if (mStartedUsers.get(userId) == null) { 9383 Slog.w(TAG, "Unable to launch app " 9384 + cpi.applicationInfo.packageName + "/" 9385 + cpi.applicationInfo.uid + " for provider " 9386 + name + ": user " + userId + " is stopped"); 9387 return null; 9388 } 9389 9390 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9391 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9392 cpr = mProviderMap.getProviderByClass(comp, userId); 9393 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9394 final boolean firstClass = cpr == null; 9395 if (firstClass) { 9396 final long ident = Binder.clearCallingIdentity(); 9397 try { 9398 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9399 ApplicationInfo ai = 9400 AppGlobals.getPackageManager(). 9401 getApplicationInfo( 9402 cpi.applicationInfo.packageName, 9403 STOCK_PM_FLAGS, userId); 9404 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9405 if (ai == null) { 9406 Slog.w(TAG, "No package info for content provider " 9407 + cpi.name); 9408 return null; 9409 } 9410 ai = getAppInfoForUser(ai, userId); 9411 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9412 } catch (RemoteException ex) { 9413 // pm is in same process, this will never happen. 9414 } finally { 9415 Binder.restoreCallingIdentity(ident); 9416 } 9417 } 9418 9419 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9420 9421 if (r != null && cpr.canRunHere(r)) { 9422 // If this is a multiprocess provider, then just return its 9423 // info and allow the caller to instantiate it. Only do 9424 // this if the provider is the same user as the caller's 9425 // process, or can run as root (so can be in any process). 9426 return cpr.newHolder(null); 9427 } 9428 9429 if (DEBUG_PROVIDER) { 9430 RuntimeException e = new RuntimeException("here"); 9431 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9432 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9433 } 9434 9435 // This is single process, and our app is now connecting to it. 9436 // See if we are already in the process of launching this 9437 // provider. 9438 final int N = mLaunchingProviders.size(); 9439 int i; 9440 for (i=0; i<N; i++) { 9441 if (mLaunchingProviders.get(i) == cpr) { 9442 break; 9443 } 9444 } 9445 9446 // If the provider is not already being launched, then get it 9447 // started. 9448 if (i >= N) { 9449 final long origId = Binder.clearCallingIdentity(); 9450 9451 try { 9452 // Content provider is now in use, its package can't be stopped. 9453 try { 9454 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9455 AppGlobals.getPackageManager().setPackageStoppedState( 9456 cpr.appInfo.packageName, false, userId); 9457 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9458 } catch (RemoteException e) { 9459 } catch (IllegalArgumentException e) { 9460 Slog.w(TAG, "Failed trying to unstop package " 9461 + cpr.appInfo.packageName + ": " + e); 9462 } 9463 9464 // Use existing process if already started 9465 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9466 ProcessRecord proc = getProcessRecordLocked( 9467 cpi.processName, cpr.appInfo.uid, false); 9468 if (proc != null && proc.thread != null) { 9469 if (DEBUG_PROVIDER) { 9470 Slog.d(TAG, "Installing in existing process " + proc); 9471 } 9472 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9473 proc.pubProviders.put(cpi.name, cpr); 9474 try { 9475 proc.thread.scheduleInstallProvider(cpi); 9476 } catch (RemoteException e) { 9477 } 9478 } else { 9479 checkTime(startTime, "getContentProviderImpl: before start process"); 9480 proc = startProcessLocked(cpi.processName, 9481 cpr.appInfo, false, 0, "content provider", 9482 new ComponentName(cpi.applicationInfo.packageName, 9483 cpi.name), false, false, false); 9484 checkTime(startTime, "getContentProviderImpl: after start process"); 9485 if (proc == null) { 9486 Slog.w(TAG, "Unable to launch app " 9487 + cpi.applicationInfo.packageName + "/" 9488 + cpi.applicationInfo.uid + " for provider " 9489 + name + ": process is bad"); 9490 return null; 9491 } 9492 } 9493 cpr.launchingApp = proc; 9494 mLaunchingProviders.add(cpr); 9495 } finally { 9496 Binder.restoreCallingIdentity(origId); 9497 } 9498 } 9499 9500 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9501 9502 // Make sure the provider is published (the same provider class 9503 // may be published under multiple names). 9504 if (firstClass) { 9505 mProviderMap.putProviderByClass(comp, cpr); 9506 } 9507 9508 mProviderMap.putProviderByName(name, cpr); 9509 conn = incProviderCountLocked(r, cpr, token, stable); 9510 if (conn != null) { 9511 conn.waiting = true; 9512 } 9513 } 9514 checkTime(startTime, "getContentProviderImpl: done!"); 9515 } 9516 9517 // Wait for the provider to be published... 9518 synchronized (cpr) { 9519 while (cpr.provider == null) { 9520 if (cpr.launchingApp == null) { 9521 Slog.w(TAG, "Unable to launch app " 9522 + cpi.applicationInfo.packageName + "/" 9523 + cpi.applicationInfo.uid + " for provider " 9524 + name + ": launching app became null"); 9525 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9526 UserHandle.getUserId(cpi.applicationInfo.uid), 9527 cpi.applicationInfo.packageName, 9528 cpi.applicationInfo.uid, name); 9529 return null; 9530 } 9531 try { 9532 if (DEBUG_MU) { 9533 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9534 + cpr.launchingApp); 9535 } 9536 if (conn != null) { 9537 conn.waiting = true; 9538 } 9539 cpr.wait(); 9540 } catch (InterruptedException ex) { 9541 } finally { 9542 if (conn != null) { 9543 conn.waiting = false; 9544 } 9545 } 9546 } 9547 } 9548 return cpr != null ? cpr.newHolder(conn) : null; 9549 } 9550 9551 @Override 9552 public final ContentProviderHolder getContentProvider( 9553 IApplicationThread caller, String name, int userId, boolean stable) { 9554 enforceNotIsolatedCaller("getContentProvider"); 9555 if (caller == null) { 9556 String msg = "null IApplicationThread when getting content provider " 9557 + name; 9558 Slog.w(TAG, msg); 9559 throw new SecurityException(msg); 9560 } 9561 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9562 // with cross-user grant. 9563 return getContentProviderImpl(caller, name, null, stable, userId); 9564 } 9565 9566 public ContentProviderHolder getContentProviderExternal( 9567 String name, int userId, IBinder token) { 9568 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9569 "Do not have permission in call getContentProviderExternal()"); 9570 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9571 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9572 return getContentProviderExternalUnchecked(name, token, userId); 9573 } 9574 9575 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9576 IBinder token, int userId) { 9577 return getContentProviderImpl(null, name, token, true, userId); 9578 } 9579 9580 /** 9581 * Drop a content provider from a ProcessRecord's bookkeeping 9582 */ 9583 public void removeContentProvider(IBinder connection, boolean stable) { 9584 enforceNotIsolatedCaller("removeContentProvider"); 9585 long ident = Binder.clearCallingIdentity(); 9586 try { 9587 synchronized (this) { 9588 ContentProviderConnection conn; 9589 try { 9590 conn = (ContentProviderConnection)connection; 9591 } catch (ClassCastException e) { 9592 String msg ="removeContentProvider: " + connection 9593 + " not a ContentProviderConnection"; 9594 Slog.w(TAG, msg); 9595 throw new IllegalArgumentException(msg); 9596 } 9597 if (conn == null) { 9598 throw new NullPointerException("connection is null"); 9599 } 9600 if (decProviderCountLocked(conn, null, null, stable)) { 9601 updateOomAdjLocked(); 9602 } 9603 } 9604 } finally { 9605 Binder.restoreCallingIdentity(ident); 9606 } 9607 } 9608 9609 public void removeContentProviderExternal(String name, IBinder token) { 9610 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9611 "Do not have permission in call removeContentProviderExternal()"); 9612 int userId = UserHandle.getCallingUserId(); 9613 long ident = Binder.clearCallingIdentity(); 9614 try { 9615 removeContentProviderExternalUnchecked(name, token, userId); 9616 } finally { 9617 Binder.restoreCallingIdentity(ident); 9618 } 9619 } 9620 9621 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9622 synchronized (this) { 9623 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9624 if(cpr == null) { 9625 //remove from mProvidersByClass 9626 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9627 return; 9628 } 9629 9630 //update content provider record entry info 9631 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9632 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9633 if (localCpr.hasExternalProcessHandles()) { 9634 if (localCpr.removeExternalProcessHandleLocked(token)) { 9635 updateOomAdjLocked(); 9636 } else { 9637 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9638 + " with no external reference for token: " 9639 + token + "."); 9640 } 9641 } else { 9642 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9643 + " with no external references."); 9644 } 9645 } 9646 } 9647 9648 public final void publishContentProviders(IApplicationThread caller, 9649 List<ContentProviderHolder> providers) { 9650 if (providers == null) { 9651 return; 9652 } 9653 9654 enforceNotIsolatedCaller("publishContentProviders"); 9655 synchronized (this) { 9656 final ProcessRecord r = getRecordForAppLocked(caller); 9657 if (DEBUG_MU) 9658 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9659 if (r == null) { 9660 throw new SecurityException( 9661 "Unable to find app for caller " + caller 9662 + " (pid=" + Binder.getCallingPid() 9663 + ") when publishing content providers"); 9664 } 9665 9666 final long origId = Binder.clearCallingIdentity(); 9667 9668 final int N = providers.size(); 9669 for (int i=0; i<N; i++) { 9670 ContentProviderHolder src = providers.get(i); 9671 if (src == null || src.info == null || src.provider == null) { 9672 continue; 9673 } 9674 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9675 if (DEBUG_MU) 9676 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9677 if (dst != null) { 9678 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9679 mProviderMap.putProviderByClass(comp, dst); 9680 String names[] = dst.info.authority.split(";"); 9681 for (int j = 0; j < names.length; j++) { 9682 mProviderMap.putProviderByName(names[j], dst); 9683 } 9684 9685 int NL = mLaunchingProviders.size(); 9686 int j; 9687 for (j=0; j<NL; j++) { 9688 if (mLaunchingProviders.get(j) == dst) { 9689 mLaunchingProviders.remove(j); 9690 j--; 9691 NL--; 9692 } 9693 } 9694 synchronized (dst) { 9695 dst.provider = src.provider; 9696 dst.proc = r; 9697 dst.notifyAll(); 9698 } 9699 updateOomAdjLocked(r); 9700 } 9701 } 9702 9703 Binder.restoreCallingIdentity(origId); 9704 } 9705 } 9706 9707 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9708 ContentProviderConnection conn; 9709 try { 9710 conn = (ContentProviderConnection)connection; 9711 } catch (ClassCastException e) { 9712 String msg ="refContentProvider: " + connection 9713 + " not a ContentProviderConnection"; 9714 Slog.w(TAG, msg); 9715 throw new IllegalArgumentException(msg); 9716 } 9717 if (conn == null) { 9718 throw new NullPointerException("connection is null"); 9719 } 9720 9721 synchronized (this) { 9722 if (stable > 0) { 9723 conn.numStableIncs += stable; 9724 } 9725 stable = conn.stableCount + stable; 9726 if (stable < 0) { 9727 throw new IllegalStateException("stableCount < 0: " + stable); 9728 } 9729 9730 if (unstable > 0) { 9731 conn.numUnstableIncs += unstable; 9732 } 9733 unstable = conn.unstableCount + unstable; 9734 if (unstable < 0) { 9735 throw new IllegalStateException("unstableCount < 0: " + unstable); 9736 } 9737 9738 if ((stable+unstable) <= 0) { 9739 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9740 + stable + " unstable=" + unstable); 9741 } 9742 conn.stableCount = stable; 9743 conn.unstableCount = unstable; 9744 return !conn.dead; 9745 } 9746 } 9747 9748 public void unstableProviderDied(IBinder connection) { 9749 ContentProviderConnection conn; 9750 try { 9751 conn = (ContentProviderConnection)connection; 9752 } catch (ClassCastException e) { 9753 String msg ="refContentProvider: " + connection 9754 + " not a ContentProviderConnection"; 9755 Slog.w(TAG, msg); 9756 throw new IllegalArgumentException(msg); 9757 } 9758 if (conn == null) { 9759 throw new NullPointerException("connection is null"); 9760 } 9761 9762 // Safely retrieve the content provider associated with the connection. 9763 IContentProvider provider; 9764 synchronized (this) { 9765 provider = conn.provider.provider; 9766 } 9767 9768 if (provider == null) { 9769 // Um, yeah, we're way ahead of you. 9770 return; 9771 } 9772 9773 // Make sure the caller is being honest with us. 9774 if (provider.asBinder().pingBinder()) { 9775 // Er, no, still looks good to us. 9776 synchronized (this) { 9777 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9778 + " says " + conn + " died, but we don't agree"); 9779 return; 9780 } 9781 } 9782 9783 // Well look at that! It's dead! 9784 synchronized (this) { 9785 if (conn.provider.provider != provider) { 9786 // But something changed... good enough. 9787 return; 9788 } 9789 9790 ProcessRecord proc = conn.provider.proc; 9791 if (proc == null || proc.thread == null) { 9792 // Seems like the process is already cleaned up. 9793 return; 9794 } 9795 9796 // As far as we're concerned, this is just like receiving a 9797 // death notification... just a bit prematurely. 9798 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9799 + ") early provider death"); 9800 final long ident = Binder.clearCallingIdentity(); 9801 try { 9802 appDiedLocked(proc); 9803 } finally { 9804 Binder.restoreCallingIdentity(ident); 9805 } 9806 } 9807 } 9808 9809 @Override 9810 public void appNotRespondingViaProvider(IBinder connection) { 9811 enforceCallingPermission( 9812 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9813 9814 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9815 if (conn == null) { 9816 Slog.w(TAG, "ContentProviderConnection is null"); 9817 return; 9818 } 9819 9820 final ProcessRecord host = conn.provider.proc; 9821 if (host == null) { 9822 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9823 return; 9824 } 9825 9826 final long token = Binder.clearCallingIdentity(); 9827 try { 9828 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9829 } finally { 9830 Binder.restoreCallingIdentity(token); 9831 } 9832 } 9833 9834 public final void installSystemProviders() { 9835 List<ProviderInfo> providers; 9836 synchronized (this) { 9837 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9838 providers = generateApplicationProvidersLocked(app); 9839 if (providers != null) { 9840 for (int i=providers.size()-1; i>=0; i--) { 9841 ProviderInfo pi = (ProviderInfo)providers.get(i); 9842 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9843 Slog.w(TAG, "Not installing system proc provider " + pi.name 9844 + ": not system .apk"); 9845 providers.remove(i); 9846 } 9847 } 9848 } 9849 } 9850 if (providers != null) { 9851 mSystemThread.installSystemProviders(providers); 9852 } 9853 9854 mCoreSettingsObserver = new CoreSettingsObserver(this); 9855 9856 //mUsageStatsService.monitorPackages(); 9857 } 9858 9859 /** 9860 * Allows apps to retrieve the MIME type of a URI. 9861 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9862 * users, then it does not need permission to access the ContentProvider. 9863 * Either, it needs cross-user uri grants. 9864 * 9865 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9866 * 9867 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9868 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9869 */ 9870 public String getProviderMimeType(Uri uri, int userId) { 9871 enforceNotIsolatedCaller("getProviderMimeType"); 9872 final String name = uri.getAuthority(); 9873 int callingUid = Binder.getCallingUid(); 9874 int callingPid = Binder.getCallingPid(); 9875 long ident = 0; 9876 boolean clearedIdentity = false; 9877 userId = unsafeConvertIncomingUser(userId); 9878 if (canClearIdentity(callingPid, callingUid, userId)) { 9879 clearedIdentity = true; 9880 ident = Binder.clearCallingIdentity(); 9881 } 9882 ContentProviderHolder holder = null; 9883 try { 9884 holder = getContentProviderExternalUnchecked(name, null, userId); 9885 if (holder != null) { 9886 return holder.provider.getType(uri); 9887 } 9888 } catch (RemoteException e) { 9889 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9890 return null; 9891 } finally { 9892 // We need to clear the identity to call removeContentProviderExternalUnchecked 9893 if (!clearedIdentity) { 9894 ident = Binder.clearCallingIdentity(); 9895 } 9896 try { 9897 if (holder != null) { 9898 removeContentProviderExternalUnchecked(name, null, userId); 9899 } 9900 } finally { 9901 Binder.restoreCallingIdentity(ident); 9902 } 9903 } 9904 9905 return null; 9906 } 9907 9908 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9909 if (UserHandle.getUserId(callingUid) == userId) { 9910 return true; 9911 } 9912 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9913 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9914 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9915 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9916 return true; 9917 } 9918 return false; 9919 } 9920 9921 // ========================================================= 9922 // GLOBAL MANAGEMENT 9923 // ========================================================= 9924 9925 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9926 boolean isolated, int isolatedUid) { 9927 String proc = customProcess != null ? customProcess : info.processName; 9928 BatteryStatsImpl.Uid.Proc ps = null; 9929 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9930 int uid = info.uid; 9931 if (isolated) { 9932 if (isolatedUid == 0) { 9933 int userId = UserHandle.getUserId(uid); 9934 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9935 while (true) { 9936 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9937 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9938 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9939 } 9940 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9941 mNextIsolatedProcessUid++; 9942 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9943 // No process for this uid, use it. 9944 break; 9945 } 9946 stepsLeft--; 9947 if (stepsLeft <= 0) { 9948 return null; 9949 } 9950 } 9951 } else { 9952 // Special case for startIsolatedProcess (internal only), where 9953 // the uid of the isolated process is specified by the caller. 9954 uid = isolatedUid; 9955 } 9956 } 9957 return new ProcessRecord(stats, info, proc, uid); 9958 } 9959 9960 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9961 String abiOverride) { 9962 ProcessRecord app; 9963 if (!isolated) { 9964 app = getProcessRecordLocked(info.processName, info.uid, true); 9965 } else { 9966 app = null; 9967 } 9968 9969 if (app == null) { 9970 app = newProcessRecordLocked(info, null, isolated, 0); 9971 mProcessNames.put(info.processName, app.uid, app); 9972 if (isolated) { 9973 mIsolatedProcesses.put(app.uid, app); 9974 } 9975 updateLruProcessLocked(app, false, null); 9976 updateOomAdjLocked(); 9977 } 9978 9979 // This package really, really can not be stopped. 9980 try { 9981 AppGlobals.getPackageManager().setPackageStoppedState( 9982 info.packageName, false, UserHandle.getUserId(app.uid)); 9983 } catch (RemoteException e) { 9984 } catch (IllegalArgumentException e) { 9985 Slog.w(TAG, "Failed trying to unstop package " 9986 + info.packageName + ": " + e); 9987 } 9988 9989 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9990 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9991 app.persistent = true; 9992 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9993 } 9994 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9995 mPersistentStartingProcesses.add(app); 9996 startProcessLocked(app, "added application", app.processName, abiOverride, 9997 null /* entryPoint */, null /* entryPointArgs */); 9998 } 9999 10000 return app; 10001 } 10002 10003 public void unhandledBack() { 10004 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 10005 "unhandledBack()"); 10006 10007 synchronized(this) { 10008 final long origId = Binder.clearCallingIdentity(); 10009 try { 10010 getFocusedStack().unhandledBackLocked(); 10011 } finally { 10012 Binder.restoreCallingIdentity(origId); 10013 } 10014 } 10015 } 10016 10017 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10018 enforceNotIsolatedCaller("openContentUri"); 10019 final int userId = UserHandle.getCallingUserId(); 10020 String name = uri.getAuthority(); 10021 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10022 ParcelFileDescriptor pfd = null; 10023 if (cph != null) { 10024 // We record the binder invoker's uid in thread-local storage before 10025 // going to the content provider to open the file. Later, in the code 10026 // that handles all permissions checks, we look for this uid and use 10027 // that rather than the Activity Manager's own uid. The effect is that 10028 // we do the check against the caller's permissions even though it looks 10029 // to the content provider like the Activity Manager itself is making 10030 // the request. 10031 sCallerIdentity.set(new Identity( 10032 Binder.getCallingPid(), Binder.getCallingUid())); 10033 try { 10034 pfd = cph.provider.openFile(null, uri, "r", null); 10035 } catch (FileNotFoundException e) { 10036 // do nothing; pfd will be returned null 10037 } finally { 10038 // Ensure that whatever happens, we clean up the identity state 10039 sCallerIdentity.remove(); 10040 } 10041 10042 // We've got the fd now, so we're done with the provider. 10043 removeContentProviderExternalUnchecked(name, null, userId); 10044 } else { 10045 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10046 } 10047 return pfd; 10048 } 10049 10050 // Actually is sleeping or shutting down or whatever else in the future 10051 // is an inactive state. 10052 public boolean isSleepingOrShuttingDown() { 10053 return isSleeping() || mShuttingDown; 10054 } 10055 10056 public boolean isSleeping() { 10057 return mSleeping; 10058 } 10059 10060 void goingToSleep() { 10061 synchronized(this) { 10062 mWentToSleep = true; 10063 goToSleepIfNeededLocked(); 10064 } 10065 } 10066 10067 void finishRunningVoiceLocked() { 10068 if (mRunningVoice) { 10069 mRunningVoice = false; 10070 goToSleepIfNeededLocked(); 10071 } 10072 } 10073 10074 void goToSleepIfNeededLocked() { 10075 if (mWentToSleep && !mRunningVoice) { 10076 if (!mSleeping) { 10077 mSleeping = true; 10078 mStackSupervisor.goingToSleepLocked(); 10079 10080 // Initialize the wake times of all processes. 10081 checkExcessivePowerUsageLocked(false); 10082 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10083 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10084 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10085 } 10086 } 10087 } 10088 10089 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10090 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10091 // Never persist the home stack. 10092 return; 10093 } 10094 mTaskPersister.wakeup(task, flush); 10095 } 10096 10097 @Override 10098 public boolean shutdown(int timeout) { 10099 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10100 != PackageManager.PERMISSION_GRANTED) { 10101 throw new SecurityException("Requires permission " 10102 + android.Manifest.permission.SHUTDOWN); 10103 } 10104 10105 boolean timedout = false; 10106 10107 synchronized(this) { 10108 mShuttingDown = true; 10109 updateEventDispatchingLocked(); 10110 timedout = mStackSupervisor.shutdownLocked(timeout); 10111 } 10112 10113 mAppOpsService.shutdown(); 10114 if (mUsageStatsService != null) { 10115 mUsageStatsService.prepareShutdown(); 10116 } 10117 mBatteryStatsService.shutdown(); 10118 synchronized (this) { 10119 mProcessStats.shutdownLocked(); 10120 } 10121 notifyTaskPersisterLocked(null, true); 10122 10123 return timedout; 10124 } 10125 10126 public final void activitySlept(IBinder token) { 10127 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10128 10129 final long origId = Binder.clearCallingIdentity(); 10130 10131 synchronized (this) { 10132 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10133 if (r != null) { 10134 mStackSupervisor.activitySleptLocked(r); 10135 } 10136 } 10137 10138 Binder.restoreCallingIdentity(origId); 10139 } 10140 10141 void logLockScreen(String msg) { 10142 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10143 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10144 mWentToSleep + " mSleeping=" + mSleeping); 10145 } 10146 10147 private void comeOutOfSleepIfNeededLocked() { 10148 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10149 if (mSleeping) { 10150 mSleeping = false; 10151 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10152 } 10153 } 10154 } 10155 10156 void wakingUp() { 10157 synchronized(this) { 10158 mWentToSleep = false; 10159 comeOutOfSleepIfNeededLocked(); 10160 } 10161 } 10162 10163 void startRunningVoiceLocked() { 10164 if (!mRunningVoice) { 10165 mRunningVoice = true; 10166 comeOutOfSleepIfNeededLocked(); 10167 } 10168 } 10169 10170 private void updateEventDispatchingLocked() { 10171 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10172 } 10173 10174 public void setLockScreenShown(boolean shown) { 10175 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10176 != PackageManager.PERMISSION_GRANTED) { 10177 throw new SecurityException("Requires permission " 10178 + android.Manifest.permission.DEVICE_POWER); 10179 } 10180 10181 synchronized(this) { 10182 long ident = Binder.clearCallingIdentity(); 10183 try { 10184 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10185 mLockScreenShown = shown; 10186 comeOutOfSleepIfNeededLocked(); 10187 } finally { 10188 Binder.restoreCallingIdentity(ident); 10189 } 10190 } 10191 } 10192 10193 @Override 10194 public void stopAppSwitches() { 10195 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10196 != PackageManager.PERMISSION_GRANTED) { 10197 throw new SecurityException("Requires permission " 10198 + android.Manifest.permission.STOP_APP_SWITCHES); 10199 } 10200 10201 synchronized(this) { 10202 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10203 + APP_SWITCH_DELAY_TIME; 10204 mDidAppSwitch = false; 10205 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10206 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10207 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10208 } 10209 } 10210 10211 public void resumeAppSwitches() { 10212 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10213 != PackageManager.PERMISSION_GRANTED) { 10214 throw new SecurityException("Requires permission " 10215 + android.Manifest.permission.STOP_APP_SWITCHES); 10216 } 10217 10218 synchronized(this) { 10219 // Note that we don't execute any pending app switches... we will 10220 // let those wait until either the timeout, or the next start 10221 // activity request. 10222 mAppSwitchesAllowedTime = 0; 10223 } 10224 } 10225 10226 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10227 int callingPid, int callingUid, String name) { 10228 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10229 return true; 10230 } 10231 10232 int perm = checkComponentPermission( 10233 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10234 sourceUid, -1, true); 10235 if (perm == PackageManager.PERMISSION_GRANTED) { 10236 return true; 10237 } 10238 10239 // If the actual IPC caller is different from the logical source, then 10240 // also see if they are allowed to control app switches. 10241 if (callingUid != -1 && callingUid != sourceUid) { 10242 perm = checkComponentPermission( 10243 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10244 callingUid, -1, true); 10245 if (perm == PackageManager.PERMISSION_GRANTED) { 10246 return true; 10247 } 10248 } 10249 10250 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10251 return false; 10252 } 10253 10254 public void setDebugApp(String packageName, boolean waitForDebugger, 10255 boolean persistent) { 10256 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10257 "setDebugApp()"); 10258 10259 long ident = Binder.clearCallingIdentity(); 10260 try { 10261 // Note that this is not really thread safe if there are multiple 10262 // callers into it at the same time, but that's not a situation we 10263 // care about. 10264 if (persistent) { 10265 final ContentResolver resolver = mContext.getContentResolver(); 10266 Settings.Global.putString( 10267 resolver, Settings.Global.DEBUG_APP, 10268 packageName); 10269 Settings.Global.putInt( 10270 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10271 waitForDebugger ? 1 : 0); 10272 } 10273 10274 synchronized (this) { 10275 if (!persistent) { 10276 mOrigDebugApp = mDebugApp; 10277 mOrigWaitForDebugger = mWaitForDebugger; 10278 } 10279 mDebugApp = packageName; 10280 mWaitForDebugger = waitForDebugger; 10281 mDebugTransient = !persistent; 10282 if (packageName != null) { 10283 forceStopPackageLocked(packageName, -1, false, false, true, true, 10284 false, UserHandle.USER_ALL, "set debug app"); 10285 } 10286 } 10287 } finally { 10288 Binder.restoreCallingIdentity(ident); 10289 } 10290 } 10291 10292 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10293 synchronized (this) { 10294 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10295 if (!isDebuggable) { 10296 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10297 throw new SecurityException("Process not debuggable: " + app.packageName); 10298 } 10299 } 10300 10301 mOpenGlTraceApp = processName; 10302 } 10303 } 10304 10305 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10306 synchronized (this) { 10307 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10308 if (!isDebuggable) { 10309 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10310 throw new SecurityException("Process not debuggable: " + app.packageName); 10311 } 10312 } 10313 mProfileApp = processName; 10314 mProfileFile = profilerInfo.profileFile; 10315 if (mProfileFd != null) { 10316 try { 10317 mProfileFd.close(); 10318 } catch (IOException e) { 10319 } 10320 mProfileFd = null; 10321 } 10322 mProfileFd = profilerInfo.profileFd; 10323 mSamplingInterval = profilerInfo.samplingInterval; 10324 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10325 mProfileType = 0; 10326 } 10327 } 10328 10329 @Override 10330 public void setAlwaysFinish(boolean enabled) { 10331 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10332 "setAlwaysFinish()"); 10333 10334 Settings.Global.putInt( 10335 mContext.getContentResolver(), 10336 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10337 10338 synchronized (this) { 10339 mAlwaysFinishActivities = enabled; 10340 } 10341 } 10342 10343 @Override 10344 public void setActivityController(IActivityController controller) { 10345 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10346 "setActivityController()"); 10347 synchronized (this) { 10348 mController = controller; 10349 Watchdog.getInstance().setActivityController(controller); 10350 } 10351 } 10352 10353 @Override 10354 public void setUserIsMonkey(boolean userIsMonkey) { 10355 synchronized (this) { 10356 synchronized (mPidsSelfLocked) { 10357 final int callingPid = Binder.getCallingPid(); 10358 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10359 if (precessRecord == null) { 10360 throw new SecurityException("Unknown process: " + callingPid); 10361 } 10362 if (precessRecord.instrumentationUiAutomationConnection == null) { 10363 throw new SecurityException("Only an instrumentation process " 10364 + "with a UiAutomation can call setUserIsMonkey"); 10365 } 10366 } 10367 mUserIsMonkey = userIsMonkey; 10368 } 10369 } 10370 10371 @Override 10372 public boolean isUserAMonkey() { 10373 synchronized (this) { 10374 // If there is a controller also implies the user is a monkey. 10375 return (mUserIsMonkey || mController != null); 10376 } 10377 } 10378 10379 public void requestBugReport() { 10380 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10381 SystemProperties.set("ctl.start", "bugreport"); 10382 } 10383 10384 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10385 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10386 } 10387 10388 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10389 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10390 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10391 } 10392 return KEY_DISPATCHING_TIMEOUT; 10393 } 10394 10395 @Override 10396 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10397 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10398 != PackageManager.PERMISSION_GRANTED) { 10399 throw new SecurityException("Requires permission " 10400 + android.Manifest.permission.FILTER_EVENTS); 10401 } 10402 ProcessRecord proc; 10403 long timeout; 10404 synchronized (this) { 10405 synchronized (mPidsSelfLocked) { 10406 proc = mPidsSelfLocked.get(pid); 10407 } 10408 timeout = getInputDispatchingTimeoutLocked(proc); 10409 } 10410 10411 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10412 return -1; 10413 } 10414 10415 return timeout; 10416 } 10417 10418 /** 10419 * Handle input dispatching timeouts. 10420 * Returns whether input dispatching should be aborted or not. 10421 */ 10422 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10423 final ActivityRecord activity, final ActivityRecord parent, 10424 final boolean aboveSystem, String reason) { 10425 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10426 != PackageManager.PERMISSION_GRANTED) { 10427 throw new SecurityException("Requires permission " 10428 + android.Manifest.permission.FILTER_EVENTS); 10429 } 10430 10431 final String annotation; 10432 if (reason == null) { 10433 annotation = "Input dispatching timed out"; 10434 } else { 10435 annotation = "Input dispatching timed out (" + reason + ")"; 10436 } 10437 10438 if (proc != null) { 10439 synchronized (this) { 10440 if (proc.debugging) { 10441 return false; 10442 } 10443 10444 if (mDidDexOpt) { 10445 // Give more time since we were dexopting. 10446 mDidDexOpt = false; 10447 return false; 10448 } 10449 10450 if (proc.instrumentationClass != null) { 10451 Bundle info = new Bundle(); 10452 info.putString("shortMsg", "keyDispatchingTimedOut"); 10453 info.putString("longMsg", annotation); 10454 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10455 return true; 10456 } 10457 } 10458 mHandler.post(new Runnable() { 10459 @Override 10460 public void run() { 10461 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10462 } 10463 }); 10464 } 10465 10466 return true; 10467 } 10468 10469 public Bundle getAssistContextExtras(int requestType) { 10470 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10471 UserHandle.getCallingUserId()); 10472 if (pae == null) { 10473 return null; 10474 } 10475 synchronized (pae) { 10476 while (!pae.haveResult) { 10477 try { 10478 pae.wait(); 10479 } catch (InterruptedException e) { 10480 } 10481 } 10482 if (pae.result != null) { 10483 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10484 } 10485 } 10486 synchronized (this) { 10487 mPendingAssistExtras.remove(pae); 10488 mHandler.removeCallbacks(pae); 10489 } 10490 return pae.extras; 10491 } 10492 10493 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10494 int userHandle) { 10495 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10496 "getAssistContextExtras()"); 10497 PendingAssistExtras pae; 10498 Bundle extras = new Bundle(); 10499 synchronized (this) { 10500 ActivityRecord activity = getFocusedStack().mResumedActivity; 10501 if (activity == null) { 10502 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10503 return null; 10504 } 10505 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10506 if (activity.app == null || activity.app.thread == null) { 10507 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10508 return null; 10509 } 10510 if (activity.app.pid == Binder.getCallingPid()) { 10511 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10512 return null; 10513 } 10514 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10515 try { 10516 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10517 requestType); 10518 mPendingAssistExtras.add(pae); 10519 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10520 } catch (RemoteException e) { 10521 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10522 return null; 10523 } 10524 return pae; 10525 } 10526 } 10527 10528 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10529 PendingAssistExtras pae = (PendingAssistExtras)token; 10530 synchronized (pae) { 10531 pae.result = extras; 10532 pae.haveResult = true; 10533 pae.notifyAll(); 10534 if (pae.intent == null) { 10535 // Caller is just waiting for the result. 10536 return; 10537 } 10538 } 10539 10540 // We are now ready to launch the assist activity. 10541 synchronized (this) { 10542 boolean exists = mPendingAssistExtras.remove(pae); 10543 mHandler.removeCallbacks(pae); 10544 if (!exists) { 10545 // Timed out. 10546 return; 10547 } 10548 } 10549 pae.intent.replaceExtras(extras); 10550 if (pae.hint != null) { 10551 pae.intent.putExtra(pae.hint, true); 10552 } 10553 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10554 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10555 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10556 closeSystemDialogs("assist"); 10557 try { 10558 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10559 } catch (ActivityNotFoundException e) { 10560 Slog.w(TAG, "No activity to handle assist action.", e); 10561 } 10562 } 10563 10564 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10565 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10566 } 10567 10568 public void registerProcessObserver(IProcessObserver observer) { 10569 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10570 "registerProcessObserver()"); 10571 synchronized (this) { 10572 mProcessObservers.register(observer); 10573 } 10574 } 10575 10576 @Override 10577 public void unregisterProcessObserver(IProcessObserver observer) { 10578 synchronized (this) { 10579 mProcessObservers.unregister(observer); 10580 } 10581 } 10582 10583 @Override 10584 public boolean convertFromTranslucent(IBinder token) { 10585 final long origId = Binder.clearCallingIdentity(); 10586 try { 10587 synchronized (this) { 10588 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10589 if (r == null) { 10590 return false; 10591 } 10592 final boolean translucentChanged = r.changeWindowTranslucency(true); 10593 if (translucentChanged) { 10594 r.task.stack.releaseBackgroundResources(); 10595 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10596 } 10597 mWindowManager.setAppFullscreen(token, true); 10598 return translucentChanged; 10599 } 10600 } finally { 10601 Binder.restoreCallingIdentity(origId); 10602 } 10603 } 10604 10605 @Override 10606 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10607 final long origId = Binder.clearCallingIdentity(); 10608 try { 10609 synchronized (this) { 10610 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10611 if (r == null) { 10612 return false; 10613 } 10614 int index = r.task.mActivities.lastIndexOf(r); 10615 if (index > 0) { 10616 ActivityRecord under = r.task.mActivities.get(index - 1); 10617 under.returningOptions = options; 10618 } 10619 final boolean translucentChanged = r.changeWindowTranslucency(false); 10620 if (translucentChanged) { 10621 r.task.stack.convertToTranslucent(r); 10622 } 10623 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10624 mWindowManager.setAppFullscreen(token, false); 10625 return translucentChanged; 10626 } 10627 } finally { 10628 Binder.restoreCallingIdentity(origId); 10629 } 10630 } 10631 10632 @Override 10633 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10634 final long origId = Binder.clearCallingIdentity(); 10635 try { 10636 synchronized (this) { 10637 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10638 if (r != null) { 10639 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10640 } 10641 } 10642 return false; 10643 } finally { 10644 Binder.restoreCallingIdentity(origId); 10645 } 10646 } 10647 10648 @Override 10649 public boolean isBackgroundVisibleBehind(IBinder token) { 10650 final long origId = Binder.clearCallingIdentity(); 10651 try { 10652 synchronized (this) { 10653 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10654 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10655 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10656 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10657 return visible; 10658 } 10659 } finally { 10660 Binder.restoreCallingIdentity(origId); 10661 } 10662 } 10663 10664 @Override 10665 public ActivityOptions getActivityOptions(IBinder token) { 10666 final long origId = Binder.clearCallingIdentity(); 10667 try { 10668 synchronized (this) { 10669 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10670 if (r != null) { 10671 final ActivityOptions activityOptions = r.pendingOptions; 10672 r.pendingOptions = null; 10673 return activityOptions; 10674 } 10675 return null; 10676 } 10677 } finally { 10678 Binder.restoreCallingIdentity(origId); 10679 } 10680 } 10681 10682 @Override 10683 public void setImmersive(IBinder token, boolean immersive) { 10684 synchronized(this) { 10685 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10686 if (r == null) { 10687 throw new IllegalArgumentException(); 10688 } 10689 r.immersive = immersive; 10690 10691 // update associated state if we're frontmost 10692 if (r == mFocusedActivity) { 10693 if (DEBUG_IMMERSIVE) { 10694 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10695 } 10696 applyUpdateLockStateLocked(r); 10697 } 10698 } 10699 } 10700 10701 @Override 10702 public boolean isImmersive(IBinder token) { 10703 synchronized (this) { 10704 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10705 if (r == null) { 10706 throw new IllegalArgumentException(); 10707 } 10708 return r.immersive; 10709 } 10710 } 10711 10712 public boolean isTopActivityImmersive() { 10713 enforceNotIsolatedCaller("startActivity"); 10714 synchronized (this) { 10715 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10716 return (r != null) ? r.immersive : false; 10717 } 10718 } 10719 10720 @Override 10721 public boolean isTopOfTask(IBinder token) { 10722 synchronized (this) { 10723 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10724 if (r == null) { 10725 throw new IllegalArgumentException(); 10726 } 10727 return r.task.getTopActivity() == r; 10728 } 10729 } 10730 10731 public final void enterSafeMode() { 10732 synchronized(this) { 10733 // It only makes sense to do this before the system is ready 10734 // and started launching other packages. 10735 if (!mSystemReady) { 10736 try { 10737 AppGlobals.getPackageManager().enterSafeMode(); 10738 } catch (RemoteException e) { 10739 } 10740 } 10741 10742 mSafeMode = true; 10743 } 10744 } 10745 10746 public final void showSafeModeOverlay() { 10747 View v = LayoutInflater.from(mContext).inflate( 10748 com.android.internal.R.layout.safe_mode, null); 10749 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10750 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10751 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10752 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10753 lp.gravity = Gravity.BOTTOM | Gravity.START; 10754 lp.format = v.getBackground().getOpacity(); 10755 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10756 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10757 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10758 ((WindowManager)mContext.getSystemService( 10759 Context.WINDOW_SERVICE)).addView(v, lp); 10760 } 10761 10762 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10763 if (!(sender instanceof PendingIntentRecord)) { 10764 return; 10765 } 10766 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10767 synchronized (stats) { 10768 if (mBatteryStatsService.isOnBattery()) { 10769 mBatteryStatsService.enforceCallingPermission(); 10770 PendingIntentRecord rec = (PendingIntentRecord)sender; 10771 int MY_UID = Binder.getCallingUid(); 10772 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10773 BatteryStatsImpl.Uid.Pkg pkg = 10774 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10775 sourcePkg != null ? sourcePkg : rec.key.packageName); 10776 pkg.incWakeupsLocked(); 10777 } 10778 } 10779 } 10780 10781 public boolean killPids(int[] pids, String pReason, boolean secure) { 10782 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10783 throw new SecurityException("killPids only available to the system"); 10784 } 10785 String reason = (pReason == null) ? "Unknown" : pReason; 10786 // XXX Note: don't acquire main activity lock here, because the window 10787 // manager calls in with its locks held. 10788 10789 boolean killed = false; 10790 synchronized (mPidsSelfLocked) { 10791 int[] types = new int[pids.length]; 10792 int worstType = 0; 10793 for (int i=0; i<pids.length; i++) { 10794 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10795 if (proc != null) { 10796 int type = proc.setAdj; 10797 types[i] = type; 10798 if (type > worstType) { 10799 worstType = type; 10800 } 10801 } 10802 } 10803 10804 // If the worst oom_adj is somewhere in the cached proc LRU range, 10805 // then constrain it so we will kill all cached procs. 10806 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10807 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10808 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10809 } 10810 10811 // If this is not a secure call, don't let it kill processes that 10812 // are important. 10813 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10814 worstType = ProcessList.SERVICE_ADJ; 10815 } 10816 10817 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10818 for (int i=0; i<pids.length; i++) { 10819 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10820 if (proc == null) { 10821 continue; 10822 } 10823 int adj = proc.setAdj; 10824 if (adj >= worstType && !proc.killedByAm) { 10825 proc.kill(reason, true); 10826 killed = true; 10827 } 10828 } 10829 } 10830 return killed; 10831 } 10832 10833 @Override 10834 public void killUid(int uid, String reason) { 10835 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10836 throw new SecurityException("killUid only available to the system"); 10837 } 10838 synchronized (this) { 10839 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10840 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10841 reason != null ? reason : "kill uid"); 10842 } 10843 } 10844 10845 @Override 10846 public boolean killProcessesBelowForeground(String reason) { 10847 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10848 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10849 } 10850 10851 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10852 } 10853 10854 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10855 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10856 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10857 } 10858 10859 boolean killed = false; 10860 synchronized (mPidsSelfLocked) { 10861 final int size = mPidsSelfLocked.size(); 10862 for (int i = 0; i < size; i++) { 10863 final int pid = mPidsSelfLocked.keyAt(i); 10864 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10865 if (proc == null) continue; 10866 10867 final int adj = proc.setAdj; 10868 if (adj > belowAdj && !proc.killedByAm) { 10869 proc.kill(reason, true); 10870 killed = true; 10871 } 10872 } 10873 } 10874 return killed; 10875 } 10876 10877 @Override 10878 public void hang(final IBinder who, boolean allowRestart) { 10879 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10880 != PackageManager.PERMISSION_GRANTED) { 10881 throw new SecurityException("Requires permission " 10882 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10883 } 10884 10885 final IBinder.DeathRecipient death = new DeathRecipient() { 10886 @Override 10887 public void binderDied() { 10888 synchronized (this) { 10889 notifyAll(); 10890 } 10891 } 10892 }; 10893 10894 try { 10895 who.linkToDeath(death, 0); 10896 } catch (RemoteException e) { 10897 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10898 return; 10899 } 10900 10901 synchronized (this) { 10902 Watchdog.getInstance().setAllowRestart(allowRestart); 10903 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10904 synchronized (death) { 10905 while (who.isBinderAlive()) { 10906 try { 10907 death.wait(); 10908 } catch (InterruptedException e) { 10909 } 10910 } 10911 } 10912 Watchdog.getInstance().setAllowRestart(true); 10913 } 10914 } 10915 10916 @Override 10917 public void restart() { 10918 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10919 != PackageManager.PERMISSION_GRANTED) { 10920 throw new SecurityException("Requires permission " 10921 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10922 } 10923 10924 Log.i(TAG, "Sending shutdown broadcast..."); 10925 10926 BroadcastReceiver br = new BroadcastReceiver() { 10927 @Override public void onReceive(Context context, Intent intent) { 10928 // Now the broadcast is done, finish up the low-level shutdown. 10929 Log.i(TAG, "Shutting down activity manager..."); 10930 shutdown(10000); 10931 Log.i(TAG, "Shutdown complete, restarting!"); 10932 Process.killProcess(Process.myPid()); 10933 System.exit(10); 10934 } 10935 }; 10936 10937 // First send the high-level shut down broadcast. 10938 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10939 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10940 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10941 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10942 mContext.sendOrderedBroadcastAsUser(intent, 10943 UserHandle.ALL, null, br, mHandler, 0, null, null); 10944 */ 10945 br.onReceive(mContext, intent); 10946 } 10947 10948 private long getLowRamTimeSinceIdle(long now) { 10949 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10950 } 10951 10952 @Override 10953 public void performIdleMaintenance() { 10954 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10955 != PackageManager.PERMISSION_GRANTED) { 10956 throw new SecurityException("Requires permission " 10957 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10958 } 10959 10960 synchronized (this) { 10961 final long now = SystemClock.uptimeMillis(); 10962 final long timeSinceLastIdle = now - mLastIdleTime; 10963 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10964 mLastIdleTime = now; 10965 mLowRamTimeSinceLastIdle = 0; 10966 if (mLowRamStartTime != 0) { 10967 mLowRamStartTime = now; 10968 } 10969 10970 StringBuilder sb = new StringBuilder(128); 10971 sb.append("Idle maintenance over "); 10972 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10973 sb.append(" low RAM for "); 10974 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10975 Slog.i(TAG, sb.toString()); 10976 10977 // If at least 1/3 of our time since the last idle period has been spent 10978 // with RAM low, then we want to kill processes. 10979 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10980 10981 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10982 ProcessRecord proc = mLruProcesses.get(i); 10983 if (proc.notCachedSinceIdle) { 10984 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10985 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10986 if (doKilling && proc.initialIdlePss != 0 10987 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10988 proc.kill("idle maint (pss " + proc.lastPss 10989 + " from " + proc.initialIdlePss + ")", true); 10990 } 10991 } 10992 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10993 proc.notCachedSinceIdle = true; 10994 proc.initialIdlePss = 0; 10995 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10996 isSleeping(), now); 10997 } 10998 } 10999 11000 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 11001 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 11002 } 11003 } 11004 11005 private void retrieveSettings() { 11006 final ContentResolver resolver = mContext.getContentResolver(); 11007 String debugApp = Settings.Global.getString( 11008 resolver, Settings.Global.DEBUG_APP); 11009 boolean waitForDebugger = Settings.Global.getInt( 11010 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11011 boolean alwaysFinishActivities = Settings.Global.getInt( 11012 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11013 boolean forceRtl = Settings.Global.getInt( 11014 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11015 // Transfer any global setting for forcing RTL layout, into a System Property 11016 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11017 11018 Configuration configuration = new Configuration(); 11019 Settings.System.getConfiguration(resolver, configuration); 11020 if (forceRtl) { 11021 // This will take care of setting the correct layout direction flags 11022 configuration.setLayoutDirection(configuration.locale); 11023 } 11024 11025 synchronized (this) { 11026 mDebugApp = mOrigDebugApp = debugApp; 11027 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11028 mAlwaysFinishActivities = alwaysFinishActivities; 11029 // This happens before any activities are started, so we can 11030 // change mConfiguration in-place. 11031 updateConfigurationLocked(configuration, null, false, true); 11032 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11033 } 11034 } 11035 11036 /** Loads resources after the current configuration has been set. */ 11037 private void loadResourcesOnSystemReady() { 11038 final Resources res = mContext.getResources(); 11039 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11040 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11041 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11042 } 11043 11044 public boolean testIsSystemReady() { 11045 // no need to synchronize(this) just to read & return the value 11046 return mSystemReady; 11047 } 11048 11049 private static File getCalledPreBootReceiversFile() { 11050 File dataDir = Environment.getDataDirectory(); 11051 File systemDir = new File(dataDir, "system"); 11052 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11053 return fname; 11054 } 11055 11056 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11057 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11058 File file = getCalledPreBootReceiversFile(); 11059 FileInputStream fis = null; 11060 try { 11061 fis = new FileInputStream(file); 11062 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11063 int fvers = dis.readInt(); 11064 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11065 String vers = dis.readUTF(); 11066 String codename = dis.readUTF(); 11067 String build = dis.readUTF(); 11068 if (android.os.Build.VERSION.RELEASE.equals(vers) 11069 && android.os.Build.VERSION.CODENAME.equals(codename) 11070 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11071 int num = dis.readInt(); 11072 while (num > 0) { 11073 num--; 11074 String pkg = dis.readUTF(); 11075 String cls = dis.readUTF(); 11076 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11077 } 11078 } 11079 } 11080 } catch (FileNotFoundException e) { 11081 } catch (IOException e) { 11082 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11083 } finally { 11084 if (fis != null) { 11085 try { 11086 fis.close(); 11087 } catch (IOException e) { 11088 } 11089 } 11090 } 11091 return lastDoneReceivers; 11092 } 11093 11094 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11095 File file = getCalledPreBootReceiversFile(); 11096 FileOutputStream fos = null; 11097 DataOutputStream dos = null; 11098 try { 11099 fos = new FileOutputStream(file); 11100 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11101 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11102 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11103 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11104 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11105 dos.writeInt(list.size()); 11106 for (int i=0; i<list.size(); i++) { 11107 dos.writeUTF(list.get(i).getPackageName()); 11108 dos.writeUTF(list.get(i).getClassName()); 11109 } 11110 } catch (IOException e) { 11111 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11112 file.delete(); 11113 } finally { 11114 FileUtils.sync(fos); 11115 if (dos != null) { 11116 try { 11117 dos.close(); 11118 } catch (IOException e) { 11119 // TODO Auto-generated catch block 11120 e.printStackTrace(); 11121 } 11122 } 11123 } 11124 } 11125 11126 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11127 ArrayList<ComponentName> doneReceivers, int userId) { 11128 boolean waitingUpdate = false; 11129 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11130 List<ResolveInfo> ris = null; 11131 try { 11132 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11133 intent, null, 0, userId); 11134 } catch (RemoteException e) { 11135 } 11136 if (ris != null) { 11137 for (int i=ris.size()-1; i>=0; i--) { 11138 if ((ris.get(i).activityInfo.applicationInfo.flags 11139 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11140 ris.remove(i); 11141 } 11142 } 11143 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11144 11145 // For User 0, load the version number. When delivering to a new user, deliver 11146 // to all receivers. 11147 if (userId == UserHandle.USER_OWNER) { 11148 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11149 for (int i=0; i<ris.size(); i++) { 11150 ActivityInfo ai = ris.get(i).activityInfo; 11151 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11152 if (lastDoneReceivers.contains(comp)) { 11153 // We already did the pre boot receiver for this app with the current 11154 // platform version, so don't do it again... 11155 ris.remove(i); 11156 i--; 11157 // ...however, do keep it as one that has been done, so we don't 11158 // forget about it when rewriting the file of last done receivers. 11159 doneReceivers.add(comp); 11160 } 11161 } 11162 } 11163 11164 // If primary user, send broadcast to all available users, else just to userId 11165 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11166 : new int[] { userId }; 11167 for (int i = 0; i < ris.size(); i++) { 11168 ActivityInfo ai = ris.get(i).activityInfo; 11169 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11170 doneReceivers.add(comp); 11171 intent.setComponent(comp); 11172 for (int j=0; j<users.length; j++) { 11173 IIntentReceiver finisher = null; 11174 // On last receiver and user, set up a completion callback 11175 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11176 finisher = new IIntentReceiver.Stub() { 11177 public void performReceive(Intent intent, int resultCode, 11178 String data, Bundle extras, boolean ordered, 11179 boolean sticky, int sendingUser) { 11180 // The raw IIntentReceiver interface is called 11181 // with the AM lock held, so redispatch to 11182 // execute our code without the lock. 11183 mHandler.post(onFinishCallback); 11184 } 11185 }; 11186 } 11187 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11188 + " for user " + users[j]); 11189 broadcastIntentLocked(null, null, intent, null, finisher, 11190 0, null, null, null, AppOpsManager.OP_NONE, 11191 true, false, MY_PID, Process.SYSTEM_UID, 11192 users[j]); 11193 if (finisher != null) { 11194 waitingUpdate = true; 11195 } 11196 } 11197 } 11198 } 11199 11200 return waitingUpdate; 11201 } 11202 11203 public void systemReady(final Runnable goingCallback) { 11204 synchronized(this) { 11205 if (mSystemReady) { 11206 // If we're done calling all the receivers, run the next "boot phase" passed in 11207 // by the SystemServer 11208 if (goingCallback != null) { 11209 goingCallback.run(); 11210 } 11211 return; 11212 } 11213 11214 // Make sure we have the current profile info, since it is needed for 11215 // security checks. 11216 updateCurrentProfileIdsLocked(); 11217 11218 if (mRecentTasks == null) { 11219 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11220 if (!mRecentTasks.isEmpty()) { 11221 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11222 } 11223 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11224 mTaskPersister.startPersisting(); 11225 } 11226 11227 // Check to see if there are any update receivers to run. 11228 if (!mDidUpdate) { 11229 if (mWaitingUpdate) { 11230 return; 11231 } 11232 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11233 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11234 public void run() { 11235 synchronized (ActivityManagerService.this) { 11236 mDidUpdate = true; 11237 } 11238 writeLastDonePreBootReceivers(doneReceivers); 11239 showBootMessage(mContext.getText( 11240 R.string.android_upgrading_complete), 11241 false); 11242 systemReady(goingCallback); 11243 } 11244 }, doneReceivers, UserHandle.USER_OWNER); 11245 11246 if (mWaitingUpdate) { 11247 return; 11248 } 11249 mDidUpdate = true; 11250 } 11251 11252 mAppOpsService.systemReady(); 11253 mSystemReady = true; 11254 } 11255 11256 ArrayList<ProcessRecord> procsToKill = null; 11257 synchronized(mPidsSelfLocked) { 11258 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11259 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11260 if (!isAllowedWhileBooting(proc.info)){ 11261 if (procsToKill == null) { 11262 procsToKill = new ArrayList<ProcessRecord>(); 11263 } 11264 procsToKill.add(proc); 11265 } 11266 } 11267 } 11268 11269 synchronized(this) { 11270 if (procsToKill != null) { 11271 for (int i=procsToKill.size()-1; i>=0; i--) { 11272 ProcessRecord proc = procsToKill.get(i); 11273 Slog.i(TAG, "Removing system update proc: " + proc); 11274 removeProcessLocked(proc, true, false, "system update done"); 11275 } 11276 } 11277 11278 // Now that we have cleaned up any update processes, we 11279 // are ready to start launching real processes and know that 11280 // we won't trample on them any more. 11281 mProcessesReady = true; 11282 } 11283 11284 Slog.i(TAG, "System now ready"); 11285 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11286 SystemClock.uptimeMillis()); 11287 11288 synchronized(this) { 11289 // Make sure we have no pre-ready processes sitting around. 11290 11291 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11292 ResolveInfo ri = mContext.getPackageManager() 11293 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11294 STOCK_PM_FLAGS); 11295 CharSequence errorMsg = null; 11296 if (ri != null) { 11297 ActivityInfo ai = ri.activityInfo; 11298 ApplicationInfo app = ai.applicationInfo; 11299 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11300 mTopAction = Intent.ACTION_FACTORY_TEST; 11301 mTopData = null; 11302 mTopComponent = new ComponentName(app.packageName, 11303 ai.name); 11304 } else { 11305 errorMsg = mContext.getResources().getText( 11306 com.android.internal.R.string.factorytest_not_system); 11307 } 11308 } else { 11309 errorMsg = mContext.getResources().getText( 11310 com.android.internal.R.string.factorytest_no_action); 11311 } 11312 if (errorMsg != null) { 11313 mTopAction = null; 11314 mTopData = null; 11315 mTopComponent = null; 11316 Message msg = Message.obtain(); 11317 msg.what = SHOW_FACTORY_ERROR_MSG; 11318 msg.getData().putCharSequence("msg", errorMsg); 11319 mHandler.sendMessage(msg); 11320 } 11321 } 11322 } 11323 11324 retrieveSettings(); 11325 loadResourcesOnSystemReady(); 11326 11327 synchronized (this) { 11328 readGrantedUriPermissionsLocked(); 11329 } 11330 11331 if (goingCallback != null) goingCallback.run(); 11332 11333 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11334 Integer.toString(mCurrentUserId), mCurrentUserId); 11335 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11336 Integer.toString(mCurrentUserId), mCurrentUserId); 11337 mSystemServiceManager.startUser(mCurrentUserId); 11338 11339 synchronized (this) { 11340 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11341 try { 11342 List apps = AppGlobals.getPackageManager(). 11343 getPersistentApplications(STOCK_PM_FLAGS); 11344 if (apps != null) { 11345 int N = apps.size(); 11346 int i; 11347 for (i=0; i<N; i++) { 11348 ApplicationInfo info 11349 = (ApplicationInfo)apps.get(i); 11350 if (info != null && 11351 !info.packageName.equals("android")) { 11352 addAppLocked(info, false, null /* ABI override */); 11353 } 11354 } 11355 } 11356 } catch (RemoteException ex) { 11357 // pm is in same process, this will never happen. 11358 } 11359 } 11360 11361 // Start up initial activity. 11362 mBooting = true; 11363 startHomeActivityLocked(mCurrentUserId); 11364 11365 try { 11366 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11367 Message msg = Message.obtain(); 11368 msg.what = SHOW_UID_ERROR_MSG; 11369 mHandler.sendMessage(msg); 11370 } 11371 } catch (RemoteException e) { 11372 } 11373 11374 long ident = Binder.clearCallingIdentity(); 11375 try { 11376 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11377 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11378 | Intent.FLAG_RECEIVER_FOREGROUND); 11379 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11380 broadcastIntentLocked(null, null, intent, 11381 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11382 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11383 intent = new Intent(Intent.ACTION_USER_STARTING); 11384 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11385 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11386 broadcastIntentLocked(null, null, intent, 11387 null, new IIntentReceiver.Stub() { 11388 @Override 11389 public void performReceive(Intent intent, int resultCode, String data, 11390 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11391 throws RemoteException { 11392 } 11393 }, 0, null, null, 11394 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11395 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11396 } catch (Throwable t) { 11397 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11398 } finally { 11399 Binder.restoreCallingIdentity(ident); 11400 } 11401 mStackSupervisor.resumeTopActivitiesLocked(); 11402 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11403 } 11404 } 11405 11406 private boolean makeAppCrashingLocked(ProcessRecord app, 11407 String shortMsg, String longMsg, String stackTrace) { 11408 app.crashing = true; 11409 app.crashingReport = generateProcessError(app, 11410 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11411 startAppProblemLocked(app); 11412 app.stopFreezingAllLocked(); 11413 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11414 } 11415 11416 private void makeAppNotRespondingLocked(ProcessRecord app, 11417 String activity, String shortMsg, String longMsg) { 11418 app.notResponding = true; 11419 app.notRespondingReport = generateProcessError(app, 11420 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11421 activity, shortMsg, longMsg, null); 11422 startAppProblemLocked(app); 11423 app.stopFreezingAllLocked(); 11424 } 11425 11426 /** 11427 * Generate a process error record, suitable for attachment to a ProcessRecord. 11428 * 11429 * @param app The ProcessRecord in which the error occurred. 11430 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11431 * ActivityManager.AppErrorStateInfo 11432 * @param activity The activity associated with the crash, if known. 11433 * @param shortMsg Short message describing the crash. 11434 * @param longMsg Long message describing the crash. 11435 * @param stackTrace Full crash stack trace, may be null. 11436 * 11437 * @return Returns a fully-formed AppErrorStateInfo record. 11438 */ 11439 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11440 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11441 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11442 11443 report.condition = condition; 11444 report.processName = app.processName; 11445 report.pid = app.pid; 11446 report.uid = app.info.uid; 11447 report.tag = activity; 11448 report.shortMsg = shortMsg; 11449 report.longMsg = longMsg; 11450 report.stackTrace = stackTrace; 11451 11452 return report; 11453 } 11454 11455 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11456 synchronized (this) { 11457 app.crashing = false; 11458 app.crashingReport = null; 11459 app.notResponding = false; 11460 app.notRespondingReport = null; 11461 if (app.anrDialog == fromDialog) { 11462 app.anrDialog = null; 11463 } 11464 if (app.waitDialog == fromDialog) { 11465 app.waitDialog = null; 11466 } 11467 if (app.pid > 0 && app.pid != MY_PID) { 11468 handleAppCrashLocked(app, null, null, null); 11469 app.kill("user request after error", true); 11470 } 11471 } 11472 } 11473 11474 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11475 String stackTrace) { 11476 long now = SystemClock.uptimeMillis(); 11477 11478 Long crashTime; 11479 if (!app.isolated) { 11480 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11481 } else { 11482 crashTime = null; 11483 } 11484 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11485 // This process loses! 11486 Slog.w(TAG, "Process " + app.info.processName 11487 + " has crashed too many times: killing!"); 11488 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11489 app.userId, app.info.processName, app.uid); 11490 mStackSupervisor.handleAppCrashLocked(app); 11491 if (!app.persistent) { 11492 // We don't want to start this process again until the user 11493 // explicitly does so... but for persistent process, we really 11494 // need to keep it running. If a persistent process is actually 11495 // repeatedly crashing, then badness for everyone. 11496 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11497 app.info.processName); 11498 if (!app.isolated) { 11499 // XXX We don't have a way to mark isolated processes 11500 // as bad, since they don't have a peristent identity. 11501 mBadProcesses.put(app.info.processName, app.uid, 11502 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11503 mProcessCrashTimes.remove(app.info.processName, app.uid); 11504 } 11505 app.bad = true; 11506 app.removed = true; 11507 // Don't let services in this process be restarted and potentially 11508 // annoy the user repeatedly. Unless it is persistent, since those 11509 // processes run critical code. 11510 removeProcessLocked(app, false, false, "crash"); 11511 mStackSupervisor.resumeTopActivitiesLocked(); 11512 return false; 11513 } 11514 mStackSupervisor.resumeTopActivitiesLocked(); 11515 } else { 11516 mStackSupervisor.finishTopRunningActivityLocked(app); 11517 } 11518 11519 // Bump up the crash count of any services currently running in the proc. 11520 for (int i=app.services.size()-1; i>=0; i--) { 11521 // Any services running in the application need to be placed 11522 // back in the pending list. 11523 ServiceRecord sr = app.services.valueAt(i); 11524 sr.crashCount++; 11525 } 11526 11527 // If the crashing process is what we consider to be the "home process" and it has been 11528 // replaced by a third-party app, clear the package preferred activities from packages 11529 // with a home activity running in the process to prevent a repeatedly crashing app 11530 // from blocking the user to manually clear the list. 11531 final ArrayList<ActivityRecord> activities = app.activities; 11532 if (app == mHomeProcess && activities.size() > 0 11533 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11534 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11535 final ActivityRecord r = activities.get(activityNdx); 11536 if (r.isHomeActivity()) { 11537 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11538 try { 11539 ActivityThread.getPackageManager() 11540 .clearPackagePreferredActivities(r.packageName); 11541 } catch (RemoteException c) { 11542 // pm is in same process, this will never happen. 11543 } 11544 } 11545 } 11546 } 11547 11548 if (!app.isolated) { 11549 // XXX Can't keep track of crash times for isolated processes, 11550 // because they don't have a perisistent identity. 11551 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11552 } 11553 11554 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11555 return true; 11556 } 11557 11558 void startAppProblemLocked(ProcessRecord app) { 11559 // If this app is not running under the current user, then we 11560 // can't give it a report button because that would require 11561 // launching the report UI under a different user. 11562 app.errorReportReceiver = null; 11563 11564 for (int userId : mCurrentProfileIds) { 11565 if (app.userId == userId) { 11566 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11567 mContext, app.info.packageName, app.info.flags); 11568 } 11569 } 11570 skipCurrentReceiverLocked(app); 11571 } 11572 11573 void skipCurrentReceiverLocked(ProcessRecord app) { 11574 for (BroadcastQueue queue : mBroadcastQueues) { 11575 queue.skipCurrentReceiverLocked(app); 11576 } 11577 } 11578 11579 /** 11580 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11581 * The application process will exit immediately after this call returns. 11582 * @param app object of the crashing app, null for the system server 11583 * @param crashInfo describing the exception 11584 */ 11585 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11586 ProcessRecord r = findAppProcess(app, "Crash"); 11587 final String processName = app == null ? "system_server" 11588 : (r == null ? "unknown" : r.processName); 11589 11590 handleApplicationCrashInner("crash", r, processName, crashInfo); 11591 } 11592 11593 /* Native crash reporting uses this inner version because it needs to be somewhat 11594 * decoupled from the AM-managed cleanup lifecycle 11595 */ 11596 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11597 ApplicationErrorReport.CrashInfo crashInfo) { 11598 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11599 UserHandle.getUserId(Binder.getCallingUid()), processName, 11600 r == null ? -1 : r.info.flags, 11601 crashInfo.exceptionClassName, 11602 crashInfo.exceptionMessage, 11603 crashInfo.throwFileName, 11604 crashInfo.throwLineNumber); 11605 11606 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11607 11608 crashApplication(r, crashInfo); 11609 } 11610 11611 public void handleApplicationStrictModeViolation( 11612 IBinder app, 11613 int violationMask, 11614 StrictMode.ViolationInfo info) { 11615 ProcessRecord r = findAppProcess(app, "StrictMode"); 11616 if (r == null) { 11617 return; 11618 } 11619 11620 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11621 Integer stackFingerprint = info.hashCode(); 11622 boolean logIt = true; 11623 synchronized (mAlreadyLoggedViolatedStacks) { 11624 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11625 logIt = false; 11626 // TODO: sub-sample into EventLog for these, with 11627 // the info.durationMillis? Then we'd get 11628 // the relative pain numbers, without logging all 11629 // the stack traces repeatedly. We'd want to do 11630 // likewise in the client code, which also does 11631 // dup suppression, before the Binder call. 11632 } else { 11633 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11634 mAlreadyLoggedViolatedStacks.clear(); 11635 } 11636 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11637 } 11638 } 11639 if (logIt) { 11640 logStrictModeViolationToDropBox(r, info); 11641 } 11642 } 11643 11644 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11645 AppErrorResult result = new AppErrorResult(); 11646 synchronized (this) { 11647 final long origId = Binder.clearCallingIdentity(); 11648 11649 Message msg = Message.obtain(); 11650 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11651 HashMap<String, Object> data = new HashMap<String, Object>(); 11652 data.put("result", result); 11653 data.put("app", r); 11654 data.put("violationMask", violationMask); 11655 data.put("info", info); 11656 msg.obj = data; 11657 mHandler.sendMessage(msg); 11658 11659 Binder.restoreCallingIdentity(origId); 11660 } 11661 int res = result.get(); 11662 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11663 } 11664 } 11665 11666 // Depending on the policy in effect, there could be a bunch of 11667 // these in quick succession so we try to batch these together to 11668 // minimize disk writes, number of dropbox entries, and maximize 11669 // compression, by having more fewer, larger records. 11670 private void logStrictModeViolationToDropBox( 11671 ProcessRecord process, 11672 StrictMode.ViolationInfo info) { 11673 if (info == null) { 11674 return; 11675 } 11676 final boolean isSystemApp = process == null || 11677 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11678 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11679 final String processName = process == null ? "unknown" : process.processName; 11680 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11681 final DropBoxManager dbox = (DropBoxManager) 11682 mContext.getSystemService(Context.DROPBOX_SERVICE); 11683 11684 // Exit early if the dropbox isn't configured to accept this report type. 11685 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11686 11687 boolean bufferWasEmpty; 11688 boolean needsFlush; 11689 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11690 synchronized (sb) { 11691 bufferWasEmpty = sb.length() == 0; 11692 appendDropBoxProcessHeaders(process, processName, sb); 11693 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11694 sb.append("System-App: ").append(isSystemApp).append("\n"); 11695 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11696 if (info.violationNumThisLoop != 0) { 11697 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11698 } 11699 if (info.numAnimationsRunning != 0) { 11700 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11701 } 11702 if (info.broadcastIntentAction != null) { 11703 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11704 } 11705 if (info.durationMillis != -1) { 11706 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11707 } 11708 if (info.numInstances != -1) { 11709 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11710 } 11711 if (info.tags != null) { 11712 for (String tag : info.tags) { 11713 sb.append("Span-Tag: ").append(tag).append("\n"); 11714 } 11715 } 11716 sb.append("\n"); 11717 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11718 sb.append(info.crashInfo.stackTrace); 11719 } 11720 sb.append("\n"); 11721 11722 // Only buffer up to ~64k. Various logging bits truncate 11723 // things at 128k. 11724 needsFlush = (sb.length() > 64 * 1024); 11725 } 11726 11727 // Flush immediately if the buffer's grown too large, or this 11728 // is a non-system app. Non-system apps are isolated with a 11729 // different tag & policy and not batched. 11730 // 11731 // Batching is useful during internal testing with 11732 // StrictMode settings turned up high. Without batching, 11733 // thousands of separate files could be created on boot. 11734 if (!isSystemApp || needsFlush) { 11735 new Thread("Error dump: " + dropboxTag) { 11736 @Override 11737 public void run() { 11738 String report; 11739 synchronized (sb) { 11740 report = sb.toString(); 11741 sb.delete(0, sb.length()); 11742 sb.trimToSize(); 11743 } 11744 if (report.length() != 0) { 11745 dbox.addText(dropboxTag, report); 11746 } 11747 } 11748 }.start(); 11749 return; 11750 } 11751 11752 // System app batching: 11753 if (!bufferWasEmpty) { 11754 // An existing dropbox-writing thread is outstanding, so 11755 // we don't need to start it up. The existing thread will 11756 // catch the buffer appends we just did. 11757 return; 11758 } 11759 11760 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11761 // (After this point, we shouldn't access AMS internal data structures.) 11762 new Thread("Error dump: " + dropboxTag) { 11763 @Override 11764 public void run() { 11765 // 5 second sleep to let stacks arrive and be batched together 11766 try { 11767 Thread.sleep(5000); // 5 seconds 11768 } catch (InterruptedException e) {} 11769 11770 String errorReport; 11771 synchronized (mStrictModeBuffer) { 11772 errorReport = mStrictModeBuffer.toString(); 11773 if (errorReport.length() == 0) { 11774 return; 11775 } 11776 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11777 mStrictModeBuffer.trimToSize(); 11778 } 11779 dbox.addText(dropboxTag, errorReport); 11780 } 11781 }.start(); 11782 } 11783 11784 /** 11785 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11786 * @param app object of the crashing app, null for the system server 11787 * @param tag reported by the caller 11788 * @param system whether this wtf is coming from the system 11789 * @param crashInfo describing the context of the error 11790 * @return true if the process should exit immediately (WTF is fatal) 11791 */ 11792 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11793 final ApplicationErrorReport.CrashInfo crashInfo) { 11794 final int callingUid = Binder.getCallingUid(); 11795 final int callingPid = Binder.getCallingPid(); 11796 11797 if (system) { 11798 // If this is coming from the system, we could very well have low-level 11799 // system locks held, so we want to do this all asynchronously. And we 11800 // never want this to become fatal, so there is that too. 11801 mHandler.post(new Runnable() { 11802 @Override public void run() { 11803 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11804 } 11805 }); 11806 return false; 11807 } 11808 11809 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11810 crashInfo); 11811 11812 if (r != null && r.pid != Process.myPid() && 11813 Settings.Global.getInt(mContext.getContentResolver(), 11814 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11815 crashApplication(r, crashInfo); 11816 return true; 11817 } else { 11818 return false; 11819 } 11820 } 11821 11822 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11823 final ApplicationErrorReport.CrashInfo crashInfo) { 11824 final ProcessRecord r = findAppProcess(app, "WTF"); 11825 final String processName = app == null ? "system_server" 11826 : (r == null ? "unknown" : r.processName); 11827 11828 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11829 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11830 11831 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11832 11833 return r; 11834 } 11835 11836 /** 11837 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11838 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11839 */ 11840 private ProcessRecord findAppProcess(IBinder app, String reason) { 11841 if (app == null) { 11842 return null; 11843 } 11844 11845 synchronized (this) { 11846 final int NP = mProcessNames.getMap().size(); 11847 for (int ip=0; ip<NP; ip++) { 11848 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11849 final int NA = apps.size(); 11850 for (int ia=0; ia<NA; ia++) { 11851 ProcessRecord p = apps.valueAt(ia); 11852 if (p.thread != null && p.thread.asBinder() == app) { 11853 return p; 11854 } 11855 } 11856 } 11857 11858 Slog.w(TAG, "Can't find mystery application for " + reason 11859 + " from pid=" + Binder.getCallingPid() 11860 + " uid=" + Binder.getCallingUid() + ": " + app); 11861 return null; 11862 } 11863 } 11864 11865 /** 11866 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11867 * to append various headers to the dropbox log text. 11868 */ 11869 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11870 StringBuilder sb) { 11871 // Watchdog thread ends up invoking this function (with 11872 // a null ProcessRecord) to add the stack file to dropbox. 11873 // Do not acquire a lock on this (am) in such cases, as it 11874 // could cause a potential deadlock, if and when watchdog 11875 // is invoked due to unavailability of lock on am and it 11876 // would prevent watchdog from killing system_server. 11877 if (process == null) { 11878 sb.append("Process: ").append(processName).append("\n"); 11879 return; 11880 } 11881 // Note: ProcessRecord 'process' is guarded by the service 11882 // instance. (notably process.pkgList, which could otherwise change 11883 // concurrently during execution of this method) 11884 synchronized (this) { 11885 sb.append("Process: ").append(processName).append("\n"); 11886 int flags = process.info.flags; 11887 IPackageManager pm = AppGlobals.getPackageManager(); 11888 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11889 for (int ip=0; ip<process.pkgList.size(); ip++) { 11890 String pkg = process.pkgList.keyAt(ip); 11891 sb.append("Package: ").append(pkg); 11892 try { 11893 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11894 if (pi != null) { 11895 sb.append(" v").append(pi.versionCode); 11896 if (pi.versionName != null) { 11897 sb.append(" (").append(pi.versionName).append(")"); 11898 } 11899 } 11900 } catch (RemoteException e) { 11901 Slog.e(TAG, "Error getting package info: " + pkg, e); 11902 } 11903 sb.append("\n"); 11904 } 11905 } 11906 } 11907 11908 private static String processClass(ProcessRecord process) { 11909 if (process == null || process.pid == MY_PID) { 11910 return "system_server"; 11911 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11912 return "system_app"; 11913 } else { 11914 return "data_app"; 11915 } 11916 } 11917 11918 /** 11919 * Write a description of an error (crash, WTF, ANR) to the drop box. 11920 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11921 * @param process which caused the error, null means the system server 11922 * @param activity which triggered the error, null if unknown 11923 * @param parent activity related to the error, null if unknown 11924 * @param subject line related to the error, null if absent 11925 * @param report in long form describing the error, null if absent 11926 * @param logFile to include in the report, null if none 11927 * @param crashInfo giving an application stack trace, null if absent 11928 */ 11929 public void addErrorToDropBox(String eventType, 11930 ProcessRecord process, String processName, ActivityRecord activity, 11931 ActivityRecord parent, String subject, 11932 final String report, final File logFile, 11933 final ApplicationErrorReport.CrashInfo crashInfo) { 11934 // NOTE -- this must never acquire the ActivityManagerService lock, 11935 // otherwise the watchdog may be prevented from resetting the system. 11936 11937 final String dropboxTag = processClass(process) + "_" + eventType; 11938 final DropBoxManager dbox = (DropBoxManager) 11939 mContext.getSystemService(Context.DROPBOX_SERVICE); 11940 11941 // Exit early if the dropbox isn't configured to accept this report type. 11942 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11943 11944 final StringBuilder sb = new StringBuilder(1024); 11945 appendDropBoxProcessHeaders(process, processName, sb); 11946 if (activity != null) { 11947 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11948 } 11949 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11950 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11951 } 11952 if (parent != null && parent != activity) { 11953 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11954 } 11955 if (subject != null) { 11956 sb.append("Subject: ").append(subject).append("\n"); 11957 } 11958 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11959 if (Debug.isDebuggerConnected()) { 11960 sb.append("Debugger: Connected\n"); 11961 } 11962 sb.append("\n"); 11963 11964 // Do the rest in a worker thread to avoid blocking the caller on I/O 11965 // (After this point, we shouldn't access AMS internal data structures.) 11966 Thread worker = new Thread("Error dump: " + dropboxTag) { 11967 @Override 11968 public void run() { 11969 if (report != null) { 11970 sb.append(report); 11971 } 11972 if (logFile != null) { 11973 try { 11974 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11975 "\n\n[[TRUNCATED]]")); 11976 } catch (IOException e) { 11977 Slog.e(TAG, "Error reading " + logFile, e); 11978 } 11979 } 11980 if (crashInfo != null && crashInfo.stackTrace != null) { 11981 sb.append(crashInfo.stackTrace); 11982 } 11983 11984 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11985 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11986 if (lines > 0) { 11987 sb.append("\n"); 11988 11989 // Merge several logcat streams, and take the last N lines 11990 InputStreamReader input = null; 11991 try { 11992 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11993 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11994 "-b", "crash", 11995 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11996 11997 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11998 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11999 input = new InputStreamReader(logcat.getInputStream()); 12000 12001 int num; 12002 char[] buf = new char[8192]; 12003 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 12004 } catch (IOException e) { 12005 Slog.e(TAG, "Error running logcat", e); 12006 } finally { 12007 if (input != null) try { input.close(); } catch (IOException e) {} 12008 } 12009 } 12010 12011 dbox.addText(dropboxTag, sb.toString()); 12012 } 12013 }; 12014 12015 if (process == null) { 12016 // If process is null, we are being called from some internal code 12017 // and may be about to die -- run this synchronously. 12018 worker.run(); 12019 } else { 12020 worker.start(); 12021 } 12022 } 12023 12024 /** 12025 * Bring up the "unexpected error" dialog box for a crashing app. 12026 * Deal with edge cases (intercepts from instrumented applications, 12027 * ActivityController, error intent receivers, that sort of thing). 12028 * @param r the application crashing 12029 * @param crashInfo describing the failure 12030 */ 12031 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12032 long timeMillis = System.currentTimeMillis(); 12033 String shortMsg = crashInfo.exceptionClassName; 12034 String longMsg = crashInfo.exceptionMessage; 12035 String stackTrace = crashInfo.stackTrace; 12036 if (shortMsg != null && longMsg != null) { 12037 longMsg = shortMsg + ": " + longMsg; 12038 } else if (shortMsg != null) { 12039 longMsg = shortMsg; 12040 } 12041 12042 AppErrorResult result = new AppErrorResult(); 12043 synchronized (this) { 12044 if (mController != null) { 12045 try { 12046 String name = r != null ? r.processName : null; 12047 int pid = r != null ? r.pid : Binder.getCallingPid(); 12048 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12049 if (!mController.appCrashed(name, pid, 12050 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12051 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12052 && "Native crash".equals(crashInfo.exceptionClassName)) { 12053 Slog.w(TAG, "Skip killing native crashed app " + name 12054 + "(" + pid + ") during testing"); 12055 } else { 12056 Slog.w(TAG, "Force-killing crashed app " + name 12057 + " at watcher's request"); 12058 if (r != null) { 12059 r.kill("crash", true); 12060 } else { 12061 // Huh. 12062 Process.killProcess(pid); 12063 Process.killProcessGroup(uid, pid); 12064 } 12065 } 12066 return; 12067 } 12068 } catch (RemoteException e) { 12069 mController = null; 12070 Watchdog.getInstance().setActivityController(null); 12071 } 12072 } 12073 12074 final long origId = Binder.clearCallingIdentity(); 12075 12076 // If this process is running instrumentation, finish it. 12077 if (r != null && r.instrumentationClass != null) { 12078 Slog.w(TAG, "Error in app " + r.processName 12079 + " running instrumentation " + r.instrumentationClass + ":"); 12080 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12081 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12082 Bundle info = new Bundle(); 12083 info.putString("shortMsg", shortMsg); 12084 info.putString("longMsg", longMsg); 12085 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12086 Binder.restoreCallingIdentity(origId); 12087 return; 12088 } 12089 12090 // If we can't identify the process or it's already exceeded its crash quota, 12091 // quit right away without showing a crash dialog. 12092 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12093 Binder.restoreCallingIdentity(origId); 12094 return; 12095 } 12096 12097 Message msg = Message.obtain(); 12098 msg.what = SHOW_ERROR_MSG; 12099 HashMap data = new HashMap(); 12100 data.put("result", result); 12101 data.put("app", r); 12102 msg.obj = data; 12103 mHandler.sendMessage(msg); 12104 12105 Binder.restoreCallingIdentity(origId); 12106 } 12107 12108 int res = result.get(); 12109 12110 Intent appErrorIntent = null; 12111 synchronized (this) { 12112 if (r != null && !r.isolated) { 12113 // XXX Can't keep track of crash time for isolated processes, 12114 // since they don't have a persistent identity. 12115 mProcessCrashTimes.put(r.info.processName, r.uid, 12116 SystemClock.uptimeMillis()); 12117 } 12118 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12119 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12120 } 12121 } 12122 12123 if (appErrorIntent != null) { 12124 try { 12125 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12126 } catch (ActivityNotFoundException e) { 12127 Slog.w(TAG, "bug report receiver dissappeared", e); 12128 } 12129 } 12130 } 12131 12132 Intent createAppErrorIntentLocked(ProcessRecord r, 12133 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12134 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12135 if (report == null) { 12136 return null; 12137 } 12138 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12139 result.setComponent(r.errorReportReceiver); 12140 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12141 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12142 return result; 12143 } 12144 12145 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12146 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12147 if (r.errorReportReceiver == null) { 12148 return null; 12149 } 12150 12151 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12152 return null; 12153 } 12154 12155 ApplicationErrorReport report = new ApplicationErrorReport(); 12156 report.packageName = r.info.packageName; 12157 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12158 report.processName = r.processName; 12159 report.time = timeMillis; 12160 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12161 12162 if (r.crashing || r.forceCrashReport) { 12163 report.type = ApplicationErrorReport.TYPE_CRASH; 12164 report.crashInfo = crashInfo; 12165 } else if (r.notResponding) { 12166 report.type = ApplicationErrorReport.TYPE_ANR; 12167 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12168 12169 report.anrInfo.activity = r.notRespondingReport.tag; 12170 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12171 report.anrInfo.info = r.notRespondingReport.longMsg; 12172 } 12173 12174 return report; 12175 } 12176 12177 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12178 enforceNotIsolatedCaller("getProcessesInErrorState"); 12179 // assume our apps are happy - lazy create the list 12180 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12181 12182 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12183 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12184 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12185 12186 synchronized (this) { 12187 12188 // iterate across all processes 12189 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12190 ProcessRecord app = mLruProcesses.get(i); 12191 if (!allUsers && app.userId != userId) { 12192 continue; 12193 } 12194 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12195 // This one's in trouble, so we'll generate a report for it 12196 // crashes are higher priority (in case there's a crash *and* an anr) 12197 ActivityManager.ProcessErrorStateInfo report = null; 12198 if (app.crashing) { 12199 report = app.crashingReport; 12200 } else if (app.notResponding) { 12201 report = app.notRespondingReport; 12202 } 12203 12204 if (report != null) { 12205 if (errList == null) { 12206 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12207 } 12208 errList.add(report); 12209 } else { 12210 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12211 " crashing = " + app.crashing + 12212 " notResponding = " + app.notResponding); 12213 } 12214 } 12215 } 12216 } 12217 12218 return errList; 12219 } 12220 12221 static int procStateToImportance(int procState, int memAdj, 12222 ActivityManager.RunningAppProcessInfo currApp) { 12223 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12224 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12225 currApp.lru = memAdj; 12226 } else { 12227 currApp.lru = 0; 12228 } 12229 return imp; 12230 } 12231 12232 private void fillInProcMemInfo(ProcessRecord app, 12233 ActivityManager.RunningAppProcessInfo outInfo) { 12234 outInfo.pid = app.pid; 12235 outInfo.uid = app.info.uid; 12236 if (mHeavyWeightProcess == app) { 12237 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12238 } 12239 if (app.persistent) { 12240 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12241 } 12242 if (app.activities.size() > 0) { 12243 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12244 } 12245 outInfo.lastTrimLevel = app.trimMemoryLevel; 12246 int adj = app.curAdj; 12247 int procState = app.curProcState; 12248 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12249 outInfo.importanceReasonCode = app.adjTypeCode; 12250 outInfo.processState = app.curProcState; 12251 } 12252 12253 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12254 enforceNotIsolatedCaller("getRunningAppProcesses"); 12255 12256 final int callingUid = Binder.getCallingUid(); 12257 12258 // Lazy instantiation of list 12259 List<ActivityManager.RunningAppProcessInfo> runList = null; 12260 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12261 callingUid) == PackageManager.PERMISSION_GRANTED; 12262 final int userId = UserHandle.getUserId(callingUid); 12263 final boolean allUids = isGetTasksAllowed( 12264 "getRunningAppProcesses", Binder.getCallingPid(), callingUid); 12265 12266 synchronized (this) { 12267 // Iterate across all processes 12268 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 12269 ProcessRecord app = mLruProcesses.get(i); 12270 if ((!allUsers && app.userId != userId) 12271 || (!allUids && app.uid != callingUid)) { 12272 continue; 12273 } 12274 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12275 // Generate process state info for running application 12276 ActivityManager.RunningAppProcessInfo currApp = 12277 new ActivityManager.RunningAppProcessInfo(app.processName, 12278 app.pid, app.getPackageList()); 12279 fillInProcMemInfo(app, currApp); 12280 if (app.adjSource instanceof ProcessRecord) { 12281 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12282 currApp.importanceReasonImportance = 12283 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12284 app.adjSourceProcState); 12285 } else if (app.adjSource instanceof ActivityRecord) { 12286 ActivityRecord r = (ActivityRecord)app.adjSource; 12287 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12288 } 12289 if (app.adjTarget instanceof ComponentName) { 12290 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12291 } 12292 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12293 // + " lru=" + currApp.lru); 12294 if (runList == null) { 12295 runList = new ArrayList<>(); 12296 } 12297 runList.add(currApp); 12298 } 12299 } 12300 } 12301 return runList; 12302 } 12303 12304 public List<ApplicationInfo> getRunningExternalApplications() { 12305 enforceNotIsolatedCaller("getRunningExternalApplications"); 12306 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12307 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12308 if (runningApps != null && runningApps.size() > 0) { 12309 Set<String> extList = new HashSet<String>(); 12310 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12311 if (app.pkgList != null) { 12312 for (String pkg : app.pkgList) { 12313 extList.add(pkg); 12314 } 12315 } 12316 } 12317 IPackageManager pm = AppGlobals.getPackageManager(); 12318 for (String pkg : extList) { 12319 try { 12320 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12321 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12322 retList.add(info); 12323 } 12324 } catch (RemoteException e) { 12325 } 12326 } 12327 } 12328 return retList; 12329 } 12330 12331 @Override 12332 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12333 enforceNotIsolatedCaller("getMyMemoryState"); 12334 synchronized (this) { 12335 ProcessRecord proc; 12336 synchronized (mPidsSelfLocked) { 12337 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12338 } 12339 fillInProcMemInfo(proc, outInfo); 12340 } 12341 } 12342 12343 @Override 12344 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12345 if (checkCallingPermission(android.Manifest.permission.DUMP) 12346 != PackageManager.PERMISSION_GRANTED) { 12347 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12348 + Binder.getCallingPid() 12349 + ", uid=" + Binder.getCallingUid() 12350 + " without permission " 12351 + android.Manifest.permission.DUMP); 12352 return; 12353 } 12354 12355 boolean dumpAll = false; 12356 boolean dumpClient = false; 12357 String dumpPackage = null; 12358 12359 int opti = 0; 12360 while (opti < args.length) { 12361 String opt = args[opti]; 12362 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12363 break; 12364 } 12365 opti++; 12366 if ("-a".equals(opt)) { 12367 dumpAll = true; 12368 } else if ("-c".equals(opt)) { 12369 dumpClient = true; 12370 } else if ("-h".equals(opt)) { 12371 pw.println("Activity manager dump options:"); 12372 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12373 pw.println(" cmd may be one of:"); 12374 pw.println(" a[ctivities]: activity stack state"); 12375 pw.println(" r[recents]: recent activities state"); 12376 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12377 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12378 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12379 pw.println(" o[om]: out of memory management"); 12380 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12381 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12382 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12383 pw.println(" service [COMP_SPEC]: service client-side state"); 12384 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12385 pw.println(" all: dump all activities"); 12386 pw.println(" top: dump the top activity"); 12387 pw.println(" write: write all pending state to storage"); 12388 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12389 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12390 pw.println(" a partial substring in a component name, a"); 12391 pw.println(" hex object identifier."); 12392 pw.println(" -a: include all available server state."); 12393 pw.println(" -c: include client state."); 12394 return; 12395 } else { 12396 pw.println("Unknown argument: " + opt + "; use -h for help"); 12397 } 12398 } 12399 12400 long origId = Binder.clearCallingIdentity(); 12401 boolean more = false; 12402 // Is the caller requesting to dump a particular piece of data? 12403 if (opti < args.length) { 12404 String cmd = args[opti]; 12405 opti++; 12406 if ("activities".equals(cmd) || "a".equals(cmd)) { 12407 synchronized (this) { 12408 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12409 } 12410 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12411 synchronized (this) { 12412 dumpRecentsLocked(fd, pw, args, opti, true, null); 12413 } 12414 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12415 String[] newArgs; 12416 String name; 12417 if (opti >= args.length) { 12418 name = null; 12419 newArgs = EMPTY_STRING_ARRAY; 12420 } else { 12421 name = args[opti]; 12422 opti++; 12423 newArgs = new String[args.length - opti]; 12424 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12425 args.length - opti); 12426 } 12427 synchronized (this) { 12428 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12429 } 12430 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12431 String[] newArgs; 12432 String name; 12433 if (opti >= args.length) { 12434 name = null; 12435 newArgs = EMPTY_STRING_ARRAY; 12436 } else { 12437 name = args[opti]; 12438 opti++; 12439 newArgs = new String[args.length - opti]; 12440 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12441 args.length - opti); 12442 } 12443 synchronized (this) { 12444 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12445 } 12446 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12447 String[] newArgs; 12448 String name; 12449 if (opti >= args.length) { 12450 name = null; 12451 newArgs = EMPTY_STRING_ARRAY; 12452 } else { 12453 name = args[opti]; 12454 opti++; 12455 newArgs = new String[args.length - opti]; 12456 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12457 args.length - opti); 12458 } 12459 synchronized (this) { 12460 dumpProcessesLocked(fd, pw, args, opti, true, name); 12461 } 12462 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12463 synchronized (this) { 12464 dumpOomLocked(fd, pw, args, opti, true); 12465 } 12466 } else if ("provider".equals(cmd)) { 12467 String[] newArgs; 12468 String name; 12469 if (opti >= args.length) { 12470 name = null; 12471 newArgs = EMPTY_STRING_ARRAY; 12472 } else { 12473 name = args[opti]; 12474 opti++; 12475 newArgs = new String[args.length - opti]; 12476 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12477 } 12478 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12479 pw.println("No providers match: " + name); 12480 pw.println("Use -h for help."); 12481 } 12482 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12483 synchronized (this) { 12484 dumpProvidersLocked(fd, pw, args, opti, true, null); 12485 } 12486 } else if ("service".equals(cmd)) { 12487 String[] newArgs; 12488 String name; 12489 if (opti >= args.length) { 12490 name = null; 12491 newArgs = EMPTY_STRING_ARRAY; 12492 } else { 12493 name = args[opti]; 12494 opti++; 12495 newArgs = new String[args.length - opti]; 12496 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12497 args.length - opti); 12498 } 12499 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12500 pw.println("No services match: " + name); 12501 pw.println("Use -h for help."); 12502 } 12503 } else if ("package".equals(cmd)) { 12504 String[] newArgs; 12505 if (opti >= args.length) { 12506 pw.println("package: no package name specified"); 12507 pw.println("Use -h for help."); 12508 } else { 12509 dumpPackage = args[opti]; 12510 opti++; 12511 newArgs = new String[args.length - opti]; 12512 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12513 args.length - opti); 12514 args = newArgs; 12515 opti = 0; 12516 more = true; 12517 } 12518 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12519 synchronized (this) { 12520 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12521 } 12522 } else if ("write".equals(cmd)) { 12523 mTaskPersister.flush(); 12524 pw.println("All tasks persisted."); 12525 return; 12526 } else { 12527 // Dumping a single activity? 12528 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12529 pw.println("Bad activity command, or no activities match: " + cmd); 12530 pw.println("Use -h for help."); 12531 } 12532 } 12533 if (!more) { 12534 Binder.restoreCallingIdentity(origId); 12535 return; 12536 } 12537 } 12538 12539 // No piece of data specified, dump everything. 12540 synchronized (this) { 12541 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12542 pw.println(); 12543 if (dumpAll) { 12544 pw.println("-------------------------------------------------------------------------------"); 12545 } 12546 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12547 pw.println(); 12548 if (dumpAll) { 12549 pw.println("-------------------------------------------------------------------------------"); 12550 } 12551 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12552 pw.println(); 12553 if (dumpAll) { 12554 pw.println("-------------------------------------------------------------------------------"); 12555 } 12556 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12557 pw.println(); 12558 if (dumpAll) { 12559 pw.println("-------------------------------------------------------------------------------"); 12560 } 12561 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12562 pw.println(); 12563 if (dumpAll) { 12564 pw.println("-------------------------------------------------------------------------------"); 12565 } 12566 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12567 pw.println(); 12568 if (dumpAll) { 12569 pw.println("-------------------------------------------------------------------------------"); 12570 } 12571 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12572 } 12573 Binder.restoreCallingIdentity(origId); 12574 } 12575 12576 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12577 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12578 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12579 12580 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12581 dumpPackage); 12582 boolean needSep = printedAnything; 12583 12584 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12585 dumpPackage, needSep, " mFocusedActivity: "); 12586 if (printed) { 12587 printedAnything = true; 12588 needSep = false; 12589 } 12590 12591 if (dumpPackage == null) { 12592 if (needSep) { 12593 pw.println(); 12594 } 12595 needSep = true; 12596 printedAnything = true; 12597 mStackSupervisor.dump(pw, " "); 12598 } 12599 12600 if (!printedAnything) { 12601 pw.println(" (nothing)"); 12602 } 12603 } 12604 12605 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12606 int opti, boolean dumpAll, String dumpPackage) { 12607 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12608 12609 boolean printedAnything = false; 12610 12611 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12612 boolean printedHeader = false; 12613 12614 final int N = mRecentTasks.size(); 12615 for (int i=0; i<N; i++) { 12616 TaskRecord tr = mRecentTasks.get(i); 12617 if (dumpPackage != null) { 12618 if (tr.realActivity == null || 12619 !dumpPackage.equals(tr.realActivity)) { 12620 continue; 12621 } 12622 } 12623 if (!printedHeader) { 12624 pw.println(" Recent tasks:"); 12625 printedHeader = true; 12626 printedAnything = true; 12627 } 12628 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12629 pw.println(tr); 12630 if (dumpAll) { 12631 mRecentTasks.get(i).dump(pw, " "); 12632 } 12633 } 12634 } 12635 12636 if (!printedAnything) { 12637 pw.println(" (nothing)"); 12638 } 12639 } 12640 12641 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12642 int opti, boolean dumpAll, String dumpPackage) { 12643 boolean needSep = false; 12644 boolean printedAnything = false; 12645 int numPers = 0; 12646 12647 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12648 12649 if (dumpAll) { 12650 final int NP = mProcessNames.getMap().size(); 12651 for (int ip=0; ip<NP; ip++) { 12652 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12653 final int NA = procs.size(); 12654 for (int ia=0; ia<NA; ia++) { 12655 ProcessRecord r = procs.valueAt(ia); 12656 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12657 continue; 12658 } 12659 if (!needSep) { 12660 pw.println(" All known processes:"); 12661 needSep = true; 12662 printedAnything = true; 12663 } 12664 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12665 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12666 pw.print(" "); pw.println(r); 12667 r.dump(pw, " "); 12668 if (r.persistent) { 12669 numPers++; 12670 } 12671 } 12672 } 12673 } 12674 12675 if (mIsolatedProcesses.size() > 0) { 12676 boolean printed = false; 12677 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12678 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12679 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12680 continue; 12681 } 12682 if (!printed) { 12683 if (needSep) { 12684 pw.println(); 12685 } 12686 pw.println(" Isolated process list (sorted by uid):"); 12687 printedAnything = true; 12688 printed = true; 12689 needSep = true; 12690 } 12691 pw.println(String.format("%sIsolated #%2d: %s", 12692 " ", i, r.toString())); 12693 } 12694 } 12695 12696 if (mLruProcesses.size() > 0) { 12697 if (needSep) { 12698 pw.println(); 12699 } 12700 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12701 pw.print(" total, non-act at "); 12702 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12703 pw.print(", non-svc at "); 12704 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12705 pw.println("):"); 12706 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12707 needSep = true; 12708 printedAnything = true; 12709 } 12710 12711 if (dumpAll || dumpPackage != null) { 12712 synchronized (mPidsSelfLocked) { 12713 boolean printed = false; 12714 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12715 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12716 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12717 continue; 12718 } 12719 if (!printed) { 12720 if (needSep) pw.println(); 12721 needSep = true; 12722 pw.println(" PID mappings:"); 12723 printed = true; 12724 printedAnything = true; 12725 } 12726 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12727 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12728 } 12729 } 12730 } 12731 12732 if (mForegroundProcesses.size() > 0) { 12733 synchronized (mPidsSelfLocked) { 12734 boolean printed = false; 12735 for (int i=0; i<mForegroundProcesses.size(); i++) { 12736 ProcessRecord r = mPidsSelfLocked.get( 12737 mForegroundProcesses.valueAt(i).pid); 12738 if (dumpPackage != null && (r == null 12739 || !r.pkgList.containsKey(dumpPackage))) { 12740 continue; 12741 } 12742 if (!printed) { 12743 if (needSep) pw.println(); 12744 needSep = true; 12745 pw.println(" Foreground Processes:"); 12746 printed = true; 12747 printedAnything = true; 12748 } 12749 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12750 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12751 } 12752 } 12753 } 12754 12755 if (mPersistentStartingProcesses.size() > 0) { 12756 if (needSep) pw.println(); 12757 needSep = true; 12758 printedAnything = true; 12759 pw.println(" Persisent processes that are starting:"); 12760 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12761 "Starting Norm", "Restarting PERS", dumpPackage); 12762 } 12763 12764 if (mRemovedProcesses.size() > 0) { 12765 if (needSep) pw.println(); 12766 needSep = true; 12767 printedAnything = true; 12768 pw.println(" Processes that are being removed:"); 12769 dumpProcessList(pw, this, mRemovedProcesses, " ", 12770 "Removed Norm", "Removed PERS", dumpPackage); 12771 } 12772 12773 if (mProcessesOnHold.size() > 0) { 12774 if (needSep) pw.println(); 12775 needSep = true; 12776 printedAnything = true; 12777 pw.println(" Processes that are on old until the system is ready:"); 12778 dumpProcessList(pw, this, mProcessesOnHold, " ", 12779 "OnHold Norm", "OnHold PERS", dumpPackage); 12780 } 12781 12782 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12783 12784 if (mProcessCrashTimes.getMap().size() > 0) { 12785 boolean printed = false; 12786 long now = SystemClock.uptimeMillis(); 12787 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12788 final int NP = pmap.size(); 12789 for (int ip=0; ip<NP; ip++) { 12790 String pname = pmap.keyAt(ip); 12791 SparseArray<Long> uids = pmap.valueAt(ip); 12792 final int N = uids.size(); 12793 for (int i=0; i<N; i++) { 12794 int puid = uids.keyAt(i); 12795 ProcessRecord r = mProcessNames.get(pname, puid); 12796 if (dumpPackage != null && (r == null 12797 || !r.pkgList.containsKey(dumpPackage))) { 12798 continue; 12799 } 12800 if (!printed) { 12801 if (needSep) pw.println(); 12802 needSep = true; 12803 pw.println(" Time since processes crashed:"); 12804 printed = true; 12805 printedAnything = true; 12806 } 12807 pw.print(" Process "); pw.print(pname); 12808 pw.print(" uid "); pw.print(puid); 12809 pw.print(": last crashed "); 12810 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12811 pw.println(" ago"); 12812 } 12813 } 12814 } 12815 12816 if (mBadProcesses.getMap().size() > 0) { 12817 boolean printed = false; 12818 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12819 final int NP = pmap.size(); 12820 for (int ip=0; ip<NP; ip++) { 12821 String pname = pmap.keyAt(ip); 12822 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12823 final int N = uids.size(); 12824 for (int i=0; i<N; i++) { 12825 int puid = uids.keyAt(i); 12826 ProcessRecord r = mProcessNames.get(pname, puid); 12827 if (dumpPackage != null && (r == null 12828 || !r.pkgList.containsKey(dumpPackage))) { 12829 continue; 12830 } 12831 if (!printed) { 12832 if (needSep) pw.println(); 12833 needSep = true; 12834 pw.println(" Bad processes:"); 12835 printedAnything = true; 12836 } 12837 BadProcessInfo info = uids.valueAt(i); 12838 pw.print(" Bad process "); pw.print(pname); 12839 pw.print(" uid "); pw.print(puid); 12840 pw.print(": crashed at time "); pw.println(info.time); 12841 if (info.shortMsg != null) { 12842 pw.print(" Short msg: "); pw.println(info.shortMsg); 12843 } 12844 if (info.longMsg != null) { 12845 pw.print(" Long msg: "); pw.println(info.longMsg); 12846 } 12847 if (info.stack != null) { 12848 pw.println(" Stack:"); 12849 int lastPos = 0; 12850 for (int pos=0; pos<info.stack.length(); pos++) { 12851 if (info.stack.charAt(pos) == '\n') { 12852 pw.print(" "); 12853 pw.write(info.stack, lastPos, pos-lastPos); 12854 pw.println(); 12855 lastPos = pos+1; 12856 } 12857 } 12858 if (lastPos < info.stack.length()) { 12859 pw.print(" "); 12860 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12861 pw.println(); 12862 } 12863 } 12864 } 12865 } 12866 } 12867 12868 if (dumpPackage == null) { 12869 pw.println(); 12870 needSep = false; 12871 pw.println(" mStartedUsers:"); 12872 for (int i=0; i<mStartedUsers.size(); i++) { 12873 UserStartedState uss = mStartedUsers.valueAt(i); 12874 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12875 pw.print(": "); uss.dump("", pw); 12876 } 12877 pw.print(" mStartedUserArray: ["); 12878 for (int i=0; i<mStartedUserArray.length; i++) { 12879 if (i > 0) pw.print(", "); 12880 pw.print(mStartedUserArray[i]); 12881 } 12882 pw.println("]"); 12883 pw.print(" mUserLru: ["); 12884 for (int i=0; i<mUserLru.size(); i++) { 12885 if (i > 0) pw.print(", "); 12886 pw.print(mUserLru.get(i)); 12887 } 12888 pw.println("]"); 12889 if (dumpAll) { 12890 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12891 } 12892 synchronized (mUserProfileGroupIdsSelfLocked) { 12893 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12894 pw.println(" mUserProfileGroupIds:"); 12895 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12896 pw.print(" User #"); 12897 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12898 pw.print(" -> profile #"); 12899 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12900 } 12901 } 12902 } 12903 } 12904 if (mHomeProcess != null && (dumpPackage == null 12905 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12906 if (needSep) { 12907 pw.println(); 12908 needSep = false; 12909 } 12910 pw.println(" mHomeProcess: " + mHomeProcess); 12911 } 12912 if (mPreviousProcess != null && (dumpPackage == null 12913 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12914 if (needSep) { 12915 pw.println(); 12916 needSep = false; 12917 } 12918 pw.println(" mPreviousProcess: " + mPreviousProcess); 12919 } 12920 if (dumpAll) { 12921 StringBuilder sb = new StringBuilder(128); 12922 sb.append(" mPreviousProcessVisibleTime: "); 12923 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12924 pw.println(sb); 12925 } 12926 if (mHeavyWeightProcess != null && (dumpPackage == null 12927 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12928 if (needSep) { 12929 pw.println(); 12930 needSep = false; 12931 } 12932 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12933 } 12934 if (dumpPackage == null) { 12935 pw.println(" mConfiguration: " + mConfiguration); 12936 } 12937 if (dumpAll) { 12938 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12939 if (mCompatModePackages.getPackages().size() > 0) { 12940 boolean printed = false; 12941 for (Map.Entry<String, Integer> entry 12942 : mCompatModePackages.getPackages().entrySet()) { 12943 String pkg = entry.getKey(); 12944 int mode = entry.getValue(); 12945 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12946 continue; 12947 } 12948 if (!printed) { 12949 pw.println(" mScreenCompatPackages:"); 12950 printed = true; 12951 } 12952 pw.print(" "); pw.print(pkg); pw.print(": "); 12953 pw.print(mode); pw.println(); 12954 } 12955 } 12956 } 12957 if (dumpPackage == null) { 12958 if (mSleeping || mWentToSleep || mLockScreenShown) { 12959 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12960 + " mLockScreenShown " + mLockScreenShown); 12961 } 12962 if (mShuttingDown || mRunningVoice) { 12963 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12964 } 12965 } 12966 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12967 || mOrigWaitForDebugger) { 12968 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12969 || dumpPackage.equals(mOrigDebugApp)) { 12970 if (needSep) { 12971 pw.println(); 12972 needSep = false; 12973 } 12974 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12975 + " mDebugTransient=" + mDebugTransient 12976 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12977 } 12978 } 12979 if (mOpenGlTraceApp != null) { 12980 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12981 if (needSep) { 12982 pw.println(); 12983 needSep = false; 12984 } 12985 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12986 } 12987 } 12988 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12989 || mProfileFd != null) { 12990 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12991 if (needSep) { 12992 pw.println(); 12993 needSep = false; 12994 } 12995 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12996 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12997 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12998 + mAutoStopProfiler); 12999 pw.println(" mProfileType=" + mProfileType); 13000 } 13001 } 13002 if (dumpPackage == null) { 13003 if (mAlwaysFinishActivities || mController != null) { 13004 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13005 + " mController=" + mController); 13006 } 13007 if (dumpAll) { 13008 pw.println(" Total persistent processes: " + numPers); 13009 pw.println(" mProcessesReady=" + mProcessesReady 13010 + " mSystemReady=" + mSystemReady 13011 + " mBooted=" + mBooted 13012 + " mFactoryTest=" + mFactoryTest); 13013 pw.println(" mBooting=" + mBooting 13014 + " mCallFinishBooting=" + mCallFinishBooting 13015 + " mBootAnimationComplete=" + mBootAnimationComplete); 13016 pw.print(" mLastPowerCheckRealtime="); 13017 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13018 pw.println(""); 13019 pw.print(" mLastPowerCheckUptime="); 13020 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13021 pw.println(""); 13022 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13023 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13024 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13025 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13026 + " (" + mLruProcesses.size() + " total)" 13027 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13028 + " mNumServiceProcs=" + mNumServiceProcs 13029 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13030 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13031 + " mLastMemoryLevel" + mLastMemoryLevel 13032 + " mLastNumProcesses" + mLastNumProcesses); 13033 long now = SystemClock.uptimeMillis(); 13034 pw.print(" mLastIdleTime="); 13035 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13036 pw.print(" mLowRamSinceLastIdle="); 13037 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13038 pw.println(); 13039 } 13040 } 13041 13042 if (!printedAnything) { 13043 pw.println(" (nothing)"); 13044 } 13045 } 13046 13047 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13048 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13049 if (mProcessesToGc.size() > 0) { 13050 boolean printed = false; 13051 long now = SystemClock.uptimeMillis(); 13052 for (int i=0; i<mProcessesToGc.size(); i++) { 13053 ProcessRecord proc = mProcessesToGc.get(i); 13054 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13055 continue; 13056 } 13057 if (!printed) { 13058 if (needSep) pw.println(); 13059 needSep = true; 13060 pw.println(" Processes that are waiting to GC:"); 13061 printed = true; 13062 } 13063 pw.print(" Process "); pw.println(proc); 13064 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13065 pw.print(", last gced="); 13066 pw.print(now-proc.lastRequestedGc); 13067 pw.print(" ms ago, last lowMem="); 13068 pw.print(now-proc.lastLowMemory); 13069 pw.println(" ms ago"); 13070 13071 } 13072 } 13073 return needSep; 13074 } 13075 13076 void printOomLevel(PrintWriter pw, String name, int adj) { 13077 pw.print(" "); 13078 if (adj >= 0) { 13079 pw.print(' '); 13080 if (adj < 10) pw.print(' '); 13081 } else { 13082 if (adj > -10) pw.print(' '); 13083 } 13084 pw.print(adj); 13085 pw.print(": "); 13086 pw.print(name); 13087 pw.print(" ("); 13088 pw.print(mProcessList.getMemLevel(adj)/1024); 13089 pw.println(" kB)"); 13090 } 13091 13092 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13093 int opti, boolean dumpAll) { 13094 boolean needSep = false; 13095 13096 if (mLruProcesses.size() > 0) { 13097 if (needSep) pw.println(); 13098 needSep = true; 13099 pw.println(" OOM levels:"); 13100 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13101 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13102 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13103 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13104 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13105 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13106 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13107 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13108 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13109 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13110 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13111 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13112 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13113 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13114 13115 if (needSep) pw.println(); 13116 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13117 pw.print(" total, non-act at "); 13118 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13119 pw.print(", non-svc at "); 13120 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13121 pw.println("):"); 13122 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13123 needSep = true; 13124 } 13125 13126 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13127 13128 pw.println(); 13129 pw.println(" mHomeProcess: " + mHomeProcess); 13130 pw.println(" mPreviousProcess: " + mPreviousProcess); 13131 if (mHeavyWeightProcess != null) { 13132 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13133 } 13134 13135 return true; 13136 } 13137 13138 /** 13139 * There are three ways to call this: 13140 * - no provider specified: dump all the providers 13141 * - a flattened component name that matched an existing provider was specified as the 13142 * first arg: dump that one provider 13143 * - the first arg isn't the flattened component name of an existing provider: 13144 * dump all providers whose component contains the first arg as a substring 13145 */ 13146 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13147 int opti, boolean dumpAll) { 13148 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13149 } 13150 13151 static class ItemMatcher { 13152 ArrayList<ComponentName> components; 13153 ArrayList<String> strings; 13154 ArrayList<Integer> objects; 13155 boolean all; 13156 13157 ItemMatcher() { 13158 all = true; 13159 } 13160 13161 void build(String name) { 13162 ComponentName componentName = ComponentName.unflattenFromString(name); 13163 if (componentName != null) { 13164 if (components == null) { 13165 components = new ArrayList<ComponentName>(); 13166 } 13167 components.add(componentName); 13168 all = false; 13169 } else { 13170 int objectId = 0; 13171 // Not a '/' separated full component name; maybe an object ID? 13172 try { 13173 objectId = Integer.parseInt(name, 16); 13174 if (objects == null) { 13175 objects = new ArrayList<Integer>(); 13176 } 13177 objects.add(objectId); 13178 all = false; 13179 } catch (RuntimeException e) { 13180 // Not an integer; just do string match. 13181 if (strings == null) { 13182 strings = new ArrayList<String>(); 13183 } 13184 strings.add(name); 13185 all = false; 13186 } 13187 } 13188 } 13189 13190 int build(String[] args, int opti) { 13191 for (; opti<args.length; opti++) { 13192 String name = args[opti]; 13193 if ("--".equals(name)) { 13194 return opti+1; 13195 } 13196 build(name); 13197 } 13198 return opti; 13199 } 13200 13201 boolean match(Object object, ComponentName comp) { 13202 if (all) { 13203 return true; 13204 } 13205 if (components != null) { 13206 for (int i=0; i<components.size(); i++) { 13207 if (components.get(i).equals(comp)) { 13208 return true; 13209 } 13210 } 13211 } 13212 if (objects != null) { 13213 for (int i=0; i<objects.size(); i++) { 13214 if (System.identityHashCode(object) == objects.get(i)) { 13215 return true; 13216 } 13217 } 13218 } 13219 if (strings != null) { 13220 String flat = comp.flattenToString(); 13221 for (int i=0; i<strings.size(); i++) { 13222 if (flat.contains(strings.get(i))) { 13223 return true; 13224 } 13225 } 13226 } 13227 return false; 13228 } 13229 } 13230 13231 /** 13232 * There are three things that cmd can be: 13233 * - a flattened component name that matches an existing activity 13234 * - the cmd arg isn't the flattened component name of an existing activity: 13235 * dump all activity whose component contains the cmd as a substring 13236 * - A hex number of the ActivityRecord object instance. 13237 */ 13238 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13239 int opti, boolean dumpAll) { 13240 ArrayList<ActivityRecord> activities; 13241 13242 synchronized (this) { 13243 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13244 } 13245 13246 if (activities.size() <= 0) { 13247 return false; 13248 } 13249 13250 String[] newArgs = new String[args.length - opti]; 13251 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13252 13253 TaskRecord lastTask = null; 13254 boolean needSep = false; 13255 for (int i=activities.size()-1; i>=0; i--) { 13256 ActivityRecord r = activities.get(i); 13257 if (needSep) { 13258 pw.println(); 13259 } 13260 needSep = true; 13261 synchronized (this) { 13262 if (lastTask != r.task) { 13263 lastTask = r.task; 13264 pw.print("TASK "); pw.print(lastTask.affinity); 13265 pw.print(" id="); pw.println(lastTask.taskId); 13266 if (dumpAll) { 13267 lastTask.dump(pw, " "); 13268 } 13269 } 13270 } 13271 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13272 } 13273 return true; 13274 } 13275 13276 /** 13277 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13278 * there is a thread associated with the activity. 13279 */ 13280 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13281 final ActivityRecord r, String[] args, boolean dumpAll) { 13282 String innerPrefix = prefix + " "; 13283 synchronized (this) { 13284 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13285 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13286 pw.print(" pid="); 13287 if (r.app != null) pw.println(r.app.pid); 13288 else pw.println("(not running)"); 13289 if (dumpAll) { 13290 r.dump(pw, innerPrefix); 13291 } 13292 } 13293 if (r.app != null && r.app.thread != null) { 13294 // flush anything that is already in the PrintWriter since the thread is going 13295 // to write to the file descriptor directly 13296 pw.flush(); 13297 try { 13298 TransferPipe tp = new TransferPipe(); 13299 try { 13300 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13301 r.appToken, innerPrefix, args); 13302 tp.go(fd); 13303 } finally { 13304 tp.kill(); 13305 } 13306 } catch (IOException e) { 13307 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13308 } catch (RemoteException e) { 13309 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13310 } 13311 } 13312 } 13313 13314 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13315 int opti, boolean dumpAll, String dumpPackage) { 13316 boolean needSep = false; 13317 boolean onlyHistory = false; 13318 boolean printedAnything = false; 13319 13320 if ("history".equals(dumpPackage)) { 13321 if (opti < args.length && "-s".equals(args[opti])) { 13322 dumpAll = false; 13323 } 13324 onlyHistory = true; 13325 dumpPackage = null; 13326 } 13327 13328 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13329 if (!onlyHistory && dumpAll) { 13330 if (mRegisteredReceivers.size() > 0) { 13331 boolean printed = false; 13332 Iterator it = mRegisteredReceivers.values().iterator(); 13333 while (it.hasNext()) { 13334 ReceiverList r = (ReceiverList)it.next(); 13335 if (dumpPackage != null && (r.app == null || 13336 !dumpPackage.equals(r.app.info.packageName))) { 13337 continue; 13338 } 13339 if (!printed) { 13340 pw.println(" Registered Receivers:"); 13341 needSep = true; 13342 printed = true; 13343 printedAnything = true; 13344 } 13345 pw.print(" * "); pw.println(r); 13346 r.dump(pw, " "); 13347 } 13348 } 13349 13350 if (mReceiverResolver.dump(pw, needSep ? 13351 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13352 " ", dumpPackage, false)) { 13353 needSep = true; 13354 printedAnything = true; 13355 } 13356 } 13357 13358 for (BroadcastQueue q : mBroadcastQueues) { 13359 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13360 printedAnything |= needSep; 13361 } 13362 13363 needSep = true; 13364 13365 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13366 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13367 if (needSep) { 13368 pw.println(); 13369 } 13370 needSep = true; 13371 printedAnything = true; 13372 pw.print(" Sticky broadcasts for user "); 13373 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13374 StringBuilder sb = new StringBuilder(128); 13375 for (Map.Entry<String, ArrayList<Intent>> ent 13376 : mStickyBroadcasts.valueAt(user).entrySet()) { 13377 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13378 if (dumpAll) { 13379 pw.println(":"); 13380 ArrayList<Intent> intents = ent.getValue(); 13381 final int N = intents.size(); 13382 for (int i=0; i<N; i++) { 13383 sb.setLength(0); 13384 sb.append(" Intent: "); 13385 intents.get(i).toShortString(sb, false, true, false, false); 13386 pw.println(sb.toString()); 13387 Bundle bundle = intents.get(i).getExtras(); 13388 if (bundle != null) { 13389 pw.print(" "); 13390 pw.println(bundle.toString()); 13391 } 13392 } 13393 } else { 13394 pw.println(""); 13395 } 13396 } 13397 } 13398 } 13399 13400 if (!onlyHistory && dumpAll) { 13401 pw.println(); 13402 for (BroadcastQueue queue : mBroadcastQueues) { 13403 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13404 + queue.mBroadcastsScheduled); 13405 } 13406 pw.println(" mHandler:"); 13407 mHandler.dump(new PrintWriterPrinter(pw), " "); 13408 needSep = true; 13409 printedAnything = true; 13410 } 13411 13412 if (!printedAnything) { 13413 pw.println(" (nothing)"); 13414 } 13415 } 13416 13417 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13418 int opti, boolean dumpAll, String dumpPackage) { 13419 boolean needSep; 13420 boolean printedAnything = false; 13421 13422 ItemMatcher matcher = new ItemMatcher(); 13423 matcher.build(args, opti); 13424 13425 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13426 13427 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13428 printedAnything |= needSep; 13429 13430 if (mLaunchingProviders.size() > 0) { 13431 boolean printed = false; 13432 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13433 ContentProviderRecord r = mLaunchingProviders.get(i); 13434 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13435 continue; 13436 } 13437 if (!printed) { 13438 if (needSep) pw.println(); 13439 needSep = true; 13440 pw.println(" Launching content providers:"); 13441 printed = true; 13442 printedAnything = true; 13443 } 13444 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13445 pw.println(r); 13446 } 13447 } 13448 13449 if (mGrantedUriPermissions.size() > 0) { 13450 boolean printed = false; 13451 int dumpUid = -2; 13452 if (dumpPackage != null) { 13453 try { 13454 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13455 } catch (NameNotFoundException e) { 13456 dumpUid = -1; 13457 } 13458 } 13459 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13460 int uid = mGrantedUriPermissions.keyAt(i); 13461 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13462 continue; 13463 } 13464 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13465 if (!printed) { 13466 if (needSep) pw.println(); 13467 needSep = true; 13468 pw.println(" Granted Uri Permissions:"); 13469 printed = true; 13470 printedAnything = true; 13471 } 13472 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13473 for (UriPermission perm : perms.values()) { 13474 pw.print(" "); pw.println(perm); 13475 if (dumpAll) { 13476 perm.dump(pw, " "); 13477 } 13478 } 13479 } 13480 } 13481 13482 if (!printedAnything) { 13483 pw.println(" (nothing)"); 13484 } 13485 } 13486 13487 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13488 int opti, boolean dumpAll, String dumpPackage) { 13489 boolean printed = false; 13490 13491 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13492 13493 if (mIntentSenderRecords.size() > 0) { 13494 Iterator<WeakReference<PendingIntentRecord>> it 13495 = mIntentSenderRecords.values().iterator(); 13496 while (it.hasNext()) { 13497 WeakReference<PendingIntentRecord> ref = it.next(); 13498 PendingIntentRecord rec = ref != null ? ref.get(): null; 13499 if (dumpPackage != null && (rec == null 13500 || !dumpPackage.equals(rec.key.packageName))) { 13501 continue; 13502 } 13503 printed = true; 13504 if (rec != null) { 13505 pw.print(" * "); pw.println(rec); 13506 if (dumpAll) { 13507 rec.dump(pw, " "); 13508 } 13509 } else { 13510 pw.print(" * "); pw.println(ref); 13511 } 13512 } 13513 } 13514 13515 if (!printed) { 13516 pw.println(" (nothing)"); 13517 } 13518 } 13519 13520 private static final int dumpProcessList(PrintWriter pw, 13521 ActivityManagerService service, List list, 13522 String prefix, String normalLabel, String persistentLabel, 13523 String dumpPackage) { 13524 int numPers = 0; 13525 final int N = list.size()-1; 13526 for (int i=N; i>=0; i--) { 13527 ProcessRecord r = (ProcessRecord)list.get(i); 13528 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13529 continue; 13530 } 13531 pw.println(String.format("%s%s #%2d: %s", 13532 prefix, (r.persistent ? persistentLabel : normalLabel), 13533 i, r.toString())); 13534 if (r.persistent) { 13535 numPers++; 13536 } 13537 } 13538 return numPers; 13539 } 13540 13541 private static final boolean dumpProcessOomList(PrintWriter pw, 13542 ActivityManagerService service, List<ProcessRecord> origList, 13543 String prefix, String normalLabel, String persistentLabel, 13544 boolean inclDetails, String dumpPackage) { 13545 13546 ArrayList<Pair<ProcessRecord, Integer>> list 13547 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13548 for (int i=0; i<origList.size(); i++) { 13549 ProcessRecord r = origList.get(i); 13550 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13551 continue; 13552 } 13553 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13554 } 13555 13556 if (list.size() <= 0) { 13557 return false; 13558 } 13559 13560 Comparator<Pair<ProcessRecord, Integer>> comparator 13561 = new Comparator<Pair<ProcessRecord, Integer>>() { 13562 @Override 13563 public int compare(Pair<ProcessRecord, Integer> object1, 13564 Pair<ProcessRecord, Integer> object2) { 13565 if (object1.first.setAdj != object2.first.setAdj) { 13566 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13567 } 13568 if (object1.second.intValue() != object2.second.intValue()) { 13569 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13570 } 13571 return 0; 13572 } 13573 }; 13574 13575 Collections.sort(list, comparator); 13576 13577 final long curRealtime = SystemClock.elapsedRealtime(); 13578 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13579 final long curUptime = SystemClock.uptimeMillis(); 13580 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13581 13582 for (int i=list.size()-1; i>=0; i--) { 13583 ProcessRecord r = list.get(i).first; 13584 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13585 char schedGroup; 13586 switch (r.setSchedGroup) { 13587 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13588 schedGroup = 'B'; 13589 break; 13590 case Process.THREAD_GROUP_DEFAULT: 13591 schedGroup = 'F'; 13592 break; 13593 default: 13594 schedGroup = '?'; 13595 break; 13596 } 13597 char foreground; 13598 if (r.foregroundActivities) { 13599 foreground = 'A'; 13600 } else if (r.foregroundServices) { 13601 foreground = 'S'; 13602 } else { 13603 foreground = ' '; 13604 } 13605 String procState = ProcessList.makeProcStateString(r.curProcState); 13606 pw.print(prefix); 13607 pw.print(r.persistent ? persistentLabel : normalLabel); 13608 pw.print(" #"); 13609 int num = (origList.size()-1)-list.get(i).second; 13610 if (num < 10) pw.print(' '); 13611 pw.print(num); 13612 pw.print(": "); 13613 pw.print(oomAdj); 13614 pw.print(' '); 13615 pw.print(schedGroup); 13616 pw.print('/'); 13617 pw.print(foreground); 13618 pw.print('/'); 13619 pw.print(procState); 13620 pw.print(" trm:"); 13621 if (r.trimMemoryLevel < 10) pw.print(' '); 13622 pw.print(r.trimMemoryLevel); 13623 pw.print(' '); 13624 pw.print(r.toShortString()); 13625 pw.print(" ("); 13626 pw.print(r.adjType); 13627 pw.println(')'); 13628 if (r.adjSource != null || r.adjTarget != null) { 13629 pw.print(prefix); 13630 pw.print(" "); 13631 if (r.adjTarget instanceof ComponentName) { 13632 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13633 } else if (r.adjTarget != null) { 13634 pw.print(r.adjTarget.toString()); 13635 } else { 13636 pw.print("{null}"); 13637 } 13638 pw.print("<="); 13639 if (r.adjSource instanceof ProcessRecord) { 13640 pw.print("Proc{"); 13641 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13642 pw.println("}"); 13643 } else if (r.adjSource != null) { 13644 pw.println(r.adjSource.toString()); 13645 } else { 13646 pw.println("{null}"); 13647 } 13648 } 13649 if (inclDetails) { 13650 pw.print(prefix); 13651 pw.print(" "); 13652 pw.print("oom: max="); pw.print(r.maxAdj); 13653 pw.print(" curRaw="); pw.print(r.curRawAdj); 13654 pw.print(" setRaw="); pw.print(r.setRawAdj); 13655 pw.print(" cur="); pw.print(r.curAdj); 13656 pw.print(" set="); pw.println(r.setAdj); 13657 pw.print(prefix); 13658 pw.print(" "); 13659 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13660 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13661 pw.print(" lastPss="); pw.print(r.lastPss); 13662 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13663 pw.print(prefix); 13664 pw.print(" "); 13665 pw.print("cached="); pw.print(r.cached); 13666 pw.print(" empty="); pw.print(r.empty); 13667 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13668 13669 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13670 if (r.lastWakeTime != 0) { 13671 long wtime; 13672 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13673 synchronized (stats) { 13674 wtime = stats.getProcessWakeTime(r.info.uid, 13675 r.pid, curRealtime); 13676 } 13677 long timeUsed = wtime - r.lastWakeTime; 13678 pw.print(prefix); 13679 pw.print(" "); 13680 pw.print("keep awake over "); 13681 TimeUtils.formatDuration(realtimeSince, pw); 13682 pw.print(" used "); 13683 TimeUtils.formatDuration(timeUsed, pw); 13684 pw.print(" ("); 13685 pw.print((timeUsed*100)/realtimeSince); 13686 pw.println("%)"); 13687 } 13688 if (r.lastCpuTime != 0) { 13689 long timeUsed = r.curCpuTime - r.lastCpuTime; 13690 pw.print(prefix); 13691 pw.print(" "); 13692 pw.print("run cpu over "); 13693 TimeUtils.formatDuration(uptimeSince, pw); 13694 pw.print(" used "); 13695 TimeUtils.formatDuration(timeUsed, pw); 13696 pw.print(" ("); 13697 pw.print((timeUsed*100)/uptimeSince); 13698 pw.println("%)"); 13699 } 13700 } 13701 } 13702 } 13703 return true; 13704 } 13705 13706 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13707 String[] args) { 13708 ArrayList<ProcessRecord> procs; 13709 synchronized (this) { 13710 if (args != null && args.length > start 13711 && args[start].charAt(0) != '-') { 13712 procs = new ArrayList<ProcessRecord>(); 13713 int pid = -1; 13714 try { 13715 pid = Integer.parseInt(args[start]); 13716 } catch (NumberFormatException e) { 13717 } 13718 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13719 ProcessRecord proc = mLruProcesses.get(i); 13720 if (proc.pid == pid) { 13721 procs.add(proc); 13722 } else if (allPkgs && proc.pkgList != null 13723 && proc.pkgList.containsKey(args[start])) { 13724 procs.add(proc); 13725 } else if (proc.processName.equals(args[start])) { 13726 procs.add(proc); 13727 } 13728 } 13729 if (procs.size() <= 0) { 13730 return null; 13731 } 13732 } else { 13733 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13734 } 13735 } 13736 return procs; 13737 } 13738 13739 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13740 PrintWriter pw, String[] args) { 13741 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13742 if (procs == null) { 13743 pw.println("No process found for: " + args[0]); 13744 return; 13745 } 13746 13747 long uptime = SystemClock.uptimeMillis(); 13748 long realtime = SystemClock.elapsedRealtime(); 13749 pw.println("Applications Graphics Acceleration Info:"); 13750 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13751 13752 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13753 ProcessRecord r = procs.get(i); 13754 if (r.thread != null) { 13755 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13756 pw.flush(); 13757 try { 13758 TransferPipe tp = new TransferPipe(); 13759 try { 13760 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13761 tp.go(fd); 13762 } finally { 13763 tp.kill(); 13764 } 13765 } catch (IOException e) { 13766 pw.println("Failure while dumping the app: " + r); 13767 pw.flush(); 13768 } catch (RemoteException e) { 13769 pw.println("Got a RemoteException while dumping the app " + r); 13770 pw.flush(); 13771 } 13772 } 13773 } 13774 } 13775 13776 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13777 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13778 if (procs == null) { 13779 pw.println("No process found for: " + args[0]); 13780 return; 13781 } 13782 13783 pw.println("Applications Database Info:"); 13784 13785 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13786 ProcessRecord r = procs.get(i); 13787 if (r.thread != null) { 13788 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13789 pw.flush(); 13790 try { 13791 TransferPipe tp = new TransferPipe(); 13792 try { 13793 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13794 tp.go(fd); 13795 } finally { 13796 tp.kill(); 13797 } 13798 } catch (IOException e) { 13799 pw.println("Failure while dumping the app: " + r); 13800 pw.flush(); 13801 } catch (RemoteException e) { 13802 pw.println("Got a RemoteException while dumping the app " + r); 13803 pw.flush(); 13804 } 13805 } 13806 } 13807 } 13808 13809 final static class MemItem { 13810 final boolean isProc; 13811 final String label; 13812 final String shortLabel; 13813 final long pss; 13814 final int id; 13815 final boolean hasActivities; 13816 ArrayList<MemItem> subitems; 13817 13818 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13819 boolean _hasActivities) { 13820 isProc = true; 13821 label = _label; 13822 shortLabel = _shortLabel; 13823 pss = _pss; 13824 id = _id; 13825 hasActivities = _hasActivities; 13826 } 13827 13828 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13829 isProc = false; 13830 label = _label; 13831 shortLabel = _shortLabel; 13832 pss = _pss; 13833 id = _id; 13834 hasActivities = false; 13835 } 13836 } 13837 13838 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13839 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13840 if (sort && !isCompact) { 13841 Collections.sort(items, new Comparator<MemItem>() { 13842 @Override 13843 public int compare(MemItem lhs, MemItem rhs) { 13844 if (lhs.pss < rhs.pss) { 13845 return 1; 13846 } else if (lhs.pss > rhs.pss) { 13847 return -1; 13848 } 13849 return 0; 13850 } 13851 }); 13852 } 13853 13854 for (int i=0; i<items.size(); i++) { 13855 MemItem mi = items.get(i); 13856 if (!isCompact) { 13857 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13858 } else if (mi.isProc) { 13859 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13860 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13861 pw.println(mi.hasActivities ? ",a" : ",e"); 13862 } else { 13863 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13864 pw.println(mi.pss); 13865 } 13866 if (mi.subitems != null) { 13867 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13868 true, isCompact); 13869 } 13870 } 13871 } 13872 13873 // These are in KB. 13874 static final long[] DUMP_MEM_BUCKETS = new long[] { 13875 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13876 120*1024, 160*1024, 200*1024, 13877 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13878 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13879 }; 13880 13881 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13882 boolean stackLike) { 13883 int start = label.lastIndexOf('.'); 13884 if (start >= 0) start++; 13885 else start = 0; 13886 int end = label.length(); 13887 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13888 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13889 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13890 out.append(bucket); 13891 out.append(stackLike ? "MB." : "MB "); 13892 out.append(label, start, end); 13893 return; 13894 } 13895 } 13896 out.append(memKB/1024); 13897 out.append(stackLike ? "MB." : "MB "); 13898 out.append(label, start, end); 13899 } 13900 13901 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13902 ProcessList.NATIVE_ADJ, 13903 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13904 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13905 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13906 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13907 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13908 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13909 }; 13910 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13911 "Native", 13912 "System", "Persistent", "Persistent Service", "Foreground", 13913 "Visible", "Perceptible", 13914 "Heavy Weight", "Backup", 13915 "A Services", "Home", 13916 "Previous", "B Services", "Cached" 13917 }; 13918 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13919 "native", 13920 "sys", "pers", "persvc", "fore", 13921 "vis", "percept", 13922 "heavy", "backup", 13923 "servicea", "home", 13924 "prev", "serviceb", "cached" 13925 }; 13926 13927 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13928 long realtime, boolean isCheckinRequest, boolean isCompact) { 13929 if (isCheckinRequest || isCompact) { 13930 // short checkin version 13931 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13932 } else { 13933 pw.println("Applications Memory Usage (kB):"); 13934 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13935 } 13936 } 13937 13938 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13939 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13940 boolean dumpDetails = false; 13941 boolean dumpFullDetails = false; 13942 boolean dumpDalvik = false; 13943 boolean oomOnly = false; 13944 boolean isCompact = false; 13945 boolean localOnly = false; 13946 boolean packages = false; 13947 13948 int opti = 0; 13949 while (opti < args.length) { 13950 String opt = args[opti]; 13951 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13952 break; 13953 } 13954 opti++; 13955 if ("-a".equals(opt)) { 13956 dumpDetails = true; 13957 dumpFullDetails = true; 13958 dumpDalvik = true; 13959 } else if ("-d".equals(opt)) { 13960 dumpDalvik = true; 13961 } else if ("-c".equals(opt)) { 13962 isCompact = true; 13963 } else if ("--oom".equals(opt)) { 13964 oomOnly = true; 13965 } else if ("--local".equals(opt)) { 13966 localOnly = true; 13967 } else if ("--package".equals(opt)) { 13968 packages = true; 13969 } else if ("-h".equals(opt)) { 13970 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13971 pw.println(" -a: include all available information for each process."); 13972 pw.println(" -d: include dalvik details when dumping process details."); 13973 pw.println(" -c: dump in a compact machine-parseable representation."); 13974 pw.println(" --oom: only show processes organized by oom adj."); 13975 pw.println(" --local: only collect details locally, don't call process."); 13976 pw.println(" --package: interpret process arg as package, dumping all"); 13977 pw.println(" processes that have loaded that package."); 13978 pw.println("If [process] is specified it can be the name or "); 13979 pw.println("pid of a specific process to dump."); 13980 return; 13981 } else { 13982 pw.println("Unknown argument: " + opt + "; use -h for help"); 13983 } 13984 } 13985 13986 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13987 long uptime = SystemClock.uptimeMillis(); 13988 long realtime = SystemClock.elapsedRealtime(); 13989 final long[] tmpLong = new long[1]; 13990 13991 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13992 if (procs == null) { 13993 // No Java processes. Maybe they want to print a native process. 13994 if (args != null && args.length > opti 13995 && args[opti].charAt(0) != '-') { 13996 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13997 = new ArrayList<ProcessCpuTracker.Stats>(); 13998 updateCpuStatsNow(); 13999 int findPid = -1; 14000 try { 14001 findPid = Integer.parseInt(args[opti]); 14002 } catch (NumberFormatException e) { 14003 } 14004 synchronized (mProcessCpuTracker) { 14005 final int N = mProcessCpuTracker.countStats(); 14006 for (int i=0; i<N; i++) { 14007 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14008 if (st.pid == findPid || (st.baseName != null 14009 && st.baseName.equals(args[opti]))) { 14010 nativeProcs.add(st); 14011 } 14012 } 14013 } 14014 if (nativeProcs.size() > 0) { 14015 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14016 isCompact); 14017 Debug.MemoryInfo mi = null; 14018 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14019 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14020 final int pid = r.pid; 14021 if (!isCheckinRequest && dumpDetails) { 14022 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14023 } 14024 if (mi == null) { 14025 mi = new Debug.MemoryInfo(); 14026 } 14027 if (dumpDetails || (!brief && !oomOnly)) { 14028 Debug.getMemoryInfo(pid, mi); 14029 } else { 14030 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14031 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14032 } 14033 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14034 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14035 if (isCheckinRequest) { 14036 pw.println(); 14037 } 14038 } 14039 return; 14040 } 14041 } 14042 pw.println("No process found for: " + args[opti]); 14043 return; 14044 } 14045 14046 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14047 dumpDetails = true; 14048 } 14049 14050 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14051 14052 String[] innerArgs = new String[args.length-opti]; 14053 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14054 14055 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14056 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14057 long nativePss=0, dalvikPss=0, otherPss=0; 14058 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14059 14060 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14061 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14062 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14063 14064 long totalPss = 0; 14065 long cachedPss = 0; 14066 14067 Debug.MemoryInfo mi = null; 14068 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14069 final ProcessRecord r = procs.get(i); 14070 final IApplicationThread thread; 14071 final int pid; 14072 final int oomAdj; 14073 final boolean hasActivities; 14074 synchronized (this) { 14075 thread = r.thread; 14076 pid = r.pid; 14077 oomAdj = r.getSetAdjWithServices(); 14078 hasActivities = r.activities.size() > 0; 14079 } 14080 if (thread != null) { 14081 if (!isCheckinRequest && dumpDetails) { 14082 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14083 } 14084 if (mi == null) { 14085 mi = new Debug.MemoryInfo(); 14086 } 14087 if (dumpDetails || (!brief && !oomOnly)) { 14088 Debug.getMemoryInfo(pid, mi); 14089 } else { 14090 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14091 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14092 } 14093 if (dumpDetails) { 14094 if (localOnly) { 14095 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14096 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14097 if (isCheckinRequest) { 14098 pw.println(); 14099 } 14100 } else { 14101 try { 14102 pw.flush(); 14103 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14104 dumpDalvik, innerArgs); 14105 } catch (RemoteException e) { 14106 if (!isCheckinRequest) { 14107 pw.println("Got RemoteException!"); 14108 pw.flush(); 14109 } 14110 } 14111 } 14112 } 14113 14114 final long myTotalPss = mi.getTotalPss(); 14115 final long myTotalUss = mi.getTotalUss(); 14116 14117 synchronized (this) { 14118 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14119 // Record this for posterity if the process has been stable. 14120 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14121 } 14122 } 14123 14124 if (!isCheckinRequest && mi != null) { 14125 totalPss += myTotalPss; 14126 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14127 (hasActivities ? " / activities)" : ")"), 14128 r.processName, myTotalPss, pid, hasActivities); 14129 procMems.add(pssItem); 14130 procMemsMap.put(pid, pssItem); 14131 14132 nativePss += mi.nativePss; 14133 dalvikPss += mi.dalvikPss; 14134 otherPss += mi.otherPss; 14135 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14136 long mem = mi.getOtherPss(j); 14137 miscPss[j] += mem; 14138 otherPss -= mem; 14139 } 14140 14141 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14142 cachedPss += myTotalPss; 14143 } 14144 14145 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14146 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14147 || oomIndex == (oomPss.length-1)) { 14148 oomPss[oomIndex] += myTotalPss; 14149 if (oomProcs[oomIndex] == null) { 14150 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14151 } 14152 oomProcs[oomIndex].add(pssItem); 14153 break; 14154 } 14155 } 14156 } 14157 } 14158 } 14159 14160 long nativeProcTotalPss = 0; 14161 14162 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14163 // If we are showing aggregations, also look for native processes to 14164 // include so that our aggregations are more accurate. 14165 updateCpuStatsNow(); 14166 synchronized (mProcessCpuTracker) { 14167 final int N = mProcessCpuTracker.countStats(); 14168 for (int i=0; i<N; i++) { 14169 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14170 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14171 if (mi == null) { 14172 mi = new Debug.MemoryInfo(); 14173 } 14174 if (!brief && !oomOnly) { 14175 Debug.getMemoryInfo(st.pid, mi); 14176 } else { 14177 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14178 mi.nativePrivateDirty = (int)tmpLong[0]; 14179 } 14180 14181 final long myTotalPss = mi.getTotalPss(); 14182 totalPss += myTotalPss; 14183 nativeProcTotalPss += myTotalPss; 14184 14185 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14186 st.name, myTotalPss, st.pid, false); 14187 procMems.add(pssItem); 14188 14189 nativePss += mi.nativePss; 14190 dalvikPss += mi.dalvikPss; 14191 otherPss += mi.otherPss; 14192 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14193 long mem = mi.getOtherPss(j); 14194 miscPss[j] += mem; 14195 otherPss -= mem; 14196 } 14197 oomPss[0] += myTotalPss; 14198 if (oomProcs[0] == null) { 14199 oomProcs[0] = new ArrayList<MemItem>(); 14200 } 14201 oomProcs[0].add(pssItem); 14202 } 14203 } 14204 } 14205 14206 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14207 14208 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14209 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14210 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14211 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14212 String label = Debug.MemoryInfo.getOtherLabel(j); 14213 catMems.add(new MemItem(label, label, miscPss[j], j)); 14214 } 14215 14216 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14217 for (int j=0; j<oomPss.length; j++) { 14218 if (oomPss[j] != 0) { 14219 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14220 : DUMP_MEM_OOM_LABEL[j]; 14221 MemItem item = new MemItem(label, label, oomPss[j], 14222 DUMP_MEM_OOM_ADJ[j]); 14223 item.subitems = oomProcs[j]; 14224 oomMems.add(item); 14225 } 14226 } 14227 14228 if (!brief && !oomOnly && !isCompact) { 14229 pw.println(); 14230 pw.println("Total PSS by process:"); 14231 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14232 pw.println(); 14233 } 14234 if (!isCompact) { 14235 pw.println("Total PSS by OOM adjustment:"); 14236 } 14237 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14238 if (!brief && !oomOnly) { 14239 PrintWriter out = categoryPw != null ? categoryPw : pw; 14240 if (!isCompact) { 14241 out.println(); 14242 out.println("Total PSS by category:"); 14243 } 14244 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14245 } 14246 if (!isCompact) { 14247 pw.println(); 14248 } 14249 MemInfoReader memInfo = new MemInfoReader(); 14250 memInfo.readMemInfo(); 14251 if (nativeProcTotalPss > 0) { 14252 synchronized (this) { 14253 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14254 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14255 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14256 nativeProcTotalPss); 14257 } 14258 } 14259 if (!brief) { 14260 if (!isCompact) { 14261 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14262 pw.print(" kB (status "); 14263 switch (mLastMemoryLevel) { 14264 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14265 pw.println("normal)"); 14266 break; 14267 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14268 pw.println("moderate)"); 14269 break; 14270 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14271 pw.println("low)"); 14272 break; 14273 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14274 pw.println("critical)"); 14275 break; 14276 default: 14277 pw.print(mLastMemoryLevel); 14278 pw.println(")"); 14279 break; 14280 } 14281 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14282 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14283 pw.print(cachedPss); pw.print(" cached pss + "); 14284 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14285 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14286 } else { 14287 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14288 pw.print(cachedPss + memInfo.getCachedSizeKb() 14289 + memInfo.getFreeSizeKb()); pw.print(","); 14290 pw.println(totalPss - cachedPss); 14291 } 14292 } 14293 if (!isCompact) { 14294 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14295 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14296 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14297 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14298 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14299 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14300 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14301 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14302 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14303 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14304 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14305 } 14306 if (!brief) { 14307 if (memInfo.getZramTotalSizeKb() != 0) { 14308 if (!isCompact) { 14309 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14310 pw.print(" kB physical used for "); 14311 pw.print(memInfo.getSwapTotalSizeKb() 14312 - memInfo.getSwapFreeSizeKb()); 14313 pw.print(" kB in swap ("); 14314 pw.print(memInfo.getSwapTotalSizeKb()); 14315 pw.println(" kB total swap)"); 14316 } else { 14317 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14318 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14319 pw.println(memInfo.getSwapFreeSizeKb()); 14320 } 14321 } 14322 final int[] SINGLE_LONG_FORMAT = new int[] { 14323 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14324 }; 14325 long[] longOut = new long[1]; 14326 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14327 SINGLE_LONG_FORMAT, null, longOut, null); 14328 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14329 longOut[0] = 0; 14330 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14331 SINGLE_LONG_FORMAT, null, longOut, null); 14332 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14333 longOut[0] = 0; 14334 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14335 SINGLE_LONG_FORMAT, null, longOut, null); 14336 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14337 longOut[0] = 0; 14338 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14339 SINGLE_LONG_FORMAT, null, longOut, null); 14340 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14341 if (!isCompact) { 14342 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14343 pw.print(" KSM: "); pw.print(sharing); 14344 pw.print(" kB saved from shared "); 14345 pw.print(shared); pw.println(" kB"); 14346 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14347 pw.print(voltile); pw.println(" kB volatile"); 14348 } 14349 pw.print(" Tuning: "); 14350 pw.print(ActivityManager.staticGetMemoryClass()); 14351 pw.print(" (large "); 14352 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14353 pw.print("), oom "); 14354 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14355 pw.print(" kB"); 14356 pw.print(", restore limit "); 14357 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14358 pw.print(" kB"); 14359 if (ActivityManager.isLowRamDeviceStatic()) { 14360 pw.print(" (low-ram)"); 14361 } 14362 if (ActivityManager.isHighEndGfx()) { 14363 pw.print(" (high-end-gfx)"); 14364 } 14365 pw.println(); 14366 } else { 14367 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14368 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14369 pw.println(voltile); 14370 pw.print("tuning,"); 14371 pw.print(ActivityManager.staticGetMemoryClass()); 14372 pw.print(','); 14373 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14374 pw.print(','); 14375 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14376 if (ActivityManager.isLowRamDeviceStatic()) { 14377 pw.print(",low-ram"); 14378 } 14379 if (ActivityManager.isHighEndGfx()) { 14380 pw.print(",high-end-gfx"); 14381 } 14382 pw.println(); 14383 } 14384 } 14385 } 14386 } 14387 14388 /** 14389 * Searches array of arguments for the specified string 14390 * @param args array of argument strings 14391 * @param value value to search for 14392 * @return true if the value is contained in the array 14393 */ 14394 private static boolean scanArgs(String[] args, String value) { 14395 if (args != null) { 14396 for (String arg : args) { 14397 if (value.equals(arg)) { 14398 return true; 14399 } 14400 } 14401 } 14402 return false; 14403 } 14404 14405 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14406 ContentProviderRecord cpr, boolean always) { 14407 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14408 14409 if (!inLaunching || always) { 14410 synchronized (cpr) { 14411 cpr.launchingApp = null; 14412 cpr.notifyAll(); 14413 } 14414 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14415 String names[] = cpr.info.authority.split(";"); 14416 for (int j = 0; j < names.length; j++) { 14417 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14418 } 14419 } 14420 14421 for (int i=0; i<cpr.connections.size(); i++) { 14422 ContentProviderConnection conn = cpr.connections.get(i); 14423 if (conn.waiting) { 14424 // If this connection is waiting for the provider, then we don't 14425 // need to mess with its process unless we are always removing 14426 // or for some reason the provider is not currently launching. 14427 if (inLaunching && !always) { 14428 continue; 14429 } 14430 } 14431 ProcessRecord capp = conn.client; 14432 conn.dead = true; 14433 if (conn.stableCount > 0) { 14434 if (!capp.persistent && capp.thread != null 14435 && capp.pid != 0 14436 && capp.pid != MY_PID) { 14437 capp.kill("depends on provider " 14438 + cpr.name.flattenToShortString() 14439 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14440 } 14441 } else if (capp.thread != null && conn.provider.provider != null) { 14442 try { 14443 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14444 } catch (RemoteException e) { 14445 } 14446 // In the protocol here, we don't expect the client to correctly 14447 // clean up this connection, we'll just remove it. 14448 cpr.connections.remove(i); 14449 conn.client.conProviders.remove(conn); 14450 } 14451 } 14452 14453 if (inLaunching && always) { 14454 mLaunchingProviders.remove(cpr); 14455 } 14456 return inLaunching; 14457 } 14458 14459 /** 14460 * Main code for cleaning up a process when it has gone away. This is 14461 * called both as a result of the process dying, or directly when stopping 14462 * a process when running in single process mode. 14463 * 14464 * @return Returns true if the given process has been restarted, so the 14465 * app that was passed in must remain on the process lists. 14466 */ 14467 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14468 boolean restarting, boolean allowRestart, int index) { 14469 if (index >= 0) { 14470 removeLruProcessLocked(app); 14471 ProcessList.remove(app.pid); 14472 } 14473 14474 mProcessesToGc.remove(app); 14475 mPendingPssProcesses.remove(app); 14476 14477 // Dismiss any open dialogs. 14478 if (app.crashDialog != null && !app.forceCrashReport) { 14479 app.crashDialog.dismiss(); 14480 app.crashDialog = null; 14481 } 14482 if (app.anrDialog != null) { 14483 app.anrDialog.dismiss(); 14484 app.anrDialog = null; 14485 } 14486 if (app.waitDialog != null) { 14487 app.waitDialog.dismiss(); 14488 app.waitDialog = null; 14489 } 14490 14491 app.crashing = false; 14492 app.notResponding = false; 14493 14494 app.resetPackageList(mProcessStats); 14495 app.unlinkDeathRecipient(); 14496 app.makeInactive(mProcessStats); 14497 app.waitingToKill = null; 14498 app.forcingToForeground = null; 14499 updateProcessForegroundLocked(app, false, false); 14500 app.foregroundActivities = false; 14501 app.hasShownUi = false; 14502 app.treatLikeActivity = false; 14503 app.hasAboveClient = false; 14504 app.hasClientActivities = false; 14505 14506 mServices.killServicesLocked(app, allowRestart); 14507 14508 boolean restart = false; 14509 14510 // Remove published content providers. 14511 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14512 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14513 final boolean always = app.bad || !allowRestart; 14514 if (removeDyingProviderLocked(app, cpr, always) || always) { 14515 // We left the provider in the launching list, need to 14516 // restart it. 14517 restart = true; 14518 } 14519 14520 cpr.provider = null; 14521 cpr.proc = null; 14522 } 14523 app.pubProviders.clear(); 14524 14525 // Take care of any launching providers waiting for this process. 14526 if (checkAppInLaunchingProvidersLocked(app, false)) { 14527 restart = true; 14528 } 14529 14530 // Unregister from connected content providers. 14531 if (!app.conProviders.isEmpty()) { 14532 for (int i=0; i<app.conProviders.size(); i++) { 14533 ContentProviderConnection conn = app.conProviders.get(i); 14534 conn.provider.connections.remove(conn); 14535 } 14536 app.conProviders.clear(); 14537 } 14538 14539 // At this point there may be remaining entries in mLaunchingProviders 14540 // where we were the only one waiting, so they are no longer of use. 14541 // Look for these and clean up if found. 14542 // XXX Commented out for now. Trying to figure out a way to reproduce 14543 // the actual situation to identify what is actually going on. 14544 if (false) { 14545 for (int i=0; i<mLaunchingProviders.size(); i++) { 14546 ContentProviderRecord cpr = (ContentProviderRecord) 14547 mLaunchingProviders.get(i); 14548 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14549 synchronized (cpr) { 14550 cpr.launchingApp = null; 14551 cpr.notifyAll(); 14552 } 14553 } 14554 } 14555 } 14556 14557 skipCurrentReceiverLocked(app); 14558 14559 // Unregister any receivers. 14560 for (int i=app.receivers.size()-1; i>=0; i--) { 14561 removeReceiverLocked(app.receivers.valueAt(i)); 14562 } 14563 app.receivers.clear(); 14564 14565 // If the app is undergoing backup, tell the backup manager about it 14566 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14567 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14568 + mBackupTarget.appInfo + " died during backup"); 14569 try { 14570 IBackupManager bm = IBackupManager.Stub.asInterface( 14571 ServiceManager.getService(Context.BACKUP_SERVICE)); 14572 bm.agentDisconnected(app.info.packageName); 14573 } catch (RemoteException e) { 14574 // can't happen; backup manager is local 14575 } 14576 } 14577 14578 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14579 ProcessChangeItem item = mPendingProcessChanges.get(i); 14580 if (item.pid == app.pid) { 14581 mPendingProcessChanges.remove(i); 14582 mAvailProcessChanges.add(item); 14583 } 14584 } 14585 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14586 14587 // If the caller is restarting this app, then leave it in its 14588 // current lists and let the caller take care of it. 14589 if (restarting) { 14590 return false; 14591 } 14592 14593 if (!app.persistent || app.isolated) { 14594 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14595 "Removing non-persistent process during cleanup: " + app); 14596 mProcessNames.remove(app.processName, app.uid); 14597 mIsolatedProcesses.remove(app.uid); 14598 if (mHeavyWeightProcess == app) { 14599 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14600 mHeavyWeightProcess.userId, 0)); 14601 mHeavyWeightProcess = null; 14602 } 14603 } else if (!app.removed) { 14604 // This app is persistent, so we need to keep its record around. 14605 // If it is not already on the pending app list, add it there 14606 // and start a new process for it. 14607 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14608 mPersistentStartingProcesses.add(app); 14609 restart = true; 14610 } 14611 } 14612 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14613 "Clean-up removing on hold: " + app); 14614 mProcessesOnHold.remove(app); 14615 14616 if (app == mHomeProcess) { 14617 mHomeProcess = null; 14618 } 14619 if (app == mPreviousProcess) { 14620 mPreviousProcess = null; 14621 } 14622 14623 if (restart && !app.isolated) { 14624 // We have components that still need to be running in the 14625 // process, so re-launch it. 14626 if (index < 0) { 14627 ProcessList.remove(app.pid); 14628 } 14629 mProcessNames.put(app.processName, app.uid, app); 14630 startProcessLocked(app, "restart", app.processName); 14631 return true; 14632 } else if (app.pid > 0 && app.pid != MY_PID) { 14633 // Goodbye! 14634 boolean removed; 14635 synchronized (mPidsSelfLocked) { 14636 mPidsSelfLocked.remove(app.pid); 14637 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14638 } 14639 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14640 if (app.isolated) { 14641 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14642 } 14643 app.setPid(0); 14644 } 14645 return false; 14646 } 14647 14648 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14649 // Look through the content providers we are waiting to have launched, 14650 // and if any run in this process then either schedule a restart of 14651 // the process or kill the client waiting for it if this process has 14652 // gone bad. 14653 int NL = mLaunchingProviders.size(); 14654 boolean restart = false; 14655 for (int i=0; i<NL; i++) { 14656 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14657 if (cpr.launchingApp == app) { 14658 if (!alwaysBad && !app.bad) { 14659 restart = true; 14660 } else { 14661 removeDyingProviderLocked(app, cpr, true); 14662 // cpr should have been removed from mLaunchingProviders 14663 NL = mLaunchingProviders.size(); 14664 i--; 14665 } 14666 } 14667 } 14668 return restart; 14669 } 14670 14671 // ========================================================= 14672 // SERVICES 14673 // ========================================================= 14674 14675 @Override 14676 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14677 int flags) { 14678 enforceNotIsolatedCaller("getServices"); 14679 synchronized (this) { 14680 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14681 } 14682 } 14683 14684 @Override 14685 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14686 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14687 synchronized (this) { 14688 return mServices.getRunningServiceControlPanelLocked(name); 14689 } 14690 } 14691 14692 @Override 14693 public ComponentName startService(IApplicationThread caller, Intent service, 14694 String resolvedType, int userId) { 14695 enforceNotIsolatedCaller("startService"); 14696 // Refuse possible leaked file descriptors 14697 if (service != null && service.hasFileDescriptors() == true) { 14698 throw new IllegalArgumentException("File descriptors passed in Intent"); 14699 } 14700 14701 if (DEBUG_SERVICE) 14702 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14703 synchronized(this) { 14704 final int callingPid = Binder.getCallingPid(); 14705 final int callingUid = Binder.getCallingUid(); 14706 final long origId = Binder.clearCallingIdentity(); 14707 ComponentName res = mServices.startServiceLocked(caller, service, 14708 resolvedType, callingPid, callingUid, userId); 14709 Binder.restoreCallingIdentity(origId); 14710 return res; 14711 } 14712 } 14713 14714 ComponentName startServiceInPackage(int uid, 14715 Intent service, String resolvedType, int userId) { 14716 synchronized(this) { 14717 if (DEBUG_SERVICE) 14718 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14719 final long origId = Binder.clearCallingIdentity(); 14720 ComponentName res = mServices.startServiceLocked(null, service, 14721 resolvedType, -1, uid, userId); 14722 Binder.restoreCallingIdentity(origId); 14723 return res; 14724 } 14725 } 14726 14727 @Override 14728 public int stopService(IApplicationThread caller, Intent service, 14729 String resolvedType, int userId) { 14730 enforceNotIsolatedCaller("stopService"); 14731 // Refuse possible leaked file descriptors 14732 if (service != null && service.hasFileDescriptors() == true) { 14733 throw new IllegalArgumentException("File descriptors passed in Intent"); 14734 } 14735 14736 synchronized(this) { 14737 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14738 } 14739 } 14740 14741 @Override 14742 public IBinder peekService(Intent service, String resolvedType) { 14743 enforceNotIsolatedCaller("peekService"); 14744 // Refuse possible leaked file descriptors 14745 if (service != null && service.hasFileDescriptors() == true) { 14746 throw new IllegalArgumentException("File descriptors passed in Intent"); 14747 } 14748 synchronized(this) { 14749 return mServices.peekServiceLocked(service, resolvedType); 14750 } 14751 } 14752 14753 @Override 14754 public boolean stopServiceToken(ComponentName className, IBinder token, 14755 int startId) { 14756 synchronized(this) { 14757 return mServices.stopServiceTokenLocked(className, token, startId); 14758 } 14759 } 14760 14761 @Override 14762 public void setServiceForeground(ComponentName className, IBinder token, 14763 int id, Notification notification, boolean removeNotification) { 14764 synchronized(this) { 14765 mServices.setServiceForegroundLocked(className, token, id, notification, 14766 removeNotification); 14767 } 14768 } 14769 14770 @Override 14771 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14772 boolean requireFull, String name, String callerPackage) { 14773 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14774 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14775 } 14776 14777 int unsafeConvertIncomingUser(int userId) { 14778 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14779 ? mCurrentUserId : userId; 14780 } 14781 14782 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14783 int allowMode, String name, String callerPackage) { 14784 final int callingUserId = UserHandle.getUserId(callingUid); 14785 if (callingUserId == userId) { 14786 return userId; 14787 } 14788 14789 // Note that we may be accessing mCurrentUserId outside of a lock... 14790 // shouldn't be a big deal, if this is being called outside 14791 // of a locked context there is intrinsically a race with 14792 // the value the caller will receive and someone else changing it. 14793 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14794 // we will switch to the calling user if access to the current user fails. 14795 int targetUserId = unsafeConvertIncomingUser(userId); 14796 14797 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14798 final boolean allow; 14799 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14800 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14801 // If the caller has this permission, they always pass go. And collect $200. 14802 allow = true; 14803 } else if (allowMode == ALLOW_FULL_ONLY) { 14804 // We require full access, sucks to be you. 14805 allow = false; 14806 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14807 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14808 // If the caller does not have either permission, they are always doomed. 14809 allow = false; 14810 } else if (allowMode == ALLOW_NON_FULL) { 14811 // We are blanket allowing non-full access, you lucky caller! 14812 allow = true; 14813 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14814 // We may or may not allow this depending on whether the two users are 14815 // in the same profile. 14816 synchronized (mUserProfileGroupIdsSelfLocked) { 14817 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14818 UserInfo.NO_PROFILE_GROUP_ID); 14819 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14820 UserInfo.NO_PROFILE_GROUP_ID); 14821 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14822 && callingProfile == targetProfile; 14823 } 14824 } else { 14825 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14826 } 14827 if (!allow) { 14828 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14829 // In this case, they would like to just execute as their 14830 // owner user instead of failing. 14831 targetUserId = callingUserId; 14832 } else { 14833 StringBuilder builder = new StringBuilder(128); 14834 builder.append("Permission Denial: "); 14835 builder.append(name); 14836 if (callerPackage != null) { 14837 builder.append(" from "); 14838 builder.append(callerPackage); 14839 } 14840 builder.append(" asks to run as user "); 14841 builder.append(userId); 14842 builder.append(" but is calling from user "); 14843 builder.append(UserHandle.getUserId(callingUid)); 14844 builder.append("; this requires "); 14845 builder.append(INTERACT_ACROSS_USERS_FULL); 14846 if (allowMode != ALLOW_FULL_ONLY) { 14847 builder.append(" or "); 14848 builder.append(INTERACT_ACROSS_USERS); 14849 } 14850 String msg = builder.toString(); 14851 Slog.w(TAG, msg); 14852 throw new SecurityException(msg); 14853 } 14854 } 14855 } 14856 if (!allowAll && targetUserId < 0) { 14857 throw new IllegalArgumentException( 14858 "Call does not support special user #" + targetUserId); 14859 } 14860 // Check shell permission 14861 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14862 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14863 targetUserId)) { 14864 throw new SecurityException("Shell does not have permission to access user " 14865 + targetUserId + "\n " + Debug.getCallers(3)); 14866 } 14867 } 14868 return targetUserId; 14869 } 14870 14871 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14872 String className, int flags) { 14873 boolean result = false; 14874 // For apps that don't have pre-defined UIDs, check for permission 14875 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14876 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14877 if (ActivityManager.checkUidPermission( 14878 INTERACT_ACROSS_USERS, 14879 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14880 ComponentName comp = new ComponentName(aInfo.packageName, className); 14881 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14882 + " requests FLAG_SINGLE_USER, but app does not hold " 14883 + INTERACT_ACROSS_USERS; 14884 Slog.w(TAG, msg); 14885 throw new SecurityException(msg); 14886 } 14887 // Permission passed 14888 result = true; 14889 } 14890 } else if ("system".equals(componentProcessName)) { 14891 result = true; 14892 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14893 // Phone app and persistent apps are allowed to export singleuser providers. 14894 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14895 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14896 } 14897 if (DEBUG_MU) { 14898 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14899 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14900 } 14901 return result; 14902 } 14903 14904 /** 14905 * Checks to see if the caller is in the same app as the singleton 14906 * component, or the component is in a special app. It allows special apps 14907 * to export singleton components but prevents exporting singleton 14908 * components for regular apps. 14909 */ 14910 boolean isValidSingletonCall(int callingUid, int componentUid) { 14911 int componentAppId = UserHandle.getAppId(componentUid); 14912 return UserHandle.isSameApp(callingUid, componentUid) 14913 || componentAppId == Process.SYSTEM_UID 14914 || componentAppId == Process.PHONE_UID 14915 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14916 == PackageManager.PERMISSION_GRANTED; 14917 } 14918 14919 public int bindService(IApplicationThread caller, IBinder token, 14920 Intent service, String resolvedType, 14921 IServiceConnection connection, int flags, int userId) { 14922 enforceNotIsolatedCaller("bindService"); 14923 14924 // Refuse possible leaked file descriptors 14925 if (service != null && service.hasFileDescriptors() == true) { 14926 throw new IllegalArgumentException("File descriptors passed in Intent"); 14927 } 14928 14929 synchronized(this) { 14930 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14931 connection, flags, userId); 14932 } 14933 } 14934 14935 public boolean unbindService(IServiceConnection connection) { 14936 synchronized (this) { 14937 return mServices.unbindServiceLocked(connection); 14938 } 14939 } 14940 14941 public void publishService(IBinder token, Intent intent, IBinder service) { 14942 // Refuse possible leaked file descriptors 14943 if (intent != null && intent.hasFileDescriptors() == true) { 14944 throw new IllegalArgumentException("File descriptors passed in Intent"); 14945 } 14946 14947 synchronized(this) { 14948 if (!(token instanceof ServiceRecord)) { 14949 throw new IllegalArgumentException("Invalid service token"); 14950 } 14951 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14952 } 14953 } 14954 14955 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14956 // Refuse possible leaked file descriptors 14957 if (intent != null && intent.hasFileDescriptors() == true) { 14958 throw new IllegalArgumentException("File descriptors passed in Intent"); 14959 } 14960 14961 synchronized(this) { 14962 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14963 } 14964 } 14965 14966 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14967 synchronized(this) { 14968 if (!(token instanceof ServiceRecord)) { 14969 throw new IllegalArgumentException("Invalid service token"); 14970 } 14971 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14972 } 14973 } 14974 14975 // ========================================================= 14976 // BACKUP AND RESTORE 14977 // ========================================================= 14978 14979 // Cause the target app to be launched if necessary and its backup agent 14980 // instantiated. The backup agent will invoke backupAgentCreated() on the 14981 // activity manager to announce its creation. 14982 public boolean bindBackupAgent(String packageName, int backupMode, int userId) { 14983 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode); 14984 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14985 14986 IPackageManager pm = AppGlobals.getPackageManager(); 14987 ApplicationInfo app = null; 14988 try { 14989 app = pm.getApplicationInfo(packageName, 0, userId); 14990 } catch (RemoteException e) { 14991 // can't happen; package manager is process-local 14992 } 14993 if (app == null) { 14994 Slog.w(TAG, "Unable to bind backup agent for " + packageName); 14995 return false; 14996 } 14997 14998 synchronized(this) { 14999 // !!! TODO: currently no check here that we're already bound 15000 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15001 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15002 synchronized (stats) { 15003 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15004 } 15005 15006 // Backup agent is now in use, its package can't be stopped. 15007 try { 15008 AppGlobals.getPackageManager().setPackageStoppedState( 15009 app.packageName, false, UserHandle.getUserId(app.uid)); 15010 } catch (RemoteException e) { 15011 } catch (IllegalArgumentException e) { 15012 Slog.w(TAG, "Failed trying to unstop package " 15013 + app.packageName + ": " + e); 15014 } 15015 15016 BackupRecord r = new BackupRecord(ss, app, backupMode); 15017 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15018 ? new ComponentName(app.packageName, app.backupAgentName) 15019 : new ComponentName("android", "FullBackupAgent"); 15020 // startProcessLocked() returns existing proc's record if it's already running 15021 ProcessRecord proc = startProcessLocked(app.processName, app, 15022 false, 0, "backup", hostingName, false, false, false); 15023 if (proc == null) { 15024 Slog.e(TAG, "Unable to start backup agent process " + r); 15025 return false; 15026 } 15027 15028 r.app = proc; 15029 mBackupTarget = r; 15030 mBackupAppName = app.packageName; 15031 15032 // Try not to kill the process during backup 15033 updateOomAdjLocked(proc); 15034 15035 // If the process is already attached, schedule the creation of the backup agent now. 15036 // If it is not yet live, this will be done when it attaches to the framework. 15037 if (proc.thread != null) { 15038 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15039 try { 15040 proc.thread.scheduleCreateBackupAgent(app, 15041 compatibilityInfoForPackageLocked(app), backupMode); 15042 } catch (RemoteException e) { 15043 // Will time out on the backup manager side 15044 } 15045 } else { 15046 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15047 } 15048 // Invariants: at this point, the target app process exists and the application 15049 // is either already running or in the process of coming up. mBackupTarget and 15050 // mBackupAppName describe the app, so that when it binds back to the AM we 15051 // know that it's scheduled for a backup-agent operation. 15052 } 15053 15054 return true; 15055 } 15056 15057 @Override 15058 public void clearPendingBackup() { 15059 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15060 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15061 15062 synchronized (this) { 15063 mBackupTarget = null; 15064 mBackupAppName = null; 15065 } 15066 } 15067 15068 // A backup agent has just come up 15069 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15070 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15071 + " = " + agent); 15072 15073 synchronized(this) { 15074 if (!agentPackageName.equals(mBackupAppName)) { 15075 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15076 return; 15077 } 15078 } 15079 15080 long oldIdent = Binder.clearCallingIdentity(); 15081 try { 15082 IBackupManager bm = IBackupManager.Stub.asInterface( 15083 ServiceManager.getService(Context.BACKUP_SERVICE)); 15084 bm.agentConnected(agentPackageName, agent); 15085 } catch (RemoteException e) { 15086 // can't happen; the backup manager service is local 15087 } catch (Exception e) { 15088 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15089 e.printStackTrace(); 15090 } finally { 15091 Binder.restoreCallingIdentity(oldIdent); 15092 } 15093 } 15094 15095 // done with this agent 15096 public void unbindBackupAgent(ApplicationInfo appInfo) { 15097 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15098 if (appInfo == null) { 15099 Slog.w(TAG, "unbind backup agent for null app"); 15100 return; 15101 } 15102 15103 synchronized(this) { 15104 try { 15105 if (mBackupAppName == null) { 15106 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15107 return; 15108 } 15109 15110 if (!mBackupAppName.equals(appInfo.packageName)) { 15111 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15112 return; 15113 } 15114 15115 // Not backing this app up any more; reset its OOM adjustment 15116 final ProcessRecord proc = mBackupTarget.app; 15117 updateOomAdjLocked(proc); 15118 15119 // If the app crashed during backup, 'thread' will be null here 15120 if (proc.thread != null) { 15121 try { 15122 proc.thread.scheduleDestroyBackupAgent(appInfo, 15123 compatibilityInfoForPackageLocked(appInfo)); 15124 } catch (Exception e) { 15125 Slog.e(TAG, "Exception when unbinding backup agent:"); 15126 e.printStackTrace(); 15127 } 15128 } 15129 } finally { 15130 mBackupTarget = null; 15131 mBackupAppName = null; 15132 } 15133 } 15134 } 15135 // ========================================================= 15136 // BROADCASTS 15137 // ========================================================= 15138 15139 private final List getStickiesLocked(String action, IntentFilter filter, 15140 List cur, int userId) { 15141 final ContentResolver resolver = mContext.getContentResolver(); 15142 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15143 if (stickies == null) { 15144 return cur; 15145 } 15146 final ArrayList<Intent> list = stickies.get(action); 15147 if (list == null) { 15148 return cur; 15149 } 15150 int N = list.size(); 15151 for (int i=0; i<N; i++) { 15152 Intent intent = list.get(i); 15153 if (filter.match(resolver, intent, true, TAG) >= 0) { 15154 if (cur == null) { 15155 cur = new ArrayList<Intent>(); 15156 } 15157 cur.add(intent); 15158 } 15159 } 15160 return cur; 15161 } 15162 15163 boolean isPendingBroadcastProcessLocked(int pid) { 15164 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15165 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15166 } 15167 15168 void skipPendingBroadcastLocked(int pid) { 15169 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15170 for (BroadcastQueue queue : mBroadcastQueues) { 15171 queue.skipPendingBroadcastLocked(pid); 15172 } 15173 } 15174 15175 // The app just attached; send any pending broadcasts that it should receive 15176 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15177 boolean didSomething = false; 15178 for (BroadcastQueue queue : mBroadcastQueues) { 15179 didSomething |= queue.sendPendingBroadcastsLocked(app); 15180 } 15181 return didSomething; 15182 } 15183 15184 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15185 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15186 enforceNotIsolatedCaller("registerReceiver"); 15187 int callingUid; 15188 int callingPid; 15189 synchronized(this) { 15190 ProcessRecord callerApp = null; 15191 if (caller != null) { 15192 callerApp = getRecordForAppLocked(caller); 15193 if (callerApp == null) { 15194 throw new SecurityException( 15195 "Unable to find app for caller " + caller 15196 + " (pid=" + Binder.getCallingPid() 15197 + ") when registering receiver " + receiver); 15198 } 15199 if (callerApp.info.uid != Process.SYSTEM_UID && 15200 !callerApp.pkgList.containsKey(callerPackage) && 15201 !"android".equals(callerPackage)) { 15202 throw new SecurityException("Given caller package " + callerPackage 15203 + " is not running in process " + callerApp); 15204 } 15205 callingUid = callerApp.info.uid; 15206 callingPid = callerApp.pid; 15207 } else { 15208 callerPackage = null; 15209 callingUid = Binder.getCallingUid(); 15210 callingPid = Binder.getCallingPid(); 15211 } 15212 15213 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15214 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15215 15216 List allSticky = null; 15217 15218 // Look for any matching sticky broadcasts... 15219 Iterator actions = filter.actionsIterator(); 15220 if (actions != null) { 15221 while (actions.hasNext()) { 15222 String action = (String)actions.next(); 15223 allSticky = getStickiesLocked(action, filter, allSticky, 15224 UserHandle.USER_ALL); 15225 allSticky = getStickiesLocked(action, filter, allSticky, 15226 UserHandle.getUserId(callingUid)); 15227 } 15228 } else { 15229 allSticky = getStickiesLocked(null, filter, allSticky, 15230 UserHandle.USER_ALL); 15231 allSticky = getStickiesLocked(null, filter, allSticky, 15232 UserHandle.getUserId(callingUid)); 15233 } 15234 15235 // The first sticky in the list is returned directly back to 15236 // the client. 15237 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15238 15239 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15240 + ": " + sticky); 15241 15242 if (receiver == null) { 15243 return sticky; 15244 } 15245 15246 ReceiverList rl 15247 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15248 if (rl == null) { 15249 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15250 userId, receiver); 15251 if (rl.app != null) { 15252 rl.app.receivers.add(rl); 15253 } else { 15254 try { 15255 receiver.asBinder().linkToDeath(rl, 0); 15256 } catch (RemoteException e) { 15257 return sticky; 15258 } 15259 rl.linkedToDeath = true; 15260 } 15261 mRegisteredReceivers.put(receiver.asBinder(), rl); 15262 } else if (rl.uid != callingUid) { 15263 throw new IllegalArgumentException( 15264 "Receiver requested to register for uid " + callingUid 15265 + " was previously registered for uid " + rl.uid); 15266 } else if (rl.pid != callingPid) { 15267 throw new IllegalArgumentException( 15268 "Receiver requested to register for pid " + callingPid 15269 + " was previously registered for pid " + rl.pid); 15270 } else if (rl.userId != userId) { 15271 throw new IllegalArgumentException( 15272 "Receiver requested to register for user " + userId 15273 + " was previously registered for user " + rl.userId); 15274 } 15275 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15276 permission, callingUid, userId); 15277 rl.add(bf); 15278 if (!bf.debugCheck()) { 15279 Slog.w(TAG, "==> For Dynamic broadast"); 15280 } 15281 mReceiverResolver.addFilter(bf); 15282 15283 // Enqueue broadcasts for all existing stickies that match 15284 // this filter. 15285 if (allSticky != null) { 15286 ArrayList receivers = new ArrayList(); 15287 receivers.add(bf); 15288 15289 int N = allSticky.size(); 15290 for (int i=0; i<N; i++) { 15291 Intent intent = (Intent)allSticky.get(i); 15292 BroadcastQueue queue = broadcastQueueForIntent(intent); 15293 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15294 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15295 null, null, false, true, true, -1); 15296 queue.enqueueParallelBroadcastLocked(r); 15297 queue.scheduleBroadcastsLocked(); 15298 } 15299 } 15300 15301 return sticky; 15302 } 15303 } 15304 15305 public void unregisterReceiver(IIntentReceiver receiver) { 15306 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15307 15308 final long origId = Binder.clearCallingIdentity(); 15309 try { 15310 boolean doTrim = false; 15311 15312 synchronized(this) { 15313 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15314 if (rl != null) { 15315 if (rl.curBroadcast != null) { 15316 BroadcastRecord r = rl.curBroadcast; 15317 final boolean doNext = finishReceiverLocked( 15318 receiver.asBinder(), r.resultCode, r.resultData, 15319 r.resultExtras, r.resultAbort); 15320 if (doNext) { 15321 doTrim = true; 15322 r.queue.processNextBroadcast(false); 15323 } 15324 } 15325 15326 if (rl.app != null) { 15327 rl.app.receivers.remove(rl); 15328 } 15329 removeReceiverLocked(rl); 15330 if (rl.linkedToDeath) { 15331 rl.linkedToDeath = false; 15332 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15333 } 15334 } 15335 } 15336 15337 // If we actually concluded any broadcasts, we might now be able 15338 // to trim the recipients' apps from our working set 15339 if (doTrim) { 15340 trimApplications(); 15341 return; 15342 } 15343 15344 } finally { 15345 Binder.restoreCallingIdentity(origId); 15346 } 15347 } 15348 15349 void removeReceiverLocked(ReceiverList rl) { 15350 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15351 int N = rl.size(); 15352 for (int i=0; i<N; i++) { 15353 mReceiverResolver.removeFilter(rl.get(i)); 15354 } 15355 } 15356 15357 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15358 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15359 ProcessRecord r = mLruProcesses.get(i); 15360 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15361 try { 15362 r.thread.dispatchPackageBroadcast(cmd, packages); 15363 } catch (RemoteException ex) { 15364 } 15365 } 15366 } 15367 } 15368 15369 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15370 int callingUid, int[] users) { 15371 List<ResolveInfo> receivers = null; 15372 try { 15373 HashSet<ComponentName> singleUserReceivers = null; 15374 boolean scannedFirstReceivers = false; 15375 for (int user : users) { 15376 // Skip users that have Shell restrictions 15377 if (callingUid == Process.SHELL_UID 15378 && getUserManagerLocked().hasUserRestriction( 15379 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15380 continue; 15381 } 15382 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15383 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15384 if (user != 0 && newReceivers != null) { 15385 // If this is not the primary user, we need to check for 15386 // any receivers that should be filtered out. 15387 for (int i=0; i<newReceivers.size(); i++) { 15388 ResolveInfo ri = newReceivers.get(i); 15389 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15390 newReceivers.remove(i); 15391 i--; 15392 } 15393 } 15394 } 15395 if (newReceivers != null && newReceivers.size() == 0) { 15396 newReceivers = null; 15397 } 15398 if (receivers == null) { 15399 receivers = newReceivers; 15400 } else if (newReceivers != null) { 15401 // We need to concatenate the additional receivers 15402 // found with what we have do far. This would be easy, 15403 // but we also need to de-dup any receivers that are 15404 // singleUser. 15405 if (!scannedFirstReceivers) { 15406 // Collect any single user receivers we had already retrieved. 15407 scannedFirstReceivers = true; 15408 for (int i=0; i<receivers.size(); i++) { 15409 ResolveInfo ri = receivers.get(i); 15410 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15411 ComponentName cn = new ComponentName( 15412 ri.activityInfo.packageName, ri.activityInfo.name); 15413 if (singleUserReceivers == null) { 15414 singleUserReceivers = new HashSet<ComponentName>(); 15415 } 15416 singleUserReceivers.add(cn); 15417 } 15418 } 15419 } 15420 // Add the new results to the existing results, tracking 15421 // and de-dupping single user receivers. 15422 for (int i=0; i<newReceivers.size(); i++) { 15423 ResolveInfo ri = newReceivers.get(i); 15424 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15425 ComponentName cn = new ComponentName( 15426 ri.activityInfo.packageName, ri.activityInfo.name); 15427 if (singleUserReceivers == null) { 15428 singleUserReceivers = new HashSet<ComponentName>(); 15429 } 15430 if (!singleUserReceivers.contains(cn)) { 15431 singleUserReceivers.add(cn); 15432 receivers.add(ri); 15433 } 15434 } else { 15435 receivers.add(ri); 15436 } 15437 } 15438 } 15439 } 15440 } catch (RemoteException ex) { 15441 // pm is in same process, this will never happen. 15442 } 15443 return receivers; 15444 } 15445 15446 private final int broadcastIntentLocked(ProcessRecord callerApp, 15447 String callerPackage, Intent intent, String resolvedType, 15448 IIntentReceiver resultTo, int resultCode, String resultData, 15449 Bundle map, String requiredPermission, int appOp, 15450 boolean ordered, boolean sticky, int callingPid, int callingUid, 15451 int userId) { 15452 intent = new Intent(intent); 15453 15454 // By default broadcasts do not go to stopped apps. 15455 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15456 15457 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15458 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15459 + " ordered=" + ordered + " userid=" + userId); 15460 if ((resultTo != null) && !ordered) { 15461 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15462 } 15463 15464 userId = handleIncomingUser(callingPid, callingUid, userId, 15465 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15466 15467 // Make sure that the user who is receiving this broadcast is started. 15468 // If not, we will just skip it. 15469 15470 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15471 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15472 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15473 Slog.w(TAG, "Skipping broadcast of " + intent 15474 + ": user " + userId + " is stopped"); 15475 return ActivityManager.BROADCAST_SUCCESS; 15476 } 15477 } 15478 15479 /* 15480 * Prevent non-system code (defined here to be non-persistent 15481 * processes) from sending protected broadcasts. 15482 */ 15483 int callingAppId = UserHandle.getAppId(callingUid); 15484 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15485 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15486 || callingAppId == Process.NFC_UID || callingUid == 0) { 15487 // Always okay. 15488 } else if (callerApp == null || !callerApp.persistent) { 15489 try { 15490 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15491 intent.getAction())) { 15492 String msg = "Permission Denial: not allowed to send broadcast " 15493 + intent.getAction() + " from pid=" 15494 + callingPid + ", uid=" + callingUid; 15495 Slog.w(TAG, msg); 15496 throw new SecurityException(msg); 15497 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15498 // Special case for compatibility: we don't want apps to send this, 15499 // but historically it has not been protected and apps may be using it 15500 // to poke their own app widget. So, instead of making it protected, 15501 // just limit it to the caller. 15502 if (callerApp == null) { 15503 String msg = "Permission Denial: not allowed to send broadcast " 15504 + intent.getAction() + " from unknown caller."; 15505 Slog.w(TAG, msg); 15506 throw new SecurityException(msg); 15507 } else if (intent.getComponent() != null) { 15508 // They are good enough to send to an explicit component... verify 15509 // it is being sent to the calling app. 15510 if (!intent.getComponent().getPackageName().equals( 15511 callerApp.info.packageName)) { 15512 String msg = "Permission Denial: not allowed to send broadcast " 15513 + intent.getAction() + " to " 15514 + intent.getComponent().getPackageName() + " from " 15515 + callerApp.info.packageName; 15516 Slog.w(TAG, msg); 15517 throw new SecurityException(msg); 15518 } 15519 } else { 15520 // Limit broadcast to their own package. 15521 intent.setPackage(callerApp.info.packageName); 15522 } 15523 } 15524 } catch (RemoteException e) { 15525 Slog.w(TAG, "Remote exception", e); 15526 return ActivityManager.BROADCAST_SUCCESS; 15527 } 15528 } 15529 15530 // Handle special intents: if this broadcast is from the package 15531 // manager about a package being removed, we need to remove all of 15532 // its activities from the history stack. 15533 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15534 intent.getAction()); 15535 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15536 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15537 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15538 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15539 || uidRemoved) { 15540 if (checkComponentPermission( 15541 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15542 callingPid, callingUid, -1, true) 15543 == PackageManager.PERMISSION_GRANTED) { 15544 if (uidRemoved) { 15545 final Bundle intentExtras = intent.getExtras(); 15546 final int uid = intentExtras != null 15547 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15548 if (uid >= 0) { 15549 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15550 synchronized (bs) { 15551 bs.removeUidStatsLocked(uid); 15552 } 15553 mAppOpsService.uidRemoved(uid); 15554 } 15555 } else { 15556 // If resources are unavailable just force stop all 15557 // those packages and flush the attribute cache as well. 15558 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15559 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15560 if (list != null && (list.length > 0)) { 15561 for (String pkg : list) { 15562 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15563 "storage unmount"); 15564 } 15565 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15566 sendPackageBroadcastLocked( 15567 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15568 } 15569 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15570 intent.getAction())) { 15571 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15572 } else { 15573 Uri data = intent.getData(); 15574 String ssp; 15575 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15576 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15577 intent.getAction()); 15578 boolean fullUninstall = removed && 15579 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15580 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15581 forceStopPackageLocked(ssp, UserHandle.getAppId( 15582 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15583 false, fullUninstall, userId, 15584 removed ? "pkg removed" : "pkg changed"); 15585 } 15586 if (removed) { 15587 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15588 new String[] {ssp}, userId); 15589 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15590 mAppOpsService.packageRemoved( 15591 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15592 15593 // Remove all permissions granted from/to this package 15594 removeUriPermissionsForPackageLocked(ssp, userId, true); 15595 } 15596 } 15597 } 15598 } 15599 } 15600 } else { 15601 String msg = "Permission Denial: " + intent.getAction() 15602 + " broadcast from " + callerPackage + " (pid=" + callingPid 15603 + ", uid=" + callingUid + ")" 15604 + " requires " 15605 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15606 Slog.w(TAG, msg); 15607 throw new SecurityException(msg); 15608 } 15609 15610 // Special case for adding a package: by default turn on compatibility 15611 // mode. 15612 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15613 Uri data = intent.getData(); 15614 String ssp; 15615 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15616 mCompatModePackages.handlePackageAddedLocked(ssp, 15617 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15618 } 15619 } 15620 15621 /* 15622 * If this is the time zone changed action, queue up a message that will reset the timezone 15623 * of all currently running processes. This message will get queued up before the broadcast 15624 * happens. 15625 */ 15626 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15627 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15628 } 15629 15630 /* 15631 * If the user set the time, let all running processes know. 15632 */ 15633 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15634 final int is24Hour = intent.getBooleanExtra( 15635 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15636 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15637 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15638 synchronized (stats) { 15639 stats.noteCurrentTimeChangedLocked(); 15640 } 15641 } 15642 15643 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15644 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15645 } 15646 15647 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15648 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15649 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15650 } 15651 15652 // Add to the sticky list if requested. 15653 if (sticky) { 15654 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15655 callingPid, callingUid) 15656 != PackageManager.PERMISSION_GRANTED) { 15657 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15658 + callingPid + ", uid=" + callingUid 15659 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15660 Slog.w(TAG, msg); 15661 throw new SecurityException(msg); 15662 } 15663 if (requiredPermission != null) { 15664 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15665 + " and enforce permission " + requiredPermission); 15666 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15667 } 15668 if (intent.getComponent() != null) { 15669 throw new SecurityException( 15670 "Sticky broadcasts can't target a specific component"); 15671 } 15672 // We use userId directly here, since the "all" target is maintained 15673 // as a separate set of sticky broadcasts. 15674 if (userId != UserHandle.USER_ALL) { 15675 // But first, if this is not a broadcast to all users, then 15676 // make sure it doesn't conflict with an existing broadcast to 15677 // all users. 15678 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15679 UserHandle.USER_ALL); 15680 if (stickies != null) { 15681 ArrayList<Intent> list = stickies.get(intent.getAction()); 15682 if (list != null) { 15683 int N = list.size(); 15684 int i; 15685 for (i=0; i<N; i++) { 15686 if (intent.filterEquals(list.get(i))) { 15687 throw new IllegalArgumentException( 15688 "Sticky broadcast " + intent + " for user " 15689 + userId + " conflicts with existing global broadcast"); 15690 } 15691 } 15692 } 15693 } 15694 } 15695 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15696 if (stickies == null) { 15697 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15698 mStickyBroadcasts.put(userId, stickies); 15699 } 15700 ArrayList<Intent> list = stickies.get(intent.getAction()); 15701 if (list == null) { 15702 list = new ArrayList<Intent>(); 15703 stickies.put(intent.getAction(), list); 15704 } 15705 int N = list.size(); 15706 int i; 15707 for (i=0; i<N; i++) { 15708 if (intent.filterEquals(list.get(i))) { 15709 // This sticky already exists, replace it. 15710 list.set(i, new Intent(intent)); 15711 break; 15712 } 15713 } 15714 if (i >= N) { 15715 list.add(new Intent(intent)); 15716 } 15717 } 15718 15719 int[] users; 15720 if (userId == UserHandle.USER_ALL) { 15721 // Caller wants broadcast to go to all started users. 15722 users = mStartedUserArray; 15723 } else { 15724 // Caller wants broadcast to go to one specific user. 15725 users = new int[] {userId}; 15726 } 15727 15728 // Figure out who all will receive this broadcast. 15729 List receivers = null; 15730 List<BroadcastFilter> registeredReceivers = null; 15731 // Need to resolve the intent to interested receivers... 15732 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15733 == 0) { 15734 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15735 } 15736 if (intent.getComponent() == null) { 15737 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15738 // Query one target user at a time, excluding shell-restricted users 15739 UserManagerService ums = getUserManagerLocked(); 15740 for (int i = 0; i < users.length; i++) { 15741 if (ums.hasUserRestriction( 15742 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15743 continue; 15744 } 15745 List<BroadcastFilter> registeredReceiversForUser = 15746 mReceiverResolver.queryIntent(intent, 15747 resolvedType, false, users[i]); 15748 if (registeredReceivers == null) { 15749 registeredReceivers = registeredReceiversForUser; 15750 } else if (registeredReceiversForUser != null) { 15751 registeredReceivers.addAll(registeredReceiversForUser); 15752 } 15753 } 15754 } else { 15755 registeredReceivers = mReceiverResolver.queryIntent(intent, 15756 resolvedType, false, userId); 15757 } 15758 } 15759 15760 final boolean replacePending = 15761 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15762 15763 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15764 + " replacePending=" + replacePending); 15765 15766 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15767 if (!ordered && NR > 0) { 15768 // If we are not serializing this broadcast, then send the 15769 // registered receivers separately so they don't wait for the 15770 // components to be launched. 15771 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15772 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15773 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15774 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15775 ordered, sticky, false, userId); 15776 if (DEBUG_BROADCAST) Slog.v( 15777 TAG, "Enqueueing parallel broadcast " + r); 15778 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15779 if (!replaced) { 15780 queue.enqueueParallelBroadcastLocked(r); 15781 queue.scheduleBroadcastsLocked(); 15782 } 15783 registeredReceivers = null; 15784 NR = 0; 15785 } 15786 15787 // Merge into one list. 15788 int ir = 0; 15789 if (receivers != null) { 15790 // A special case for PACKAGE_ADDED: do not allow the package 15791 // being added to see this broadcast. This prevents them from 15792 // using this as a back door to get run as soon as they are 15793 // installed. Maybe in the future we want to have a special install 15794 // broadcast or such for apps, but we'd like to deliberately make 15795 // this decision. 15796 String skipPackages[] = null; 15797 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15798 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15799 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15800 Uri data = intent.getData(); 15801 if (data != null) { 15802 String pkgName = data.getSchemeSpecificPart(); 15803 if (pkgName != null) { 15804 skipPackages = new String[] { pkgName }; 15805 } 15806 } 15807 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15808 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15809 } 15810 if (skipPackages != null && (skipPackages.length > 0)) { 15811 for (String skipPackage : skipPackages) { 15812 if (skipPackage != null) { 15813 int NT = receivers.size(); 15814 for (int it=0; it<NT; it++) { 15815 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15816 if (curt.activityInfo.packageName.equals(skipPackage)) { 15817 receivers.remove(it); 15818 it--; 15819 NT--; 15820 } 15821 } 15822 } 15823 } 15824 } 15825 15826 int NT = receivers != null ? receivers.size() : 0; 15827 int it = 0; 15828 ResolveInfo curt = null; 15829 BroadcastFilter curr = null; 15830 while (it < NT && ir < NR) { 15831 if (curt == null) { 15832 curt = (ResolveInfo)receivers.get(it); 15833 } 15834 if (curr == null) { 15835 curr = registeredReceivers.get(ir); 15836 } 15837 if (curr.getPriority() >= curt.priority) { 15838 // Insert this broadcast record into the final list. 15839 receivers.add(it, curr); 15840 ir++; 15841 curr = null; 15842 it++; 15843 NT++; 15844 } else { 15845 // Skip to the next ResolveInfo in the final list. 15846 it++; 15847 curt = null; 15848 } 15849 } 15850 } 15851 while (ir < NR) { 15852 if (receivers == null) { 15853 receivers = new ArrayList(); 15854 } 15855 receivers.add(registeredReceivers.get(ir)); 15856 ir++; 15857 } 15858 15859 if ((receivers != null && receivers.size() > 0) 15860 || resultTo != null) { 15861 BroadcastQueue queue = broadcastQueueForIntent(intent); 15862 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15863 callerPackage, callingPid, callingUid, resolvedType, 15864 requiredPermission, appOp, receivers, resultTo, resultCode, 15865 resultData, map, ordered, sticky, false, userId); 15866 if (DEBUG_BROADCAST) Slog.v( 15867 TAG, "Enqueueing ordered broadcast " + r 15868 + ": prev had " + queue.mOrderedBroadcasts.size()); 15869 if (DEBUG_BROADCAST) { 15870 int seq = r.intent.getIntExtra("seq", -1); 15871 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15872 } 15873 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15874 if (!replaced) { 15875 queue.enqueueOrderedBroadcastLocked(r); 15876 queue.scheduleBroadcastsLocked(); 15877 } 15878 } 15879 15880 return ActivityManager.BROADCAST_SUCCESS; 15881 } 15882 15883 final Intent verifyBroadcastLocked(Intent intent) { 15884 // Refuse possible leaked file descriptors 15885 if (intent != null && intent.hasFileDescriptors() == true) { 15886 throw new IllegalArgumentException("File descriptors passed in Intent"); 15887 } 15888 15889 int flags = intent.getFlags(); 15890 15891 if (!mProcessesReady) { 15892 // if the caller really truly claims to know what they're doing, go 15893 // ahead and allow the broadcast without launching any receivers 15894 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15895 intent = new Intent(intent); 15896 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15897 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15898 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15899 + " before boot completion"); 15900 throw new IllegalStateException("Cannot broadcast before boot completed"); 15901 } 15902 } 15903 15904 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15905 throw new IllegalArgumentException( 15906 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15907 } 15908 15909 return intent; 15910 } 15911 15912 public final int broadcastIntent(IApplicationThread caller, 15913 Intent intent, String resolvedType, IIntentReceiver resultTo, 15914 int resultCode, String resultData, Bundle map, 15915 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15916 enforceNotIsolatedCaller("broadcastIntent"); 15917 synchronized(this) { 15918 intent = verifyBroadcastLocked(intent); 15919 15920 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15921 final int callingPid = Binder.getCallingPid(); 15922 final int callingUid = Binder.getCallingUid(); 15923 final long origId = Binder.clearCallingIdentity(); 15924 int res = broadcastIntentLocked(callerApp, 15925 callerApp != null ? callerApp.info.packageName : null, 15926 intent, resolvedType, resultTo, 15927 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15928 callingPid, callingUid, userId); 15929 Binder.restoreCallingIdentity(origId); 15930 return res; 15931 } 15932 } 15933 15934 int broadcastIntentInPackage(String packageName, int uid, 15935 Intent intent, String resolvedType, IIntentReceiver resultTo, 15936 int resultCode, String resultData, Bundle map, 15937 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15938 synchronized(this) { 15939 intent = verifyBroadcastLocked(intent); 15940 15941 final long origId = Binder.clearCallingIdentity(); 15942 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15943 resultTo, resultCode, resultData, map, requiredPermission, 15944 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15945 Binder.restoreCallingIdentity(origId); 15946 return res; 15947 } 15948 } 15949 15950 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15951 // Refuse possible leaked file descriptors 15952 if (intent != null && intent.hasFileDescriptors() == true) { 15953 throw new IllegalArgumentException("File descriptors passed in Intent"); 15954 } 15955 15956 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15957 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15958 15959 synchronized(this) { 15960 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15961 != PackageManager.PERMISSION_GRANTED) { 15962 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15963 + Binder.getCallingPid() 15964 + ", uid=" + Binder.getCallingUid() 15965 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15966 Slog.w(TAG, msg); 15967 throw new SecurityException(msg); 15968 } 15969 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15970 if (stickies != null) { 15971 ArrayList<Intent> list = stickies.get(intent.getAction()); 15972 if (list != null) { 15973 int N = list.size(); 15974 int i; 15975 for (i=0; i<N; i++) { 15976 if (intent.filterEquals(list.get(i))) { 15977 list.remove(i); 15978 break; 15979 } 15980 } 15981 if (list.size() <= 0) { 15982 stickies.remove(intent.getAction()); 15983 } 15984 } 15985 if (stickies.size() <= 0) { 15986 mStickyBroadcasts.remove(userId); 15987 } 15988 } 15989 } 15990 } 15991 15992 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15993 String resultData, Bundle resultExtras, boolean resultAbort) { 15994 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15995 if (r == null) { 15996 Slog.w(TAG, "finishReceiver called but not found on queue"); 15997 return false; 15998 } 15999 16000 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16001 } 16002 16003 void backgroundServicesFinishedLocked(int userId) { 16004 for (BroadcastQueue queue : mBroadcastQueues) { 16005 queue.backgroundServicesFinishedLocked(userId); 16006 } 16007 } 16008 16009 public void finishReceiver(IBinder who, int resultCode, String resultData, 16010 Bundle resultExtras, boolean resultAbort) { 16011 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16012 16013 // Refuse possible leaked file descriptors 16014 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16015 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16016 } 16017 16018 final long origId = Binder.clearCallingIdentity(); 16019 try { 16020 boolean doNext = false; 16021 BroadcastRecord r; 16022 16023 synchronized(this) { 16024 r = broadcastRecordForReceiverLocked(who); 16025 if (r != null) { 16026 doNext = r.queue.finishReceiverLocked(r, resultCode, 16027 resultData, resultExtras, resultAbort, true); 16028 } 16029 } 16030 16031 if (doNext) { 16032 r.queue.processNextBroadcast(false); 16033 } 16034 trimApplications(); 16035 } finally { 16036 Binder.restoreCallingIdentity(origId); 16037 } 16038 } 16039 16040 // ========================================================= 16041 // INSTRUMENTATION 16042 // ========================================================= 16043 16044 public boolean startInstrumentation(ComponentName className, 16045 String profileFile, int flags, Bundle arguments, 16046 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16047 int userId, String abiOverride) { 16048 enforceNotIsolatedCaller("startInstrumentation"); 16049 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16050 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16051 // Refuse possible leaked file descriptors 16052 if (arguments != null && arguments.hasFileDescriptors()) { 16053 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16054 } 16055 16056 synchronized(this) { 16057 InstrumentationInfo ii = null; 16058 ApplicationInfo ai = null; 16059 try { 16060 ii = mContext.getPackageManager().getInstrumentationInfo( 16061 className, STOCK_PM_FLAGS); 16062 ai = AppGlobals.getPackageManager().getApplicationInfo( 16063 ii.targetPackage, STOCK_PM_FLAGS, userId); 16064 } catch (PackageManager.NameNotFoundException e) { 16065 } catch (RemoteException e) { 16066 } 16067 if (ii == null) { 16068 reportStartInstrumentationFailure(watcher, className, 16069 "Unable to find instrumentation info for: " + className); 16070 return false; 16071 } 16072 if (ai == null) { 16073 reportStartInstrumentationFailure(watcher, className, 16074 "Unable to find instrumentation target package: " + ii.targetPackage); 16075 return false; 16076 } 16077 16078 int match = mContext.getPackageManager().checkSignatures( 16079 ii.targetPackage, ii.packageName); 16080 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16081 String msg = "Permission Denial: starting instrumentation " 16082 + className + " from pid=" 16083 + Binder.getCallingPid() 16084 + ", uid=" + Binder.getCallingPid() 16085 + " not allowed because package " + ii.packageName 16086 + " does not have a signature matching the target " 16087 + ii.targetPackage; 16088 reportStartInstrumentationFailure(watcher, className, msg); 16089 throw new SecurityException(msg); 16090 } 16091 16092 final long origId = Binder.clearCallingIdentity(); 16093 // Instrumentation can kill and relaunch even persistent processes 16094 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16095 "start instr"); 16096 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16097 app.instrumentationClass = className; 16098 app.instrumentationInfo = ai; 16099 app.instrumentationProfileFile = profileFile; 16100 app.instrumentationArguments = arguments; 16101 app.instrumentationWatcher = watcher; 16102 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16103 app.instrumentationResultClass = className; 16104 Binder.restoreCallingIdentity(origId); 16105 } 16106 16107 return true; 16108 } 16109 16110 /** 16111 * Report errors that occur while attempting to start Instrumentation. Always writes the 16112 * error to the logs, but if somebody is watching, send the report there too. This enables 16113 * the "am" command to report errors with more information. 16114 * 16115 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16116 * @param cn The component name of the instrumentation. 16117 * @param report The error report. 16118 */ 16119 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16120 ComponentName cn, String report) { 16121 Slog.w(TAG, report); 16122 try { 16123 if (watcher != null) { 16124 Bundle results = new Bundle(); 16125 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16126 results.putString("Error", report); 16127 watcher.instrumentationStatus(cn, -1, results); 16128 } 16129 } catch (RemoteException e) { 16130 Slog.w(TAG, e); 16131 } 16132 } 16133 16134 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16135 if (app.instrumentationWatcher != null) { 16136 try { 16137 // NOTE: IInstrumentationWatcher *must* be oneway here 16138 app.instrumentationWatcher.instrumentationFinished( 16139 app.instrumentationClass, 16140 resultCode, 16141 results); 16142 } catch (RemoteException e) { 16143 } 16144 } 16145 if (app.instrumentationUiAutomationConnection != null) { 16146 try { 16147 app.instrumentationUiAutomationConnection.shutdown(); 16148 } catch (RemoteException re) { 16149 /* ignore */ 16150 } 16151 // Only a UiAutomation can set this flag and now that 16152 // it is finished we make sure it is reset to its default. 16153 mUserIsMonkey = false; 16154 } 16155 app.instrumentationWatcher = null; 16156 app.instrumentationUiAutomationConnection = null; 16157 app.instrumentationClass = null; 16158 app.instrumentationInfo = null; 16159 app.instrumentationProfileFile = null; 16160 app.instrumentationArguments = null; 16161 16162 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16163 "finished inst"); 16164 } 16165 16166 public void finishInstrumentation(IApplicationThread target, 16167 int resultCode, Bundle results) { 16168 int userId = UserHandle.getCallingUserId(); 16169 // Refuse possible leaked file descriptors 16170 if (results != null && results.hasFileDescriptors()) { 16171 throw new IllegalArgumentException("File descriptors passed in Intent"); 16172 } 16173 16174 synchronized(this) { 16175 ProcessRecord app = getRecordForAppLocked(target); 16176 if (app == null) { 16177 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16178 return; 16179 } 16180 final long origId = Binder.clearCallingIdentity(); 16181 finishInstrumentationLocked(app, resultCode, results); 16182 Binder.restoreCallingIdentity(origId); 16183 } 16184 } 16185 16186 // ========================================================= 16187 // CONFIGURATION 16188 // ========================================================= 16189 16190 public ConfigurationInfo getDeviceConfigurationInfo() { 16191 ConfigurationInfo config = new ConfigurationInfo(); 16192 synchronized (this) { 16193 config.reqTouchScreen = mConfiguration.touchscreen; 16194 config.reqKeyboardType = mConfiguration.keyboard; 16195 config.reqNavigation = mConfiguration.navigation; 16196 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16197 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16198 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16199 } 16200 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16201 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16202 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16203 } 16204 config.reqGlEsVersion = GL_ES_VERSION; 16205 } 16206 return config; 16207 } 16208 16209 ActivityStack getFocusedStack() { 16210 return mStackSupervisor.getFocusedStack(); 16211 } 16212 16213 public Configuration getConfiguration() { 16214 Configuration ci; 16215 synchronized(this) { 16216 ci = new Configuration(mConfiguration); 16217 } 16218 return ci; 16219 } 16220 16221 public void updatePersistentConfiguration(Configuration values) { 16222 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16223 "updateConfiguration()"); 16224 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16225 "updateConfiguration()"); 16226 if (values == null) { 16227 throw new NullPointerException("Configuration must not be null"); 16228 } 16229 16230 synchronized(this) { 16231 final long origId = Binder.clearCallingIdentity(); 16232 updateConfigurationLocked(values, null, true, false); 16233 Binder.restoreCallingIdentity(origId); 16234 } 16235 } 16236 16237 public void updateConfiguration(Configuration values) { 16238 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16239 "updateConfiguration()"); 16240 16241 synchronized(this) { 16242 if (values == null && mWindowManager != null) { 16243 // sentinel: fetch the current configuration from the window manager 16244 values = mWindowManager.computeNewConfiguration(); 16245 } 16246 16247 if (mWindowManager != null) { 16248 mProcessList.applyDisplaySize(mWindowManager); 16249 } 16250 16251 final long origId = Binder.clearCallingIdentity(); 16252 if (values != null) { 16253 Settings.System.clearConfiguration(values); 16254 } 16255 updateConfigurationLocked(values, null, false, false); 16256 Binder.restoreCallingIdentity(origId); 16257 } 16258 } 16259 16260 /** 16261 * Do either or both things: (1) change the current configuration, and (2) 16262 * make sure the given activity is running with the (now) current 16263 * configuration. Returns true if the activity has been left running, or 16264 * false if <var>starting</var> is being destroyed to match the new 16265 * configuration. 16266 * @param persistent TODO 16267 */ 16268 boolean updateConfigurationLocked(Configuration values, 16269 ActivityRecord starting, boolean persistent, boolean initLocale) { 16270 int changes = 0; 16271 16272 if (values != null) { 16273 Configuration newConfig = new Configuration(mConfiguration); 16274 changes = newConfig.updateFrom(values); 16275 if (changes != 0) { 16276 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16277 Slog.i(TAG, "Updating configuration to: " + values); 16278 } 16279 16280 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16281 16282 if (values.locale != null && !initLocale) { 16283 saveLocaleLocked(values.locale, 16284 !values.locale.equals(mConfiguration.locale), 16285 values.userSetLocale); 16286 } 16287 16288 mConfigurationSeq++; 16289 if (mConfigurationSeq <= 0) { 16290 mConfigurationSeq = 1; 16291 } 16292 newConfig.seq = mConfigurationSeq; 16293 mConfiguration = newConfig; 16294 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16295 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16296 //mUsageStatsService.noteStartConfig(newConfig); 16297 16298 final Configuration configCopy = new Configuration(mConfiguration); 16299 16300 // TODO: If our config changes, should we auto dismiss any currently 16301 // showing dialogs? 16302 mShowDialogs = shouldShowDialogs(newConfig); 16303 16304 AttributeCache ac = AttributeCache.instance(); 16305 if (ac != null) { 16306 ac.updateConfiguration(configCopy); 16307 } 16308 16309 // Make sure all resources in our process are updated 16310 // right now, so that anyone who is going to retrieve 16311 // resource values after we return will be sure to get 16312 // the new ones. This is especially important during 16313 // boot, where the first config change needs to guarantee 16314 // all resources have that config before following boot 16315 // code is executed. 16316 mSystemThread.applyConfigurationToResources(configCopy); 16317 16318 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16319 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16320 msg.obj = new Configuration(configCopy); 16321 mHandler.sendMessage(msg); 16322 } 16323 16324 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16325 ProcessRecord app = mLruProcesses.get(i); 16326 try { 16327 if (app.thread != null) { 16328 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16329 + app.processName + " new config " + mConfiguration); 16330 app.thread.scheduleConfigurationChanged(configCopy); 16331 } 16332 } catch (Exception e) { 16333 } 16334 } 16335 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16336 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16337 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16338 | Intent.FLAG_RECEIVER_FOREGROUND); 16339 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16340 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16341 Process.SYSTEM_UID, UserHandle.USER_ALL); 16342 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16343 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16344 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16345 broadcastIntentLocked(null, null, intent, 16346 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16347 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16348 } 16349 } 16350 } 16351 16352 boolean kept = true; 16353 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16354 // mainStack is null during startup. 16355 if (mainStack != null) { 16356 if (changes != 0 && starting == null) { 16357 // If the configuration changed, and the caller is not already 16358 // in the process of starting an activity, then find the top 16359 // activity to check if its configuration needs to change. 16360 starting = mainStack.topRunningActivityLocked(null); 16361 } 16362 16363 if (starting != null) { 16364 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16365 // And we need to make sure at this point that all other activities 16366 // are made visible with the correct configuration. 16367 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16368 } 16369 } 16370 16371 if (values != null && mWindowManager != null) { 16372 mWindowManager.setNewConfiguration(mConfiguration); 16373 } 16374 16375 return kept; 16376 } 16377 16378 /** 16379 * Decide based on the configuration whether we should shouw the ANR, 16380 * crash, etc dialogs. The idea is that if there is no affordnace to 16381 * press the on-screen buttons, we shouldn't show the dialog. 16382 * 16383 * A thought: SystemUI might also want to get told about this, the Power 16384 * dialog / global actions also might want different behaviors. 16385 */ 16386 private static final boolean shouldShowDialogs(Configuration config) { 16387 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16388 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16389 } 16390 16391 /** 16392 * Save the locale. You must be inside a synchronized (this) block. 16393 */ 16394 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16395 if(isDiff) { 16396 SystemProperties.set("user.language", l.getLanguage()); 16397 SystemProperties.set("user.region", l.getCountry()); 16398 } 16399 16400 if(isPersist) { 16401 SystemProperties.set("persist.sys.language", l.getLanguage()); 16402 SystemProperties.set("persist.sys.country", l.getCountry()); 16403 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16404 16405 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16406 } 16407 } 16408 16409 @Override 16410 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16411 synchronized (this) { 16412 ActivityRecord srec = ActivityRecord.forToken(token); 16413 if (srec.task != null && srec.task.stack != null) { 16414 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16415 } 16416 } 16417 return false; 16418 } 16419 16420 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16421 Intent resultData) { 16422 16423 synchronized (this) { 16424 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16425 if (stack != null) { 16426 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16427 } 16428 return false; 16429 } 16430 } 16431 16432 public int getLaunchedFromUid(IBinder activityToken) { 16433 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16434 if (srec == null) { 16435 return -1; 16436 } 16437 return srec.launchedFromUid; 16438 } 16439 16440 public String getLaunchedFromPackage(IBinder activityToken) { 16441 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16442 if (srec == null) { 16443 return null; 16444 } 16445 return srec.launchedFromPackage; 16446 } 16447 16448 // ========================================================= 16449 // LIFETIME MANAGEMENT 16450 // ========================================================= 16451 16452 // Returns which broadcast queue the app is the current [or imminent] receiver 16453 // on, or 'null' if the app is not an active broadcast recipient. 16454 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16455 BroadcastRecord r = app.curReceiver; 16456 if (r != null) { 16457 return r.queue; 16458 } 16459 16460 // It's not the current receiver, but it might be starting up to become one 16461 synchronized (this) { 16462 for (BroadcastQueue queue : mBroadcastQueues) { 16463 r = queue.mPendingBroadcast; 16464 if (r != null && r.curApp == app) { 16465 // found it; report which queue it's in 16466 return queue; 16467 } 16468 } 16469 } 16470 16471 return null; 16472 } 16473 16474 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16475 boolean doingAll, long now) { 16476 if (mAdjSeq == app.adjSeq) { 16477 // This adjustment has already been computed. 16478 return app.curRawAdj; 16479 } 16480 16481 if (app.thread == null) { 16482 app.adjSeq = mAdjSeq; 16483 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16484 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16485 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16486 } 16487 16488 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16489 app.adjSource = null; 16490 app.adjTarget = null; 16491 app.empty = false; 16492 app.cached = false; 16493 16494 final int activitiesSize = app.activities.size(); 16495 16496 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16497 // The max adjustment doesn't allow this app to be anything 16498 // below foreground, so it is not worth doing work for it. 16499 app.adjType = "fixed"; 16500 app.adjSeq = mAdjSeq; 16501 app.curRawAdj = app.maxAdj; 16502 app.foregroundActivities = false; 16503 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16504 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16505 // System processes can do UI, and when they do we want to have 16506 // them trim their memory after the user leaves the UI. To 16507 // facilitate this, here we need to determine whether or not it 16508 // is currently showing UI. 16509 app.systemNoUi = true; 16510 if (app == TOP_APP) { 16511 app.systemNoUi = false; 16512 } else if (activitiesSize > 0) { 16513 for (int j = 0; j < activitiesSize; j++) { 16514 final ActivityRecord r = app.activities.get(j); 16515 if (r.visible) { 16516 app.systemNoUi = false; 16517 } 16518 } 16519 } 16520 if (!app.systemNoUi) { 16521 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16522 } 16523 return (app.curAdj=app.maxAdj); 16524 } 16525 16526 app.systemNoUi = false; 16527 16528 // Determine the importance of the process, starting with most 16529 // important to least, and assign an appropriate OOM adjustment. 16530 int adj; 16531 int schedGroup; 16532 int procState; 16533 boolean foregroundActivities = false; 16534 BroadcastQueue queue; 16535 if (app == TOP_APP) { 16536 // The last app on the list is the foreground app. 16537 adj = ProcessList.FOREGROUND_APP_ADJ; 16538 schedGroup = Process.THREAD_GROUP_DEFAULT; 16539 app.adjType = "top-activity"; 16540 foregroundActivities = true; 16541 procState = ActivityManager.PROCESS_STATE_TOP; 16542 } else if (app.instrumentationClass != null) { 16543 // Don't want to kill running instrumentation. 16544 adj = ProcessList.FOREGROUND_APP_ADJ; 16545 schedGroup = Process.THREAD_GROUP_DEFAULT; 16546 app.adjType = "instrumentation"; 16547 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16548 } else if ((queue = isReceivingBroadcast(app)) != null) { 16549 // An app that is currently receiving a broadcast also 16550 // counts as being in the foreground for OOM killer purposes. 16551 // It's placed in a sched group based on the nature of the 16552 // broadcast as reflected by which queue it's active in. 16553 adj = ProcessList.FOREGROUND_APP_ADJ; 16554 schedGroup = (queue == mFgBroadcastQueue) 16555 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16556 app.adjType = "broadcast"; 16557 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16558 } else if (app.executingServices.size() > 0) { 16559 // An app that is currently executing a service callback also 16560 // counts as being in the foreground. 16561 adj = ProcessList.FOREGROUND_APP_ADJ; 16562 schedGroup = app.execServicesFg ? 16563 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16564 app.adjType = "exec-service"; 16565 procState = ActivityManager.PROCESS_STATE_SERVICE; 16566 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16567 } else { 16568 // As far as we know the process is empty. We may change our mind later. 16569 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16570 // At this point we don't actually know the adjustment. Use the cached adj 16571 // value that the caller wants us to. 16572 adj = cachedAdj; 16573 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16574 app.cached = true; 16575 app.empty = true; 16576 app.adjType = "cch-empty"; 16577 } 16578 16579 // Examine all activities if not already foreground. 16580 if (!foregroundActivities && activitiesSize > 0) { 16581 for (int j = 0; j < activitiesSize; j++) { 16582 final ActivityRecord r = app.activities.get(j); 16583 if (r.app != app) { 16584 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16585 + app + "?!?"); 16586 continue; 16587 } 16588 if (r.visible) { 16589 // App has a visible activity; only upgrade adjustment. 16590 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16591 adj = ProcessList.VISIBLE_APP_ADJ; 16592 app.adjType = "visible"; 16593 } 16594 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16595 procState = ActivityManager.PROCESS_STATE_TOP; 16596 } 16597 schedGroup = Process.THREAD_GROUP_DEFAULT; 16598 app.cached = false; 16599 app.empty = false; 16600 foregroundActivities = true; 16601 break; 16602 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16603 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16604 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16605 app.adjType = "pausing"; 16606 } 16607 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16608 procState = ActivityManager.PROCESS_STATE_TOP; 16609 } 16610 schedGroup = Process.THREAD_GROUP_DEFAULT; 16611 app.cached = false; 16612 app.empty = false; 16613 foregroundActivities = true; 16614 } else if (r.state == ActivityState.STOPPING) { 16615 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16616 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16617 app.adjType = "stopping"; 16618 } 16619 // For the process state, we will at this point consider the 16620 // process to be cached. It will be cached either as an activity 16621 // or empty depending on whether the activity is finishing. We do 16622 // this so that we can treat the process as cached for purposes of 16623 // memory trimming (determing current memory level, trim command to 16624 // send to process) since there can be an arbitrary number of stopping 16625 // processes and they should soon all go into the cached state. 16626 if (!r.finishing) { 16627 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16628 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16629 } 16630 } 16631 app.cached = false; 16632 app.empty = false; 16633 foregroundActivities = true; 16634 } else { 16635 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16636 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16637 app.adjType = "cch-act"; 16638 } 16639 } 16640 } 16641 } 16642 16643 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16644 if (app.foregroundServices) { 16645 // The user is aware of this app, so make it visible. 16646 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16647 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16648 app.cached = false; 16649 app.adjType = "fg-service"; 16650 schedGroup = Process.THREAD_GROUP_DEFAULT; 16651 } else if (app.forcingToForeground != null) { 16652 // The user is aware of this app, so make it visible. 16653 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16654 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16655 app.cached = false; 16656 app.adjType = "force-fg"; 16657 app.adjSource = app.forcingToForeground; 16658 schedGroup = Process.THREAD_GROUP_DEFAULT; 16659 } 16660 } 16661 16662 if (app == mHeavyWeightProcess) { 16663 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16664 // We don't want to kill the current heavy-weight process. 16665 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16666 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16667 app.cached = false; 16668 app.adjType = "heavy"; 16669 } 16670 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16671 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16672 } 16673 } 16674 16675 if (app == mHomeProcess) { 16676 if (adj > ProcessList.HOME_APP_ADJ) { 16677 // This process is hosting what we currently consider to be the 16678 // home app, so we don't want to let it go into the background. 16679 adj = ProcessList.HOME_APP_ADJ; 16680 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16681 app.cached = false; 16682 app.adjType = "home"; 16683 } 16684 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16685 procState = ActivityManager.PROCESS_STATE_HOME; 16686 } 16687 } 16688 16689 if (app == mPreviousProcess && app.activities.size() > 0) { 16690 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16691 // This was the previous process that showed UI to the user. 16692 // We want to try to keep it around more aggressively, to give 16693 // a good experience around switching between two apps. 16694 adj = ProcessList.PREVIOUS_APP_ADJ; 16695 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16696 app.cached = false; 16697 app.adjType = "previous"; 16698 } 16699 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16700 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16701 } 16702 } 16703 16704 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16705 + " reason=" + app.adjType); 16706 16707 // By default, we use the computed adjustment. It may be changed if 16708 // there are applications dependent on our services or providers, but 16709 // this gives us a baseline and makes sure we don't get into an 16710 // infinite recursion. 16711 app.adjSeq = mAdjSeq; 16712 app.curRawAdj = adj; 16713 app.hasStartedServices = false; 16714 16715 if (mBackupTarget != null && app == mBackupTarget.app) { 16716 // If possible we want to avoid killing apps while they're being backed up 16717 if (adj > ProcessList.BACKUP_APP_ADJ) { 16718 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16719 adj = ProcessList.BACKUP_APP_ADJ; 16720 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16721 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16722 } 16723 app.adjType = "backup"; 16724 app.cached = false; 16725 } 16726 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16727 procState = ActivityManager.PROCESS_STATE_BACKUP; 16728 } 16729 } 16730 16731 boolean mayBeTop = false; 16732 16733 for (int is = app.services.size()-1; 16734 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16735 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16736 || procState > ActivityManager.PROCESS_STATE_TOP); 16737 is--) { 16738 ServiceRecord s = app.services.valueAt(is); 16739 if (s.startRequested) { 16740 app.hasStartedServices = true; 16741 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16742 procState = ActivityManager.PROCESS_STATE_SERVICE; 16743 } 16744 if (app.hasShownUi && app != mHomeProcess) { 16745 // If this process has shown some UI, let it immediately 16746 // go to the LRU list because it may be pretty heavy with 16747 // UI stuff. We'll tag it with a label just to help 16748 // debug and understand what is going on. 16749 if (adj > ProcessList.SERVICE_ADJ) { 16750 app.adjType = "cch-started-ui-services"; 16751 } 16752 } else { 16753 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16754 // This service has seen some activity within 16755 // recent memory, so we will keep its process ahead 16756 // of the background processes. 16757 if (adj > ProcessList.SERVICE_ADJ) { 16758 adj = ProcessList.SERVICE_ADJ; 16759 app.adjType = "started-services"; 16760 app.cached = false; 16761 } 16762 } 16763 // If we have let the service slide into the background 16764 // state, still have some text describing what it is doing 16765 // even though the service no longer has an impact. 16766 if (adj > ProcessList.SERVICE_ADJ) { 16767 app.adjType = "cch-started-services"; 16768 } 16769 } 16770 } 16771 for (int conni = s.connections.size()-1; 16772 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16773 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16774 || procState > ActivityManager.PROCESS_STATE_TOP); 16775 conni--) { 16776 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16777 for (int i = 0; 16778 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16779 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16780 || procState > ActivityManager.PROCESS_STATE_TOP); 16781 i++) { 16782 // XXX should compute this based on the max of 16783 // all connected clients. 16784 ConnectionRecord cr = clist.get(i); 16785 if (cr.binding.client == app) { 16786 // Binding to ourself is not interesting. 16787 continue; 16788 } 16789 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16790 ProcessRecord client = cr.binding.client; 16791 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16792 TOP_APP, doingAll, now); 16793 int clientProcState = client.curProcState; 16794 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16795 // If the other app is cached for any reason, for purposes here 16796 // we are going to consider it empty. The specific cached state 16797 // doesn't propagate except under certain conditions. 16798 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16799 } 16800 String adjType = null; 16801 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16802 // Not doing bind OOM management, so treat 16803 // this guy more like a started service. 16804 if (app.hasShownUi && app != mHomeProcess) { 16805 // If this process has shown some UI, let it immediately 16806 // go to the LRU list because it may be pretty heavy with 16807 // UI stuff. We'll tag it with a label just to help 16808 // debug and understand what is going on. 16809 if (adj > clientAdj) { 16810 adjType = "cch-bound-ui-services"; 16811 } 16812 app.cached = false; 16813 clientAdj = adj; 16814 clientProcState = procState; 16815 } else { 16816 if (now >= (s.lastActivity 16817 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16818 // This service has not seen activity within 16819 // recent memory, so allow it to drop to the 16820 // LRU list if there is no other reason to keep 16821 // it around. We'll also tag it with a label just 16822 // to help debug and undertand what is going on. 16823 if (adj > clientAdj) { 16824 adjType = "cch-bound-services"; 16825 } 16826 clientAdj = adj; 16827 } 16828 } 16829 } 16830 if (adj > clientAdj) { 16831 // If this process has recently shown UI, and 16832 // the process that is binding to it is less 16833 // important than being visible, then we don't 16834 // care about the binding as much as we care 16835 // about letting this process get into the LRU 16836 // list to be killed and restarted if needed for 16837 // memory. 16838 if (app.hasShownUi && app != mHomeProcess 16839 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16840 adjType = "cch-bound-ui-services"; 16841 } else { 16842 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16843 |Context.BIND_IMPORTANT)) != 0) { 16844 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16845 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16846 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16847 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16848 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16849 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16850 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16851 adj = clientAdj; 16852 } else { 16853 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16854 adj = ProcessList.VISIBLE_APP_ADJ; 16855 } 16856 } 16857 if (!client.cached) { 16858 app.cached = false; 16859 } 16860 adjType = "service"; 16861 } 16862 } 16863 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16864 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16865 schedGroup = Process.THREAD_GROUP_DEFAULT; 16866 } 16867 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16868 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16869 // Special handling of clients who are in the top state. 16870 // We *may* want to consider this process to be in the 16871 // top state as well, but only if there is not another 16872 // reason for it to be running. Being on the top is a 16873 // special state, meaning you are specifically running 16874 // for the current top app. If the process is already 16875 // running in the background for some other reason, it 16876 // is more important to continue considering it to be 16877 // in the background state. 16878 mayBeTop = true; 16879 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16880 } else { 16881 // Special handling for above-top states (persistent 16882 // processes). These should not bring the current process 16883 // into the top state, since they are not on top. Instead 16884 // give them the best state after that. 16885 clientProcState = 16886 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16887 } 16888 } 16889 } else { 16890 if (clientProcState < 16891 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16892 clientProcState = 16893 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16894 } 16895 } 16896 if (procState > clientProcState) { 16897 procState = clientProcState; 16898 } 16899 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16900 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16901 app.pendingUiClean = true; 16902 } 16903 if (adjType != null) { 16904 app.adjType = adjType; 16905 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16906 .REASON_SERVICE_IN_USE; 16907 app.adjSource = cr.binding.client; 16908 app.adjSourceProcState = clientProcState; 16909 app.adjTarget = s.name; 16910 } 16911 } 16912 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16913 app.treatLikeActivity = true; 16914 } 16915 final ActivityRecord a = cr.activity; 16916 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16917 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16918 (a.visible || a.state == ActivityState.RESUMED 16919 || a.state == ActivityState.PAUSING)) { 16920 adj = ProcessList.FOREGROUND_APP_ADJ; 16921 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16922 schedGroup = Process.THREAD_GROUP_DEFAULT; 16923 } 16924 app.cached = false; 16925 app.adjType = "service"; 16926 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16927 .REASON_SERVICE_IN_USE; 16928 app.adjSource = a; 16929 app.adjSourceProcState = procState; 16930 app.adjTarget = s.name; 16931 } 16932 } 16933 } 16934 } 16935 } 16936 16937 for (int provi = app.pubProviders.size()-1; 16938 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16939 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16940 || procState > ActivityManager.PROCESS_STATE_TOP); 16941 provi--) { 16942 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16943 for (int i = cpr.connections.size()-1; 16944 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16945 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16946 || procState > ActivityManager.PROCESS_STATE_TOP); 16947 i--) { 16948 ContentProviderConnection conn = cpr.connections.get(i); 16949 ProcessRecord client = conn.client; 16950 if (client == app) { 16951 // Being our own client is not interesting. 16952 continue; 16953 } 16954 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16955 int clientProcState = client.curProcState; 16956 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16957 // If the other app is cached for any reason, for purposes here 16958 // we are going to consider it empty. 16959 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16960 } 16961 if (adj > clientAdj) { 16962 if (app.hasShownUi && app != mHomeProcess 16963 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16964 app.adjType = "cch-ui-provider"; 16965 } else { 16966 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16967 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16968 app.adjType = "provider"; 16969 } 16970 app.cached &= client.cached; 16971 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16972 .REASON_PROVIDER_IN_USE; 16973 app.adjSource = client; 16974 app.adjSourceProcState = clientProcState; 16975 app.adjTarget = cpr.name; 16976 } 16977 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16978 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16979 // Special handling of clients who are in the top state. 16980 // We *may* want to consider this process to be in the 16981 // top state as well, but only if there is not another 16982 // reason for it to be running. Being on the top is a 16983 // special state, meaning you are specifically running 16984 // for the current top app. If the process is already 16985 // running in the background for some other reason, it 16986 // is more important to continue considering it to be 16987 // in the background state. 16988 mayBeTop = true; 16989 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16990 } else { 16991 // Special handling for above-top states (persistent 16992 // processes). These should not bring the current process 16993 // into the top state, since they are not on top. Instead 16994 // give them the best state after that. 16995 clientProcState = 16996 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16997 } 16998 } 16999 if (procState > clientProcState) { 17000 procState = clientProcState; 17001 } 17002 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17003 schedGroup = Process.THREAD_GROUP_DEFAULT; 17004 } 17005 } 17006 // If the provider has external (non-framework) process 17007 // dependencies, ensure that its adjustment is at least 17008 // FOREGROUND_APP_ADJ. 17009 if (cpr.hasExternalProcessHandles()) { 17010 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17011 adj = ProcessList.FOREGROUND_APP_ADJ; 17012 schedGroup = Process.THREAD_GROUP_DEFAULT; 17013 app.cached = false; 17014 app.adjType = "provider"; 17015 app.adjTarget = cpr.name; 17016 } 17017 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17018 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17019 } 17020 } 17021 } 17022 17023 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17024 // A client of one of our services or providers is in the top state. We 17025 // *may* want to be in the top state, but not if we are already running in 17026 // the background for some other reason. For the decision here, we are going 17027 // to pick out a few specific states that we want to remain in when a client 17028 // is top (states that tend to be longer-term) and otherwise allow it to go 17029 // to the top state. 17030 switch (procState) { 17031 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17032 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17033 case ActivityManager.PROCESS_STATE_SERVICE: 17034 // These all are longer-term states, so pull them up to the top 17035 // of the background states, but not all the way to the top state. 17036 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17037 break; 17038 default: 17039 // Otherwise, top is a better choice, so take it. 17040 procState = ActivityManager.PROCESS_STATE_TOP; 17041 break; 17042 } 17043 } 17044 17045 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17046 if (app.hasClientActivities) { 17047 // This is a cached process, but with client activities. Mark it so. 17048 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17049 app.adjType = "cch-client-act"; 17050 } else if (app.treatLikeActivity) { 17051 // This is a cached process, but somebody wants us to treat it like it has 17052 // an activity, okay! 17053 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17054 app.adjType = "cch-as-act"; 17055 } 17056 } 17057 17058 if (adj == ProcessList.SERVICE_ADJ) { 17059 if (doingAll) { 17060 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17061 mNewNumServiceProcs++; 17062 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17063 if (!app.serviceb) { 17064 // This service isn't far enough down on the LRU list to 17065 // normally be a B service, but if we are low on RAM and it 17066 // is large we want to force it down since we would prefer to 17067 // keep launcher over it. 17068 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17069 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17070 app.serviceHighRam = true; 17071 app.serviceb = true; 17072 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17073 } else { 17074 mNewNumAServiceProcs++; 17075 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17076 } 17077 } else { 17078 app.serviceHighRam = false; 17079 } 17080 } 17081 if (app.serviceb) { 17082 adj = ProcessList.SERVICE_B_ADJ; 17083 } 17084 } 17085 17086 app.curRawAdj = adj; 17087 17088 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17089 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17090 if (adj > app.maxAdj) { 17091 adj = app.maxAdj; 17092 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17093 schedGroup = Process.THREAD_GROUP_DEFAULT; 17094 } 17095 } 17096 17097 // Do final modification to adj. Everything we do between here and applying 17098 // the final setAdj must be done in this function, because we will also use 17099 // it when computing the final cached adj later. Note that we don't need to 17100 // worry about this for max adj above, since max adj will always be used to 17101 // keep it out of the cached vaues. 17102 app.curAdj = app.modifyRawOomAdj(adj); 17103 app.curSchedGroup = schedGroup; 17104 app.curProcState = procState; 17105 app.foregroundActivities = foregroundActivities; 17106 17107 return app.curRawAdj; 17108 } 17109 17110 /** 17111 * Schedule PSS collection of a process. 17112 */ 17113 void requestPssLocked(ProcessRecord proc, int procState) { 17114 if (mPendingPssProcesses.contains(proc)) { 17115 return; 17116 } 17117 if (mPendingPssProcesses.size() == 0) { 17118 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17119 } 17120 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17121 proc.pssProcState = procState; 17122 mPendingPssProcesses.add(proc); 17123 } 17124 17125 /** 17126 * Schedule PSS collection of all processes. 17127 */ 17128 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17129 if (!always) { 17130 if (now < (mLastFullPssTime + 17131 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17132 return; 17133 } 17134 } 17135 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17136 mLastFullPssTime = now; 17137 mFullPssPending = true; 17138 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17139 mPendingPssProcesses.clear(); 17140 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17141 ProcessRecord app = mLruProcesses.get(i); 17142 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17143 app.pssProcState = app.setProcState; 17144 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17145 isSleeping(), now); 17146 mPendingPssProcesses.add(app); 17147 } 17148 } 17149 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17150 } 17151 17152 /** 17153 * Ask a given process to GC right now. 17154 */ 17155 final void performAppGcLocked(ProcessRecord app) { 17156 try { 17157 app.lastRequestedGc = SystemClock.uptimeMillis(); 17158 if (app.thread != null) { 17159 if (app.reportLowMemory) { 17160 app.reportLowMemory = false; 17161 app.thread.scheduleLowMemory(); 17162 } else { 17163 app.thread.processInBackground(); 17164 } 17165 } 17166 } catch (Exception e) { 17167 // whatever. 17168 } 17169 } 17170 17171 /** 17172 * Returns true if things are idle enough to perform GCs. 17173 */ 17174 private final boolean canGcNowLocked() { 17175 boolean processingBroadcasts = false; 17176 for (BroadcastQueue q : mBroadcastQueues) { 17177 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17178 processingBroadcasts = true; 17179 } 17180 } 17181 return !processingBroadcasts 17182 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17183 } 17184 17185 /** 17186 * Perform GCs on all processes that are waiting for it, but only 17187 * if things are idle. 17188 */ 17189 final void performAppGcsLocked() { 17190 final int N = mProcessesToGc.size(); 17191 if (N <= 0) { 17192 return; 17193 } 17194 if (canGcNowLocked()) { 17195 while (mProcessesToGc.size() > 0) { 17196 ProcessRecord proc = mProcessesToGc.remove(0); 17197 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17198 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17199 <= SystemClock.uptimeMillis()) { 17200 // To avoid spamming the system, we will GC processes one 17201 // at a time, waiting a few seconds between each. 17202 performAppGcLocked(proc); 17203 scheduleAppGcsLocked(); 17204 return; 17205 } else { 17206 // It hasn't been long enough since we last GCed this 17207 // process... put it in the list to wait for its time. 17208 addProcessToGcListLocked(proc); 17209 break; 17210 } 17211 } 17212 } 17213 17214 scheduleAppGcsLocked(); 17215 } 17216 } 17217 17218 /** 17219 * If all looks good, perform GCs on all processes waiting for them. 17220 */ 17221 final void performAppGcsIfAppropriateLocked() { 17222 if (canGcNowLocked()) { 17223 performAppGcsLocked(); 17224 return; 17225 } 17226 // Still not idle, wait some more. 17227 scheduleAppGcsLocked(); 17228 } 17229 17230 /** 17231 * Schedule the execution of all pending app GCs. 17232 */ 17233 final void scheduleAppGcsLocked() { 17234 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17235 17236 if (mProcessesToGc.size() > 0) { 17237 // Schedule a GC for the time to the next process. 17238 ProcessRecord proc = mProcessesToGc.get(0); 17239 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17240 17241 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17242 long now = SystemClock.uptimeMillis(); 17243 if (when < (now+GC_TIMEOUT)) { 17244 when = now + GC_TIMEOUT; 17245 } 17246 mHandler.sendMessageAtTime(msg, when); 17247 } 17248 } 17249 17250 /** 17251 * Add a process to the array of processes waiting to be GCed. Keeps the 17252 * list in sorted order by the last GC time. The process can't already be 17253 * on the list. 17254 */ 17255 final void addProcessToGcListLocked(ProcessRecord proc) { 17256 boolean added = false; 17257 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17258 if (mProcessesToGc.get(i).lastRequestedGc < 17259 proc.lastRequestedGc) { 17260 added = true; 17261 mProcessesToGc.add(i+1, proc); 17262 break; 17263 } 17264 } 17265 if (!added) { 17266 mProcessesToGc.add(0, proc); 17267 } 17268 } 17269 17270 /** 17271 * Set up to ask a process to GC itself. This will either do it 17272 * immediately, or put it on the list of processes to gc the next 17273 * time things are idle. 17274 */ 17275 final void scheduleAppGcLocked(ProcessRecord app) { 17276 long now = SystemClock.uptimeMillis(); 17277 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17278 return; 17279 } 17280 if (!mProcessesToGc.contains(app)) { 17281 addProcessToGcListLocked(app); 17282 scheduleAppGcsLocked(); 17283 } 17284 } 17285 17286 final void checkExcessivePowerUsageLocked(boolean doKills) { 17287 updateCpuStatsNow(); 17288 17289 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17290 boolean doWakeKills = doKills; 17291 boolean doCpuKills = doKills; 17292 if (mLastPowerCheckRealtime == 0) { 17293 doWakeKills = false; 17294 } 17295 if (mLastPowerCheckUptime == 0) { 17296 doCpuKills = false; 17297 } 17298 if (stats.isScreenOn()) { 17299 doWakeKills = false; 17300 } 17301 final long curRealtime = SystemClock.elapsedRealtime(); 17302 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17303 final long curUptime = SystemClock.uptimeMillis(); 17304 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17305 mLastPowerCheckRealtime = curRealtime; 17306 mLastPowerCheckUptime = curUptime; 17307 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17308 doWakeKills = false; 17309 } 17310 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17311 doCpuKills = false; 17312 } 17313 int i = mLruProcesses.size(); 17314 while (i > 0) { 17315 i--; 17316 ProcessRecord app = mLruProcesses.get(i); 17317 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17318 long wtime; 17319 synchronized (stats) { 17320 wtime = stats.getProcessWakeTime(app.info.uid, 17321 app.pid, curRealtime); 17322 } 17323 long wtimeUsed = wtime - app.lastWakeTime; 17324 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17325 if (DEBUG_POWER) { 17326 StringBuilder sb = new StringBuilder(128); 17327 sb.append("Wake for "); 17328 app.toShortString(sb); 17329 sb.append(": over "); 17330 TimeUtils.formatDuration(realtimeSince, sb); 17331 sb.append(" used "); 17332 TimeUtils.formatDuration(wtimeUsed, sb); 17333 sb.append(" ("); 17334 sb.append((wtimeUsed*100)/realtimeSince); 17335 sb.append("%)"); 17336 Slog.i(TAG, sb.toString()); 17337 sb.setLength(0); 17338 sb.append("CPU for "); 17339 app.toShortString(sb); 17340 sb.append(": over "); 17341 TimeUtils.formatDuration(uptimeSince, sb); 17342 sb.append(" used "); 17343 TimeUtils.formatDuration(cputimeUsed, sb); 17344 sb.append(" ("); 17345 sb.append((cputimeUsed*100)/uptimeSince); 17346 sb.append("%)"); 17347 Slog.i(TAG, sb.toString()); 17348 } 17349 // If a process has held a wake lock for more 17350 // than 50% of the time during this period, 17351 // that sounds bad. Kill! 17352 if (doWakeKills && realtimeSince > 0 17353 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17354 synchronized (stats) { 17355 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17356 realtimeSince, wtimeUsed); 17357 } 17358 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17359 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17360 } else if (doCpuKills && uptimeSince > 0 17361 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17362 synchronized (stats) { 17363 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17364 uptimeSince, cputimeUsed); 17365 } 17366 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17367 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17368 } else { 17369 app.lastWakeTime = wtime; 17370 app.lastCpuTime = app.curCpuTime; 17371 } 17372 } 17373 } 17374 } 17375 17376 private final boolean applyOomAdjLocked(ProcessRecord app, 17377 ProcessRecord TOP_APP, boolean doingAll, long now) { 17378 boolean success = true; 17379 17380 if (app.curRawAdj != app.setRawAdj) { 17381 app.setRawAdj = app.curRawAdj; 17382 } 17383 17384 int changes = 0; 17385 17386 if (app.curAdj != app.setAdj) { 17387 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17388 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17389 TAG, "Set " + app.pid + " " + app.processName + 17390 " adj " + app.curAdj + ": " + app.adjType); 17391 app.setAdj = app.curAdj; 17392 } 17393 17394 if (app.setSchedGroup != app.curSchedGroup) { 17395 app.setSchedGroup = app.curSchedGroup; 17396 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17397 "Setting process group of " + app.processName 17398 + " to " + app.curSchedGroup); 17399 if (app.waitingToKill != null && 17400 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17401 app.kill(app.waitingToKill, true); 17402 success = false; 17403 } else { 17404 if (true) { 17405 long oldId = Binder.clearCallingIdentity(); 17406 try { 17407 Process.setProcessGroup(app.pid, app.curSchedGroup); 17408 } catch (Exception e) { 17409 Slog.w(TAG, "Failed setting process group of " + app.pid 17410 + " to " + app.curSchedGroup); 17411 e.printStackTrace(); 17412 } finally { 17413 Binder.restoreCallingIdentity(oldId); 17414 } 17415 } else { 17416 if (app.thread != null) { 17417 try { 17418 app.thread.setSchedulingGroup(app.curSchedGroup); 17419 } catch (RemoteException e) { 17420 } 17421 } 17422 } 17423 Process.setSwappiness(app.pid, 17424 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17425 } 17426 } 17427 if (app.repForegroundActivities != app.foregroundActivities) { 17428 app.repForegroundActivities = app.foregroundActivities; 17429 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17430 } 17431 if (app.repProcState != app.curProcState) { 17432 app.repProcState = app.curProcState; 17433 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17434 if (app.thread != null) { 17435 try { 17436 if (false) { 17437 //RuntimeException h = new RuntimeException("here"); 17438 Slog.i(TAG, "Sending new process state " + app.repProcState 17439 + " to " + app /*, h*/); 17440 } 17441 app.thread.setProcessState(app.repProcState); 17442 } catch (RemoteException e) { 17443 } 17444 } 17445 } 17446 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17447 app.setProcState)) { 17448 app.lastStateTime = now; 17449 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17450 isSleeping(), now); 17451 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17452 + ProcessList.makeProcStateString(app.setProcState) + " to " 17453 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17454 + (app.nextPssTime-now) + ": " + app); 17455 } else { 17456 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17457 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17458 requestPssLocked(app, app.setProcState); 17459 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17460 isSleeping(), now); 17461 } else if (false && DEBUG_PSS) { 17462 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17463 } 17464 } 17465 if (app.setProcState != app.curProcState) { 17466 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17467 "Proc state change of " + app.processName 17468 + " to " + app.curProcState); 17469 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17470 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17471 if (setImportant && !curImportant) { 17472 // This app is no longer something we consider important enough to allow to 17473 // use arbitrary amounts of battery power. Note 17474 // its current wake lock time to later know to kill it if 17475 // it is not behaving well. 17476 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17477 synchronized (stats) { 17478 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17479 app.pid, SystemClock.elapsedRealtime()); 17480 } 17481 app.lastCpuTime = app.curCpuTime; 17482 17483 } 17484 app.setProcState = app.curProcState; 17485 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17486 app.notCachedSinceIdle = false; 17487 } 17488 if (!doingAll) { 17489 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17490 } else { 17491 app.procStateChanged = true; 17492 } 17493 } 17494 17495 if (changes != 0) { 17496 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17497 int i = mPendingProcessChanges.size()-1; 17498 ProcessChangeItem item = null; 17499 while (i >= 0) { 17500 item = mPendingProcessChanges.get(i); 17501 if (item.pid == app.pid) { 17502 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17503 break; 17504 } 17505 i--; 17506 } 17507 if (i < 0) { 17508 // No existing item in pending changes; need a new one. 17509 final int NA = mAvailProcessChanges.size(); 17510 if (NA > 0) { 17511 item = mAvailProcessChanges.remove(NA-1); 17512 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17513 } else { 17514 item = new ProcessChangeItem(); 17515 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17516 } 17517 item.changes = 0; 17518 item.pid = app.pid; 17519 item.uid = app.info.uid; 17520 if (mPendingProcessChanges.size() == 0) { 17521 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17522 "*** Enqueueing dispatch processes changed!"); 17523 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17524 } 17525 mPendingProcessChanges.add(item); 17526 } 17527 item.changes |= changes; 17528 item.processState = app.repProcState; 17529 item.foregroundActivities = app.repForegroundActivities; 17530 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17531 + Integer.toHexString(System.identityHashCode(item)) 17532 + " " + app.toShortString() + ": changes=" + item.changes 17533 + " procState=" + item.processState 17534 + " foreground=" + item.foregroundActivities 17535 + " type=" + app.adjType + " source=" + app.adjSource 17536 + " target=" + app.adjTarget); 17537 } 17538 17539 return success; 17540 } 17541 17542 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17543 if (proc.thread != null) { 17544 if (proc.baseProcessTracker != null) { 17545 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17546 } 17547 if (proc.repProcState >= 0) { 17548 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17549 proc.repProcState); 17550 } 17551 } 17552 } 17553 17554 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17555 ProcessRecord TOP_APP, boolean doingAll, long now) { 17556 if (app.thread == null) { 17557 return false; 17558 } 17559 17560 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17561 17562 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17563 } 17564 17565 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17566 boolean oomAdj) { 17567 if (isForeground != proc.foregroundServices) { 17568 proc.foregroundServices = isForeground; 17569 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17570 proc.info.uid); 17571 if (isForeground) { 17572 if (curProcs == null) { 17573 curProcs = new ArrayList<ProcessRecord>(); 17574 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17575 } 17576 if (!curProcs.contains(proc)) { 17577 curProcs.add(proc); 17578 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17579 proc.info.packageName, proc.info.uid); 17580 } 17581 } else { 17582 if (curProcs != null) { 17583 if (curProcs.remove(proc)) { 17584 mBatteryStatsService.noteEvent( 17585 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17586 proc.info.packageName, proc.info.uid); 17587 if (curProcs.size() <= 0) { 17588 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17589 } 17590 } 17591 } 17592 } 17593 if (oomAdj) { 17594 updateOomAdjLocked(); 17595 } 17596 } 17597 } 17598 17599 private final ActivityRecord resumedAppLocked() { 17600 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17601 String pkg; 17602 int uid; 17603 if (act != null) { 17604 pkg = act.packageName; 17605 uid = act.info.applicationInfo.uid; 17606 } else { 17607 pkg = null; 17608 uid = -1; 17609 } 17610 // Has the UID or resumed package name changed? 17611 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17612 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17613 if (mCurResumedPackage != null) { 17614 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17615 mCurResumedPackage, mCurResumedUid); 17616 } 17617 mCurResumedPackage = pkg; 17618 mCurResumedUid = uid; 17619 if (mCurResumedPackage != null) { 17620 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17621 mCurResumedPackage, mCurResumedUid); 17622 } 17623 } 17624 return act; 17625 } 17626 17627 final boolean updateOomAdjLocked(ProcessRecord app) { 17628 final ActivityRecord TOP_ACT = resumedAppLocked(); 17629 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17630 final boolean wasCached = app.cached; 17631 17632 mAdjSeq++; 17633 17634 // This is the desired cached adjusment we want to tell it to use. 17635 // If our app is currently cached, we know it, and that is it. Otherwise, 17636 // we don't know it yet, and it needs to now be cached we will then 17637 // need to do a complete oom adj. 17638 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17639 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17640 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17641 SystemClock.uptimeMillis()); 17642 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17643 // Changed to/from cached state, so apps after it in the LRU 17644 // list may also be changed. 17645 updateOomAdjLocked(); 17646 } 17647 return success; 17648 } 17649 17650 final void updateOomAdjLocked() { 17651 final ActivityRecord TOP_ACT = resumedAppLocked(); 17652 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17653 final long now = SystemClock.uptimeMillis(); 17654 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17655 final int N = mLruProcesses.size(); 17656 17657 if (false) { 17658 RuntimeException e = new RuntimeException(); 17659 e.fillInStackTrace(); 17660 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17661 } 17662 17663 mAdjSeq++; 17664 mNewNumServiceProcs = 0; 17665 mNewNumAServiceProcs = 0; 17666 17667 final int emptyProcessLimit; 17668 final int cachedProcessLimit; 17669 if (mProcessLimit <= 0) { 17670 emptyProcessLimit = cachedProcessLimit = 0; 17671 } else if (mProcessLimit == 1) { 17672 emptyProcessLimit = 1; 17673 cachedProcessLimit = 0; 17674 } else { 17675 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17676 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17677 } 17678 17679 // Let's determine how many processes we have running vs. 17680 // how many slots we have for background processes; we may want 17681 // to put multiple processes in a slot of there are enough of 17682 // them. 17683 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17684 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17685 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17686 if (numEmptyProcs > cachedProcessLimit) { 17687 // If there are more empty processes than our limit on cached 17688 // processes, then use the cached process limit for the factor. 17689 // This ensures that the really old empty processes get pushed 17690 // down to the bottom, so if we are running low on memory we will 17691 // have a better chance at keeping around more cached processes 17692 // instead of a gazillion empty processes. 17693 numEmptyProcs = cachedProcessLimit; 17694 } 17695 int emptyFactor = numEmptyProcs/numSlots; 17696 if (emptyFactor < 1) emptyFactor = 1; 17697 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17698 if (cachedFactor < 1) cachedFactor = 1; 17699 int stepCached = 0; 17700 int stepEmpty = 0; 17701 int numCached = 0; 17702 int numEmpty = 0; 17703 int numTrimming = 0; 17704 17705 mNumNonCachedProcs = 0; 17706 mNumCachedHiddenProcs = 0; 17707 17708 // First update the OOM adjustment for each of the 17709 // application processes based on their current state. 17710 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17711 int nextCachedAdj = curCachedAdj+1; 17712 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17713 int nextEmptyAdj = curEmptyAdj+2; 17714 for (int i=N-1; i>=0; i--) { 17715 ProcessRecord app = mLruProcesses.get(i); 17716 if (!app.killedByAm && app.thread != null) { 17717 app.procStateChanged = false; 17718 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17719 17720 // If we haven't yet assigned the final cached adj 17721 // to the process, do that now. 17722 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17723 switch (app.curProcState) { 17724 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17725 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17726 // This process is a cached process holding activities... 17727 // assign it the next cached value for that type, and then 17728 // step that cached level. 17729 app.curRawAdj = curCachedAdj; 17730 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17731 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17732 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17733 + ")"); 17734 if (curCachedAdj != nextCachedAdj) { 17735 stepCached++; 17736 if (stepCached >= cachedFactor) { 17737 stepCached = 0; 17738 curCachedAdj = nextCachedAdj; 17739 nextCachedAdj += 2; 17740 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17741 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17742 } 17743 } 17744 } 17745 break; 17746 default: 17747 // For everything else, assign next empty cached process 17748 // level and bump that up. Note that this means that 17749 // long-running services that have dropped down to the 17750 // cached level will be treated as empty (since their process 17751 // state is still as a service), which is what we want. 17752 app.curRawAdj = curEmptyAdj; 17753 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17754 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17755 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17756 + ")"); 17757 if (curEmptyAdj != nextEmptyAdj) { 17758 stepEmpty++; 17759 if (stepEmpty >= emptyFactor) { 17760 stepEmpty = 0; 17761 curEmptyAdj = nextEmptyAdj; 17762 nextEmptyAdj += 2; 17763 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17764 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17765 } 17766 } 17767 } 17768 break; 17769 } 17770 } 17771 17772 applyOomAdjLocked(app, TOP_APP, true, now); 17773 17774 // Count the number of process types. 17775 switch (app.curProcState) { 17776 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17777 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17778 mNumCachedHiddenProcs++; 17779 numCached++; 17780 if (numCached > cachedProcessLimit) { 17781 app.kill("cached #" + numCached, true); 17782 } 17783 break; 17784 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17785 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17786 && app.lastActivityTime < oldTime) { 17787 app.kill("empty for " 17788 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17789 / 1000) + "s", true); 17790 } else { 17791 numEmpty++; 17792 if (numEmpty > emptyProcessLimit) { 17793 app.kill("empty #" + numEmpty, true); 17794 } 17795 } 17796 break; 17797 default: 17798 mNumNonCachedProcs++; 17799 break; 17800 } 17801 17802 if (app.isolated && app.services.size() <= 0) { 17803 // If this is an isolated process, and there are no 17804 // services running in it, then the process is no longer 17805 // needed. We agressively kill these because we can by 17806 // definition not re-use the same process again, and it is 17807 // good to avoid having whatever code was running in them 17808 // left sitting around after no longer needed. 17809 app.kill("isolated not needed", true); 17810 } 17811 17812 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17813 && !app.killedByAm) { 17814 numTrimming++; 17815 } 17816 } 17817 } 17818 17819 mNumServiceProcs = mNewNumServiceProcs; 17820 17821 // Now determine the memory trimming level of background processes. 17822 // Unfortunately we need to start at the back of the list to do this 17823 // properly. We only do this if the number of background apps we 17824 // are managing to keep around is less than half the maximum we desire; 17825 // if we are keeping a good number around, we'll let them use whatever 17826 // memory they want. 17827 final int numCachedAndEmpty = numCached + numEmpty; 17828 int memFactor; 17829 if (numCached <= ProcessList.TRIM_CACHED_APPS 17830 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17831 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17832 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17833 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17834 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17835 } else { 17836 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17837 } 17838 } else { 17839 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17840 } 17841 // We always allow the memory level to go up (better). We only allow it to go 17842 // down if we are in a state where that is allowed, *and* the total number of processes 17843 // has gone down since last time. 17844 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17845 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17846 + " last=" + mLastNumProcesses); 17847 if (memFactor > mLastMemoryLevel) { 17848 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17849 memFactor = mLastMemoryLevel; 17850 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17851 } 17852 } 17853 mLastMemoryLevel = memFactor; 17854 mLastNumProcesses = mLruProcesses.size(); 17855 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17856 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17857 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17858 if (mLowRamStartTime == 0) { 17859 mLowRamStartTime = now; 17860 } 17861 int step = 0; 17862 int fgTrimLevel; 17863 switch (memFactor) { 17864 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17865 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17866 break; 17867 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17868 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17869 break; 17870 default: 17871 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17872 break; 17873 } 17874 int factor = numTrimming/3; 17875 int minFactor = 2; 17876 if (mHomeProcess != null) minFactor++; 17877 if (mPreviousProcess != null) minFactor++; 17878 if (factor < minFactor) factor = minFactor; 17879 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17880 for (int i=N-1; i>=0; i--) { 17881 ProcessRecord app = mLruProcesses.get(i); 17882 if (allChanged || app.procStateChanged) { 17883 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17884 app.procStateChanged = false; 17885 } 17886 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17887 && !app.killedByAm) { 17888 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17889 try { 17890 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17891 "Trimming memory of " + app.processName 17892 + " to " + curLevel); 17893 app.thread.scheduleTrimMemory(curLevel); 17894 } catch (RemoteException e) { 17895 } 17896 if (false) { 17897 // For now we won't do this; our memory trimming seems 17898 // to be good enough at this point that destroying 17899 // activities causes more harm than good. 17900 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17901 && app != mHomeProcess && app != mPreviousProcess) { 17902 // Need to do this on its own message because the stack may not 17903 // be in a consistent state at this point. 17904 // For these apps we will also finish their activities 17905 // to help them free memory. 17906 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17907 } 17908 } 17909 } 17910 app.trimMemoryLevel = curLevel; 17911 step++; 17912 if (step >= factor) { 17913 step = 0; 17914 switch (curLevel) { 17915 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17916 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17917 break; 17918 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17919 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17920 break; 17921 } 17922 } 17923 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17924 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17925 && app.thread != null) { 17926 try { 17927 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17928 "Trimming memory of heavy-weight " + app.processName 17929 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17930 app.thread.scheduleTrimMemory( 17931 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17932 } catch (RemoteException e) { 17933 } 17934 } 17935 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17936 } else { 17937 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17938 || app.systemNoUi) && app.pendingUiClean) { 17939 // If this application is now in the background and it 17940 // had done UI, then give it the special trim level to 17941 // have it free UI resources. 17942 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17943 if (app.trimMemoryLevel < level && app.thread != null) { 17944 try { 17945 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17946 "Trimming memory of bg-ui " + app.processName 17947 + " to " + level); 17948 app.thread.scheduleTrimMemory(level); 17949 } catch (RemoteException e) { 17950 } 17951 } 17952 app.pendingUiClean = false; 17953 } 17954 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17955 try { 17956 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17957 "Trimming memory of fg " + app.processName 17958 + " to " + fgTrimLevel); 17959 app.thread.scheduleTrimMemory(fgTrimLevel); 17960 } catch (RemoteException e) { 17961 } 17962 } 17963 app.trimMemoryLevel = fgTrimLevel; 17964 } 17965 } 17966 } else { 17967 if (mLowRamStartTime != 0) { 17968 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17969 mLowRamStartTime = 0; 17970 } 17971 for (int i=N-1; i>=0; i--) { 17972 ProcessRecord app = mLruProcesses.get(i); 17973 if (allChanged || app.procStateChanged) { 17974 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17975 app.procStateChanged = false; 17976 } 17977 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17978 || app.systemNoUi) && app.pendingUiClean) { 17979 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17980 && app.thread != null) { 17981 try { 17982 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17983 "Trimming memory of ui hidden " + app.processName 17984 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17985 app.thread.scheduleTrimMemory( 17986 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17987 } catch (RemoteException e) { 17988 } 17989 } 17990 app.pendingUiClean = false; 17991 } 17992 app.trimMemoryLevel = 0; 17993 } 17994 } 17995 17996 if (mAlwaysFinishActivities) { 17997 // Need to do this on its own message because the stack may not 17998 // be in a consistent state at this point. 17999 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18000 } 18001 18002 if (allChanged) { 18003 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18004 } 18005 18006 if (mProcessStats.shouldWriteNowLocked(now)) { 18007 mHandler.post(new Runnable() { 18008 @Override public void run() { 18009 synchronized (ActivityManagerService.this) { 18010 mProcessStats.writeStateAsyncLocked(); 18011 } 18012 } 18013 }); 18014 } 18015 18016 if (DEBUG_OOM_ADJ) { 18017 if (false) { 18018 RuntimeException here = new RuntimeException("here"); 18019 here.fillInStackTrace(); 18020 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18021 } else { 18022 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18023 } 18024 } 18025 } 18026 18027 final void trimApplications() { 18028 synchronized (this) { 18029 int i; 18030 18031 // First remove any unused application processes whose package 18032 // has been removed. 18033 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18034 final ProcessRecord app = mRemovedProcesses.get(i); 18035 if (app.activities.size() == 0 18036 && app.curReceiver == null && app.services.size() == 0) { 18037 Slog.i( 18038 TAG, "Exiting empty application process " 18039 + app.processName + " (" 18040 + (app.thread != null ? app.thread.asBinder() : null) 18041 + ")\n"); 18042 if (app.pid > 0 && app.pid != MY_PID) { 18043 app.kill("empty", false); 18044 } else { 18045 try { 18046 app.thread.scheduleExit(); 18047 } catch (Exception e) { 18048 // Ignore exceptions. 18049 } 18050 } 18051 cleanUpApplicationRecordLocked(app, false, true, -1); 18052 mRemovedProcesses.remove(i); 18053 18054 if (app.persistent) { 18055 addAppLocked(app.info, false, null /* ABI override */); 18056 } 18057 } 18058 } 18059 18060 // Now update the oom adj for all processes. 18061 updateOomAdjLocked(); 18062 } 18063 } 18064 18065 /** This method sends the specified signal to each of the persistent apps */ 18066 public void signalPersistentProcesses(int sig) throws RemoteException { 18067 if (sig != Process.SIGNAL_USR1) { 18068 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18069 } 18070 18071 synchronized (this) { 18072 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18073 != PackageManager.PERMISSION_GRANTED) { 18074 throw new SecurityException("Requires permission " 18075 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18076 } 18077 18078 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18079 ProcessRecord r = mLruProcesses.get(i); 18080 if (r.thread != null && r.persistent) { 18081 Process.sendSignal(r.pid, sig); 18082 } 18083 } 18084 } 18085 } 18086 18087 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18088 if (proc == null || proc == mProfileProc) { 18089 proc = mProfileProc; 18090 profileType = mProfileType; 18091 clearProfilerLocked(); 18092 } 18093 if (proc == null) { 18094 return; 18095 } 18096 try { 18097 proc.thread.profilerControl(false, null, profileType); 18098 } catch (RemoteException e) { 18099 throw new IllegalStateException("Process disappeared"); 18100 } 18101 } 18102 18103 private void clearProfilerLocked() { 18104 if (mProfileFd != null) { 18105 try { 18106 mProfileFd.close(); 18107 } catch (IOException e) { 18108 } 18109 } 18110 mProfileApp = null; 18111 mProfileProc = null; 18112 mProfileFile = null; 18113 mProfileType = 0; 18114 mAutoStopProfiler = false; 18115 mSamplingInterval = 0; 18116 } 18117 18118 public boolean profileControl(String process, int userId, boolean start, 18119 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18120 18121 try { 18122 synchronized (this) { 18123 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18124 // its own permission. 18125 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18126 != PackageManager.PERMISSION_GRANTED) { 18127 throw new SecurityException("Requires permission " 18128 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18129 } 18130 18131 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18132 throw new IllegalArgumentException("null profile info or fd"); 18133 } 18134 18135 ProcessRecord proc = null; 18136 if (process != null) { 18137 proc = findProcessLocked(process, userId, "profileControl"); 18138 } 18139 18140 if (start && (proc == null || proc.thread == null)) { 18141 throw new IllegalArgumentException("Unknown process: " + process); 18142 } 18143 18144 if (start) { 18145 stopProfilerLocked(null, 0); 18146 setProfileApp(proc.info, proc.processName, profilerInfo); 18147 mProfileProc = proc; 18148 mProfileType = profileType; 18149 ParcelFileDescriptor fd = profilerInfo.profileFd; 18150 try { 18151 fd = fd.dup(); 18152 } catch (IOException e) { 18153 fd = null; 18154 } 18155 profilerInfo.profileFd = fd; 18156 proc.thread.profilerControl(start, profilerInfo, profileType); 18157 fd = null; 18158 mProfileFd = null; 18159 } else { 18160 stopProfilerLocked(proc, profileType); 18161 if (profilerInfo != null && profilerInfo.profileFd != null) { 18162 try { 18163 profilerInfo.profileFd.close(); 18164 } catch (IOException e) { 18165 } 18166 } 18167 } 18168 18169 return true; 18170 } 18171 } catch (RemoteException e) { 18172 throw new IllegalStateException("Process disappeared"); 18173 } finally { 18174 if (profilerInfo != null && profilerInfo.profileFd != null) { 18175 try { 18176 profilerInfo.profileFd.close(); 18177 } catch (IOException e) { 18178 } 18179 } 18180 } 18181 } 18182 18183 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18184 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18185 userId, true, ALLOW_FULL_ONLY, callName, null); 18186 ProcessRecord proc = null; 18187 try { 18188 int pid = Integer.parseInt(process); 18189 synchronized (mPidsSelfLocked) { 18190 proc = mPidsSelfLocked.get(pid); 18191 } 18192 } catch (NumberFormatException e) { 18193 } 18194 18195 if (proc == null) { 18196 ArrayMap<String, SparseArray<ProcessRecord>> all 18197 = mProcessNames.getMap(); 18198 SparseArray<ProcessRecord> procs = all.get(process); 18199 if (procs != null && procs.size() > 0) { 18200 proc = procs.valueAt(0); 18201 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18202 for (int i=1; i<procs.size(); i++) { 18203 ProcessRecord thisProc = procs.valueAt(i); 18204 if (thisProc.userId == userId) { 18205 proc = thisProc; 18206 break; 18207 } 18208 } 18209 } 18210 } 18211 } 18212 18213 return proc; 18214 } 18215 18216 public boolean dumpHeap(String process, int userId, boolean managed, 18217 String path, ParcelFileDescriptor fd) throws RemoteException { 18218 18219 try { 18220 synchronized (this) { 18221 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18222 // its own permission (same as profileControl). 18223 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18224 != PackageManager.PERMISSION_GRANTED) { 18225 throw new SecurityException("Requires permission " 18226 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18227 } 18228 18229 if (fd == null) { 18230 throw new IllegalArgumentException("null fd"); 18231 } 18232 18233 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18234 if (proc == null || proc.thread == null) { 18235 throw new IllegalArgumentException("Unknown process: " + process); 18236 } 18237 18238 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18239 if (!isDebuggable) { 18240 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18241 throw new SecurityException("Process not debuggable: " + proc); 18242 } 18243 } 18244 18245 proc.thread.dumpHeap(managed, path, fd); 18246 fd = null; 18247 return true; 18248 } 18249 } catch (RemoteException e) { 18250 throw new IllegalStateException("Process disappeared"); 18251 } finally { 18252 if (fd != null) { 18253 try { 18254 fd.close(); 18255 } catch (IOException e) { 18256 } 18257 } 18258 } 18259 } 18260 18261 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18262 public void monitor() { 18263 synchronized (this) { } 18264 } 18265 18266 void onCoreSettingsChange(Bundle settings) { 18267 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18268 ProcessRecord processRecord = mLruProcesses.get(i); 18269 try { 18270 if (processRecord.thread != null) { 18271 processRecord.thread.setCoreSettings(settings); 18272 } 18273 } catch (RemoteException re) { 18274 /* ignore */ 18275 } 18276 } 18277 } 18278 18279 // Multi-user methods 18280 18281 /** 18282 * Start user, if its not already running, but don't bring it to foreground. 18283 */ 18284 @Override 18285 public boolean startUserInBackground(final int userId) { 18286 return startUser(userId, /* foreground */ false); 18287 } 18288 18289 /** 18290 * Start user, if its not already running, and bring it to foreground. 18291 */ 18292 boolean startUserInForeground(final int userId, Dialog dlg) { 18293 boolean result = startUser(userId, /* foreground */ true); 18294 dlg.dismiss(); 18295 return result; 18296 } 18297 18298 /** 18299 * Refreshes the list of users related to the current user when either a 18300 * user switch happens or when a new related user is started in the 18301 * background. 18302 */ 18303 private void updateCurrentProfileIdsLocked() { 18304 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18305 mCurrentUserId, false /* enabledOnly */); 18306 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18307 for (int i = 0; i < currentProfileIds.length; i++) { 18308 currentProfileIds[i] = profiles.get(i).id; 18309 } 18310 mCurrentProfileIds = currentProfileIds; 18311 18312 synchronized (mUserProfileGroupIdsSelfLocked) { 18313 mUserProfileGroupIdsSelfLocked.clear(); 18314 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18315 for (int i = 0; i < users.size(); i++) { 18316 UserInfo user = users.get(i); 18317 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18318 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18319 } 18320 } 18321 } 18322 } 18323 18324 private Set getProfileIdsLocked(int userId) { 18325 Set userIds = new HashSet<Integer>(); 18326 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18327 userId, false /* enabledOnly */); 18328 for (UserInfo user : profiles) { 18329 userIds.add(Integer.valueOf(user.id)); 18330 } 18331 return userIds; 18332 } 18333 18334 @Override 18335 public boolean switchUser(final int userId) { 18336 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18337 String userName; 18338 synchronized (this) { 18339 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18340 if (userInfo == null) { 18341 Slog.w(TAG, "No user info for user #" + userId); 18342 return false; 18343 } 18344 if (userInfo.isManagedProfile()) { 18345 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18346 return false; 18347 } 18348 userName = userInfo.name; 18349 mTargetUserId = userId; 18350 } 18351 mHandler.removeMessages(START_USER_SWITCH_MSG); 18352 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18353 return true; 18354 } 18355 18356 private void showUserSwitchDialog(int userId, String userName) { 18357 // The dialog will show and then initiate the user switch by calling startUserInForeground 18358 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18359 true /* above system */); 18360 d.show(); 18361 } 18362 18363 private boolean startUser(final int userId, final boolean foreground) { 18364 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18365 != PackageManager.PERMISSION_GRANTED) { 18366 String msg = "Permission Denial: switchUser() from pid=" 18367 + Binder.getCallingPid() 18368 + ", uid=" + Binder.getCallingUid() 18369 + " requires " + INTERACT_ACROSS_USERS_FULL; 18370 Slog.w(TAG, msg); 18371 throw new SecurityException(msg); 18372 } 18373 18374 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18375 18376 final long ident = Binder.clearCallingIdentity(); 18377 try { 18378 synchronized (this) { 18379 final int oldUserId = mCurrentUserId; 18380 if (oldUserId == userId) { 18381 return true; 18382 } 18383 18384 mStackSupervisor.setLockTaskModeLocked(null, false); 18385 18386 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18387 if (userInfo == null) { 18388 Slog.w(TAG, "No user info for user #" + userId); 18389 return false; 18390 } 18391 if (foreground && userInfo.isManagedProfile()) { 18392 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18393 return false; 18394 } 18395 18396 if (foreground) { 18397 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18398 R.anim.screen_user_enter); 18399 } 18400 18401 boolean needStart = false; 18402 18403 // If the user we are switching to is not currently started, then 18404 // we need to start it now. 18405 if (mStartedUsers.get(userId) == null) { 18406 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18407 updateStartedUserArrayLocked(); 18408 needStart = true; 18409 } 18410 18411 final Integer userIdInt = Integer.valueOf(userId); 18412 mUserLru.remove(userIdInt); 18413 mUserLru.add(userIdInt); 18414 18415 if (foreground) { 18416 mCurrentUserId = userId; 18417 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18418 updateCurrentProfileIdsLocked(); 18419 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18420 // Once the internal notion of the active user has switched, we lock the device 18421 // with the option to show the user switcher on the keyguard. 18422 mWindowManager.lockNow(null); 18423 } else { 18424 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18425 updateCurrentProfileIdsLocked(); 18426 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18427 mUserLru.remove(currentUserIdInt); 18428 mUserLru.add(currentUserIdInt); 18429 } 18430 18431 final UserStartedState uss = mStartedUsers.get(userId); 18432 18433 // Make sure user is in the started state. If it is currently 18434 // stopping, we need to knock that off. 18435 if (uss.mState == UserStartedState.STATE_STOPPING) { 18436 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18437 // so we can just fairly silently bring the user back from 18438 // the almost-dead. 18439 uss.mState = UserStartedState.STATE_RUNNING; 18440 updateStartedUserArrayLocked(); 18441 needStart = true; 18442 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18443 // This means ACTION_SHUTDOWN has been sent, so we will 18444 // need to treat this as a new boot of the user. 18445 uss.mState = UserStartedState.STATE_BOOTING; 18446 updateStartedUserArrayLocked(); 18447 needStart = true; 18448 } 18449 18450 if (uss.mState == UserStartedState.STATE_BOOTING) { 18451 // Booting up a new user, need to tell system services about it. 18452 // Note that this is on the same handler as scheduling of broadcasts, 18453 // which is important because it needs to go first. 18454 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18455 } 18456 18457 if (foreground) { 18458 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18459 oldUserId)); 18460 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18461 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18462 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18463 oldUserId, userId, uss)); 18464 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18465 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18466 } 18467 18468 if (needStart) { 18469 // Send USER_STARTED broadcast 18470 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18471 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18472 | Intent.FLAG_RECEIVER_FOREGROUND); 18473 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18474 broadcastIntentLocked(null, null, intent, 18475 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18476 false, false, MY_PID, Process.SYSTEM_UID, userId); 18477 } 18478 18479 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18480 if (userId != UserHandle.USER_OWNER) { 18481 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18482 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18483 broadcastIntentLocked(null, null, intent, null, 18484 new IIntentReceiver.Stub() { 18485 public void performReceive(Intent intent, int resultCode, 18486 String data, Bundle extras, boolean ordered, 18487 boolean sticky, int sendingUser) { 18488 onUserInitialized(uss, foreground, oldUserId, userId); 18489 } 18490 }, 0, null, null, null, AppOpsManager.OP_NONE, 18491 true, false, MY_PID, Process.SYSTEM_UID, 18492 userId); 18493 uss.initializing = true; 18494 } else { 18495 getUserManagerLocked().makeInitialized(userInfo.id); 18496 } 18497 } 18498 18499 if (foreground) { 18500 if (!uss.initializing) { 18501 moveUserToForeground(uss, oldUserId, userId); 18502 } 18503 } else { 18504 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18505 } 18506 18507 if (needStart) { 18508 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18509 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18510 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18511 broadcastIntentLocked(null, null, intent, 18512 null, new IIntentReceiver.Stub() { 18513 @Override 18514 public void performReceive(Intent intent, int resultCode, String data, 18515 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18516 throws RemoteException { 18517 } 18518 }, 0, null, null, 18519 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18520 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18521 } 18522 } 18523 } finally { 18524 Binder.restoreCallingIdentity(ident); 18525 } 18526 18527 return true; 18528 } 18529 18530 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18531 long ident = Binder.clearCallingIdentity(); 18532 try { 18533 Intent intent; 18534 if (oldUserId >= 0) { 18535 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18536 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18537 int count = profiles.size(); 18538 for (int i = 0; i < count; i++) { 18539 int profileUserId = profiles.get(i).id; 18540 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18541 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18542 | Intent.FLAG_RECEIVER_FOREGROUND); 18543 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18544 broadcastIntentLocked(null, null, intent, 18545 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18546 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18547 } 18548 } 18549 if (newUserId >= 0) { 18550 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18551 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18552 int count = profiles.size(); 18553 for (int i = 0; i < count; i++) { 18554 int profileUserId = profiles.get(i).id; 18555 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18556 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18557 | Intent.FLAG_RECEIVER_FOREGROUND); 18558 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18559 broadcastIntentLocked(null, null, intent, 18560 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18561 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18562 } 18563 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18564 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18565 | Intent.FLAG_RECEIVER_FOREGROUND); 18566 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18567 broadcastIntentLocked(null, null, intent, 18568 null, null, 0, null, null, 18569 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18570 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18571 } 18572 } finally { 18573 Binder.restoreCallingIdentity(ident); 18574 } 18575 } 18576 18577 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18578 final int newUserId) { 18579 final int N = mUserSwitchObservers.beginBroadcast(); 18580 if (N > 0) { 18581 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18582 int mCount = 0; 18583 @Override 18584 public void sendResult(Bundle data) throws RemoteException { 18585 synchronized (ActivityManagerService.this) { 18586 if (mCurUserSwitchCallback == this) { 18587 mCount++; 18588 if (mCount == N) { 18589 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18590 } 18591 } 18592 } 18593 } 18594 }; 18595 synchronized (this) { 18596 uss.switching = true; 18597 mCurUserSwitchCallback = callback; 18598 } 18599 for (int i=0; i<N; i++) { 18600 try { 18601 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18602 newUserId, callback); 18603 } catch (RemoteException e) { 18604 } 18605 } 18606 } else { 18607 synchronized (this) { 18608 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18609 } 18610 } 18611 mUserSwitchObservers.finishBroadcast(); 18612 } 18613 18614 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18615 synchronized (this) { 18616 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18617 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18618 } 18619 } 18620 18621 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18622 mCurUserSwitchCallback = null; 18623 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18624 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18625 oldUserId, newUserId, uss)); 18626 } 18627 18628 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18629 synchronized (this) { 18630 if (foreground) { 18631 moveUserToForeground(uss, oldUserId, newUserId); 18632 } 18633 } 18634 18635 completeSwitchAndInitalize(uss, newUserId, true, false); 18636 } 18637 18638 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18639 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18640 if (homeInFront) { 18641 startHomeActivityLocked(newUserId); 18642 } else { 18643 mStackSupervisor.resumeTopActivitiesLocked(); 18644 } 18645 EventLogTags.writeAmSwitchUser(newUserId); 18646 getUserManagerLocked().userForeground(newUserId); 18647 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18648 } 18649 18650 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18651 completeSwitchAndInitalize(uss, newUserId, false, true); 18652 } 18653 18654 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18655 boolean clearInitializing, boolean clearSwitching) { 18656 boolean unfrozen = false; 18657 synchronized (this) { 18658 if (clearInitializing) { 18659 uss.initializing = false; 18660 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18661 } 18662 if (clearSwitching) { 18663 uss.switching = false; 18664 } 18665 if (!uss.switching && !uss.initializing) { 18666 mWindowManager.stopFreezingScreen(); 18667 unfrozen = true; 18668 } 18669 } 18670 if (unfrozen) { 18671 final int N = mUserSwitchObservers.beginBroadcast(); 18672 for (int i=0; i<N; i++) { 18673 try { 18674 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18675 } catch (RemoteException e) { 18676 } 18677 } 18678 mUserSwitchObservers.finishBroadcast(); 18679 } 18680 } 18681 18682 void scheduleStartProfilesLocked() { 18683 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18684 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18685 DateUtils.SECOND_IN_MILLIS); 18686 } 18687 } 18688 18689 void startProfilesLocked() { 18690 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18691 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18692 mCurrentUserId, false /* enabledOnly */); 18693 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18694 for (UserInfo user : profiles) { 18695 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18696 && user.id != mCurrentUserId) { 18697 toStart.add(user); 18698 } 18699 } 18700 final int n = toStart.size(); 18701 int i = 0; 18702 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18703 startUserInBackground(toStart.get(i).id); 18704 } 18705 if (i < n) { 18706 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18707 } 18708 } 18709 18710 void finishUserBoot(UserStartedState uss) { 18711 synchronized (this) { 18712 if (uss.mState == UserStartedState.STATE_BOOTING 18713 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18714 uss.mState = UserStartedState.STATE_RUNNING; 18715 final int userId = uss.mHandle.getIdentifier(); 18716 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18717 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18718 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18719 broadcastIntentLocked(null, null, intent, 18720 null, null, 0, null, null, 18721 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18722 true, false, MY_PID, Process.SYSTEM_UID, userId); 18723 } 18724 } 18725 } 18726 18727 void finishUserSwitch(UserStartedState uss) { 18728 synchronized (this) { 18729 finishUserBoot(uss); 18730 18731 startProfilesLocked(); 18732 18733 int num = mUserLru.size(); 18734 int i = 0; 18735 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18736 Integer oldUserId = mUserLru.get(i); 18737 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18738 if (oldUss == null) { 18739 // Shouldn't happen, but be sane if it does. 18740 mUserLru.remove(i); 18741 num--; 18742 continue; 18743 } 18744 if (oldUss.mState == UserStartedState.STATE_STOPPING 18745 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18746 // This user is already stopping, doesn't count. 18747 num--; 18748 i++; 18749 continue; 18750 } 18751 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18752 // Owner and current can't be stopped, but count as running. 18753 i++; 18754 continue; 18755 } 18756 // This is a user to be stopped. 18757 stopUserLocked(oldUserId, null); 18758 num--; 18759 i++; 18760 } 18761 } 18762 } 18763 18764 @Override 18765 public int stopUser(final int userId, final IStopUserCallback callback) { 18766 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18767 != PackageManager.PERMISSION_GRANTED) { 18768 String msg = "Permission Denial: switchUser() from pid=" 18769 + Binder.getCallingPid() 18770 + ", uid=" + Binder.getCallingUid() 18771 + " requires " + INTERACT_ACROSS_USERS_FULL; 18772 Slog.w(TAG, msg); 18773 throw new SecurityException(msg); 18774 } 18775 if (userId <= 0) { 18776 throw new IllegalArgumentException("Can't stop primary user " + userId); 18777 } 18778 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18779 synchronized (this) { 18780 return stopUserLocked(userId, callback); 18781 } 18782 } 18783 18784 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18785 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18786 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18787 return ActivityManager.USER_OP_IS_CURRENT; 18788 } 18789 18790 final UserStartedState uss = mStartedUsers.get(userId); 18791 if (uss == null) { 18792 // User is not started, nothing to do... but we do need to 18793 // callback if requested. 18794 if (callback != null) { 18795 mHandler.post(new Runnable() { 18796 @Override 18797 public void run() { 18798 try { 18799 callback.userStopped(userId); 18800 } catch (RemoteException e) { 18801 } 18802 } 18803 }); 18804 } 18805 return ActivityManager.USER_OP_SUCCESS; 18806 } 18807 18808 if (callback != null) { 18809 uss.mStopCallbacks.add(callback); 18810 } 18811 18812 if (uss.mState != UserStartedState.STATE_STOPPING 18813 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18814 uss.mState = UserStartedState.STATE_STOPPING; 18815 updateStartedUserArrayLocked(); 18816 18817 long ident = Binder.clearCallingIdentity(); 18818 try { 18819 // We are going to broadcast ACTION_USER_STOPPING and then 18820 // once that is done send a final ACTION_SHUTDOWN and then 18821 // stop the user. 18822 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18823 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18824 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18825 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18826 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18827 // This is the result receiver for the final shutdown broadcast. 18828 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18829 @Override 18830 public void performReceive(Intent intent, int resultCode, String data, 18831 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18832 finishUserStop(uss); 18833 } 18834 }; 18835 // This is the result receiver for the initial stopping broadcast. 18836 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18837 @Override 18838 public void performReceive(Intent intent, int resultCode, String data, 18839 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18840 // On to the next. 18841 synchronized (ActivityManagerService.this) { 18842 if (uss.mState != UserStartedState.STATE_STOPPING) { 18843 // Whoops, we are being started back up. Abort, abort! 18844 return; 18845 } 18846 uss.mState = UserStartedState.STATE_SHUTDOWN; 18847 } 18848 mBatteryStatsService.noteEvent( 18849 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18850 Integer.toString(userId), userId); 18851 mSystemServiceManager.stopUser(userId); 18852 broadcastIntentLocked(null, null, shutdownIntent, 18853 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18854 true, false, MY_PID, Process.SYSTEM_UID, userId); 18855 } 18856 }; 18857 // Kick things off. 18858 broadcastIntentLocked(null, null, stoppingIntent, 18859 null, stoppingReceiver, 0, null, null, 18860 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18861 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18862 } finally { 18863 Binder.restoreCallingIdentity(ident); 18864 } 18865 } 18866 18867 return ActivityManager.USER_OP_SUCCESS; 18868 } 18869 18870 void finishUserStop(UserStartedState uss) { 18871 final int userId = uss.mHandle.getIdentifier(); 18872 boolean stopped; 18873 ArrayList<IStopUserCallback> callbacks; 18874 synchronized (this) { 18875 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18876 if (mStartedUsers.get(userId) != uss) { 18877 stopped = false; 18878 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18879 stopped = false; 18880 } else { 18881 stopped = true; 18882 // User can no longer run. 18883 mStartedUsers.remove(userId); 18884 mUserLru.remove(Integer.valueOf(userId)); 18885 updateStartedUserArrayLocked(); 18886 18887 // Clean up all state and processes associated with the user. 18888 // Kill all the processes for the user. 18889 forceStopUserLocked(userId, "finish user"); 18890 } 18891 18892 // Explicitly remove the old information in mRecentTasks. 18893 removeRecentTasksForUserLocked(userId); 18894 } 18895 18896 for (int i=0; i<callbacks.size(); i++) { 18897 try { 18898 if (stopped) callbacks.get(i).userStopped(userId); 18899 else callbacks.get(i).userStopAborted(userId); 18900 } catch (RemoteException e) { 18901 } 18902 } 18903 18904 if (stopped) { 18905 mSystemServiceManager.cleanupUser(userId); 18906 synchronized (this) { 18907 mStackSupervisor.removeUserLocked(userId); 18908 } 18909 } 18910 } 18911 18912 @Override 18913 public UserInfo getCurrentUser() { 18914 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18915 != PackageManager.PERMISSION_GRANTED) && ( 18916 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18917 != PackageManager.PERMISSION_GRANTED)) { 18918 String msg = "Permission Denial: getCurrentUser() from pid=" 18919 + Binder.getCallingPid() 18920 + ", uid=" + Binder.getCallingUid() 18921 + " requires " + INTERACT_ACROSS_USERS; 18922 Slog.w(TAG, msg); 18923 throw new SecurityException(msg); 18924 } 18925 synchronized (this) { 18926 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18927 return getUserManagerLocked().getUserInfo(userId); 18928 } 18929 } 18930 18931 int getCurrentUserIdLocked() { 18932 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18933 } 18934 18935 @Override 18936 public boolean isUserRunning(int userId, boolean orStopped) { 18937 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18938 != PackageManager.PERMISSION_GRANTED) { 18939 String msg = "Permission Denial: isUserRunning() from pid=" 18940 + Binder.getCallingPid() 18941 + ", uid=" + Binder.getCallingUid() 18942 + " requires " + INTERACT_ACROSS_USERS; 18943 Slog.w(TAG, msg); 18944 throw new SecurityException(msg); 18945 } 18946 synchronized (this) { 18947 return isUserRunningLocked(userId, orStopped); 18948 } 18949 } 18950 18951 boolean isUserRunningLocked(int userId, boolean orStopped) { 18952 UserStartedState state = mStartedUsers.get(userId); 18953 if (state == null) { 18954 return false; 18955 } 18956 if (orStopped) { 18957 return true; 18958 } 18959 return state.mState != UserStartedState.STATE_STOPPING 18960 && state.mState != UserStartedState.STATE_SHUTDOWN; 18961 } 18962 18963 @Override 18964 public int[] getRunningUserIds() { 18965 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18966 != PackageManager.PERMISSION_GRANTED) { 18967 String msg = "Permission Denial: isUserRunning() from pid=" 18968 + Binder.getCallingPid() 18969 + ", uid=" + Binder.getCallingUid() 18970 + " requires " + INTERACT_ACROSS_USERS; 18971 Slog.w(TAG, msg); 18972 throw new SecurityException(msg); 18973 } 18974 synchronized (this) { 18975 return mStartedUserArray; 18976 } 18977 } 18978 18979 private void updateStartedUserArrayLocked() { 18980 int num = 0; 18981 for (int i=0; i<mStartedUsers.size(); i++) { 18982 UserStartedState uss = mStartedUsers.valueAt(i); 18983 // This list does not include stopping users. 18984 if (uss.mState != UserStartedState.STATE_STOPPING 18985 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18986 num++; 18987 } 18988 } 18989 mStartedUserArray = new int[num]; 18990 num = 0; 18991 for (int i=0; i<mStartedUsers.size(); i++) { 18992 UserStartedState uss = mStartedUsers.valueAt(i); 18993 if (uss.mState != UserStartedState.STATE_STOPPING 18994 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18995 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18996 num++; 18997 } 18998 } 18999 } 19000 19001 @Override 19002 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19003 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19004 != PackageManager.PERMISSION_GRANTED) { 19005 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19006 + Binder.getCallingPid() 19007 + ", uid=" + Binder.getCallingUid() 19008 + " requires " + INTERACT_ACROSS_USERS_FULL; 19009 Slog.w(TAG, msg); 19010 throw new SecurityException(msg); 19011 } 19012 19013 mUserSwitchObservers.register(observer); 19014 } 19015 19016 @Override 19017 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19018 mUserSwitchObservers.unregister(observer); 19019 } 19020 19021 private boolean userExists(int userId) { 19022 if (userId == 0) { 19023 return true; 19024 } 19025 UserManagerService ums = getUserManagerLocked(); 19026 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19027 } 19028 19029 int[] getUsersLocked() { 19030 UserManagerService ums = getUserManagerLocked(); 19031 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19032 } 19033 19034 UserManagerService getUserManagerLocked() { 19035 if (mUserManager == null) { 19036 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19037 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19038 } 19039 return mUserManager; 19040 } 19041 19042 private int applyUserId(int uid, int userId) { 19043 return UserHandle.getUid(userId, uid); 19044 } 19045 19046 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19047 if (info == null) return null; 19048 ApplicationInfo newInfo = new ApplicationInfo(info); 19049 newInfo.uid = applyUserId(info.uid, userId); 19050 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19051 + info.packageName; 19052 return newInfo; 19053 } 19054 19055 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19056 if (aInfo == null 19057 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19058 return aInfo; 19059 } 19060 19061 ActivityInfo info = new ActivityInfo(aInfo); 19062 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19063 return info; 19064 } 19065 19066 private final class LocalService extends ActivityManagerInternal { 19067 @Override 19068 public void goingToSleep() { 19069 ActivityManagerService.this.goingToSleep(); 19070 } 19071 19072 @Override 19073 public void wakingUp() { 19074 ActivityManagerService.this.wakingUp(); 19075 } 19076 19077 @Override 19078 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19079 String processName, String abiOverride, int uid, Runnable crashHandler) { 19080 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19081 processName, abiOverride, uid, crashHandler); 19082 } 19083 } 19084 19085 /** 19086 * An implementation of IAppTask, that allows an app to manage its own tasks via 19087 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19088 * only the process that calls getAppTasks() can call the AppTask methods. 19089 */ 19090 class AppTaskImpl extends IAppTask.Stub { 19091 private int mTaskId; 19092 private int mCallingUid; 19093 19094 public AppTaskImpl(int taskId, int callingUid) { 19095 mTaskId = taskId; 19096 mCallingUid = callingUid; 19097 } 19098 19099 private void checkCaller() { 19100 if (mCallingUid != Binder.getCallingUid()) { 19101 throw new SecurityException("Caller " + mCallingUid 19102 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19103 } 19104 } 19105 19106 @Override 19107 public void finishAndRemoveTask() { 19108 checkCaller(); 19109 19110 synchronized (ActivityManagerService.this) { 19111 long origId = Binder.clearCallingIdentity(); 19112 try { 19113 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19114 if (tr == null) { 19115 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19116 } 19117 // Only kill the process if we are not a new document 19118 int flags = tr.getBaseIntent().getFlags(); 19119 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19120 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19121 removeTaskByIdLocked(mTaskId, 19122 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19123 } finally { 19124 Binder.restoreCallingIdentity(origId); 19125 } 19126 } 19127 } 19128 19129 @Override 19130 public ActivityManager.RecentTaskInfo getTaskInfo() { 19131 checkCaller(); 19132 19133 synchronized (ActivityManagerService.this) { 19134 long origId = Binder.clearCallingIdentity(); 19135 try { 19136 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19137 if (tr == null) { 19138 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19139 } 19140 return createRecentTaskInfoFromTaskRecord(tr); 19141 } finally { 19142 Binder.restoreCallingIdentity(origId); 19143 } 19144 } 19145 } 19146 19147 @Override 19148 public void moveToFront() { 19149 checkCaller(); 19150 19151 final TaskRecord tr; 19152 synchronized (ActivityManagerService.this) { 19153 tr = recentTaskForIdLocked(mTaskId); 19154 if (tr == null) { 19155 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19156 } 19157 if (tr.getRootActivity() != null) { 19158 moveTaskToFrontLocked(tr.taskId, 0, null); 19159 return; 19160 } 19161 } 19162 19163 startActivityFromRecentsInner(tr.taskId, null); 19164 } 19165 19166 @Override 19167 public int startActivity(IBinder whoThread, String callingPackage, 19168 Intent intent, String resolvedType, Bundle options) { 19169 checkCaller(); 19170 19171 int callingUser = UserHandle.getCallingUserId(); 19172 TaskRecord tr; 19173 IApplicationThread appThread; 19174 synchronized (ActivityManagerService.this) { 19175 tr = recentTaskForIdLocked(mTaskId); 19176 if (tr == null) { 19177 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19178 } 19179 appThread = ApplicationThreadNative.asInterface(whoThread); 19180 if (appThread == null) { 19181 throw new IllegalArgumentException("Bad app thread " + appThread); 19182 } 19183 } 19184 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19185 resolvedType, null, null, null, null, 0, 0, null, null, 19186 null, options, callingUser, null, tr); 19187 } 19188 19189 @Override 19190 public void setExcludeFromRecents(boolean exclude) { 19191 checkCaller(); 19192 19193 synchronized (ActivityManagerService.this) { 19194 long origId = Binder.clearCallingIdentity(); 19195 try { 19196 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19197 if (tr == null) { 19198 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19199 } 19200 Intent intent = tr.getBaseIntent(); 19201 if (exclude) { 19202 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19203 } else { 19204 intent.setFlags(intent.getFlags() 19205 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19206 } 19207 } finally { 19208 Binder.restoreCallingIdentity(origId); 19209 } 19210 } 19211 } 19212 } 19213} 19214