ActivityManagerService.java revision 605eb79c9519307147fc1795d0eb155638a7f542
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.content.PackageMonitor; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.Installer; 85import com.android.server.pm.UserManagerService; 86import com.android.server.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 private Installer mInstaller; 375 376 /** Run all ActivityStacks through this */ 377 ActivityStackSupervisor mStackSupervisor; 378 379 public IntentFirewall mIntentFirewall; 380 381 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 382 // default actuion automatically. Important for devices without direct input 383 // devices. 384 private boolean mShowDialogs = true; 385 386 BroadcastQueue mFgBroadcastQueue; 387 BroadcastQueue mBgBroadcastQueue; 388 // Convenient for easy iteration over the queues. Foreground is first 389 // so that dispatch of foreground broadcasts gets precedence. 390 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 391 392 BroadcastQueue broadcastQueueForIntent(Intent intent) { 393 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 394 if (DEBUG_BACKGROUND_BROADCAST) { 395 Slog.i(TAG, "Broadcast intent " + intent + " on " 396 + (isFg ? "foreground" : "background") 397 + " queue"); 398 } 399 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 400 } 401 402 /** 403 * Activity we have told the window manager to have key focus. 404 */ 405 ActivityRecord mFocusedActivity = null; 406 407 /** 408 * List of intents that were used to start the most recent tasks. 409 */ 410 ArrayList<TaskRecord> mRecentTasks; 411 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 412 413 /** 414 * For addAppTask: cached of the last activity component that was added. 415 */ 416 ComponentName mLastAddedTaskComponent; 417 418 /** 419 * For addAppTask: cached of the last activity uid that was added. 420 */ 421 int mLastAddedTaskUid; 422 423 /** 424 * For addAppTask: cached of the last ActivityInfo that was added. 425 */ 426 ActivityInfo mLastAddedTaskActivity; 427 428 public class PendingAssistExtras extends Binder implements Runnable { 429 public final ActivityRecord activity; 430 public final Bundle extras; 431 public final Intent intent; 432 public final String hint; 433 public final int userHandle; 434 public boolean haveResult = false; 435 public Bundle result = null; 436 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 437 String _hint, int _userHandle) { 438 activity = _activity; 439 extras = _extras; 440 intent = _intent; 441 hint = _hint; 442 userHandle = _userHandle; 443 } 444 @Override 445 public void run() { 446 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 447 synchronized (this) { 448 haveResult = true; 449 notifyAll(); 450 } 451 } 452 } 453 454 final ArrayList<PendingAssistExtras> mPendingAssistExtras 455 = new ArrayList<PendingAssistExtras>(); 456 457 /** 458 * Process management. 459 */ 460 final ProcessList mProcessList = new ProcessList(); 461 462 /** 463 * All of the applications we currently have running organized by name. 464 * The keys are strings of the application package name (as 465 * returned by the package manager), and the keys are ApplicationRecord 466 * objects. 467 */ 468 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 469 470 /** 471 * Tracking long-term execution of processes to look for abuse and other 472 * bad app behavior. 473 */ 474 final ProcessStatsService mProcessStats; 475 476 /** 477 * The currently running isolated processes. 478 */ 479 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 480 481 /** 482 * Counter for assigning isolated process uids, to avoid frequently reusing the 483 * same ones. 484 */ 485 int mNextIsolatedProcessUid = 0; 486 487 /** 488 * The currently running heavy-weight process, if any. 489 */ 490 ProcessRecord mHeavyWeightProcess = null; 491 492 /** 493 * The last time that various processes have crashed. 494 */ 495 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 496 497 /** 498 * Information about a process that is currently marked as bad. 499 */ 500 static final class BadProcessInfo { 501 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 502 this.time = time; 503 this.shortMsg = shortMsg; 504 this.longMsg = longMsg; 505 this.stack = stack; 506 } 507 508 final long time; 509 final String shortMsg; 510 final String longMsg; 511 final String stack; 512 } 513 514 /** 515 * Set of applications that we consider to be bad, and will reject 516 * incoming broadcasts from (which the user has no control over). 517 * Processes are added to this set when they have crashed twice within 518 * a minimum amount of time; they are removed from it when they are 519 * later restarted (hopefully due to some user action). The value is the 520 * time it was added to the list. 521 */ 522 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 523 524 /** 525 * All of the processes we currently have running organized by pid. 526 * The keys are the pid running the application. 527 * 528 * <p>NOTE: This object is protected by its own lock, NOT the global 529 * activity manager lock! 530 */ 531 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 532 533 /** 534 * All of the processes that have been forced to be foreground. The key 535 * is the pid of the caller who requested it (we hold a death 536 * link on it). 537 */ 538 abstract class ForegroundToken implements IBinder.DeathRecipient { 539 int pid; 540 IBinder token; 541 } 542 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 543 544 /** 545 * List of records for processes that someone had tried to start before the 546 * system was ready. We don't start them at that point, but ensure they 547 * are started by the time booting is complete. 548 */ 549 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 550 551 /** 552 * List of persistent applications that are in the process 553 * of being started. 554 */ 555 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * Processes that are being forcibly torn down. 559 */ 560 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * List of running applications, sorted by recent usage. 564 * The first entry in the list is the least recently used. 565 */ 566 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 567 568 /** 569 * Where in mLruProcesses that the processes hosting activities start. 570 */ 571 int mLruProcessActivityStart = 0; 572 573 /** 574 * Where in mLruProcesses that the processes hosting services start. 575 * This is after (lower index) than mLruProcessesActivityStart. 576 */ 577 int mLruProcessServiceStart = 0; 578 579 /** 580 * List of processes that should gc as soon as things are idle. 581 */ 582 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 583 584 /** 585 * Processes we want to collect PSS data from. 586 */ 587 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 588 589 /** 590 * Last time we requested PSS data of all processes. 591 */ 592 long mLastFullPssTime = SystemClock.uptimeMillis(); 593 594 /** 595 * If set, the next time we collect PSS data we should do a full collection 596 * with data from native processes and the kernel. 597 */ 598 boolean mFullPssPending = false; 599 600 /** 601 * This is the process holding what we currently consider to be 602 * the "home" activity. 603 */ 604 ProcessRecord mHomeProcess; 605 606 /** 607 * This is the process holding the activity the user last visited that 608 * is in a different process from the one they are currently in. 609 */ 610 ProcessRecord mPreviousProcess; 611 612 /** 613 * The time at which the previous process was last visible. 614 */ 615 long mPreviousProcessVisibleTime; 616 617 /** 618 * Which uses have been started, so are allowed to run code. 619 */ 620 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 621 622 /** 623 * LRU list of history of current users. Most recently current is at the end. 624 */ 625 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 626 627 /** 628 * Constant array of the users that are currently started. 629 */ 630 int[] mStartedUserArray = new int[] { 0 }; 631 632 /** 633 * Registered observers of the user switching mechanics. 634 */ 635 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 636 = new RemoteCallbackList<IUserSwitchObserver>(); 637 638 /** 639 * Currently active user switch. 640 */ 641 Object mCurUserSwitchCallback; 642 643 /** 644 * Packages that the user has asked to have run in screen size 645 * compatibility mode instead of filling the screen. 646 */ 647 final CompatModePackages mCompatModePackages; 648 649 /** 650 * Set of IntentSenderRecord objects that are currently active. 651 */ 652 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 653 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 654 655 /** 656 * Fingerprints (hashCode()) of stack traces that we've 657 * already logged DropBox entries for. Guarded by itself. If 658 * something (rogue user app) forces this over 659 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 660 */ 661 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 662 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 663 664 /** 665 * Strict Mode background batched logging state. 666 * 667 * The string buffer is guarded by itself, and its lock is also 668 * used to determine if another batched write is already 669 * in-flight. 670 */ 671 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 672 673 /** 674 * Keeps track of all IIntentReceivers that have been registered for 675 * broadcasts. Hash keys are the receiver IBinder, hash value is 676 * a ReceiverList. 677 */ 678 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 679 new HashMap<IBinder, ReceiverList>(); 680 681 /** 682 * Resolver for broadcast intents to registered receivers. 683 * Holds BroadcastFilter (subclass of IntentFilter). 684 */ 685 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 686 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 687 @Override 688 protected boolean allowFilterResult( 689 BroadcastFilter filter, List<BroadcastFilter> dest) { 690 IBinder target = filter.receiverList.receiver.asBinder(); 691 for (int i=dest.size()-1; i>=0; i--) { 692 if (dest.get(i).receiverList.receiver.asBinder() == target) { 693 return false; 694 } 695 } 696 return true; 697 } 698 699 @Override 700 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 701 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 702 || userId == filter.owningUserId) { 703 return super.newResult(filter, match, userId); 704 } 705 return null; 706 } 707 708 @Override 709 protected BroadcastFilter[] newArray(int size) { 710 return new BroadcastFilter[size]; 711 } 712 713 @Override 714 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 715 return packageName.equals(filter.packageName); 716 } 717 }; 718 719 /** 720 * State of all active sticky broadcasts per user. Keys are the action of the 721 * sticky Intent, values are an ArrayList of all broadcasted intents with 722 * that action (which should usually be one). The SparseArray is keyed 723 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 724 * for stickies that are sent to all users. 725 */ 726 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 727 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 728 729 final ActiveServices mServices; 730 731 /** 732 * Backup/restore process management 733 */ 734 String mBackupAppName = null; 735 BackupRecord mBackupTarget = null; 736 737 final ProviderMap mProviderMap; 738 739 /** 740 * List of content providers who have clients waiting for them. The 741 * application is currently being launched and the provider will be 742 * removed from this list once it is published. 743 */ 744 final ArrayList<ContentProviderRecord> mLaunchingProviders 745 = new ArrayList<ContentProviderRecord>(); 746 747 /** 748 * File storing persisted {@link #mGrantedUriPermissions}. 749 */ 750 private final AtomicFile mGrantFile; 751 752 /** XML constants used in {@link #mGrantFile} */ 753 private static final String TAG_URI_GRANTS = "uri-grants"; 754 private static final String TAG_URI_GRANT = "uri-grant"; 755 private static final String ATTR_USER_HANDLE = "userHandle"; 756 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 757 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 758 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 759 private static final String ATTR_TARGET_PKG = "targetPkg"; 760 private static final String ATTR_URI = "uri"; 761 private static final String ATTR_MODE_FLAGS = "modeFlags"; 762 private static final String ATTR_CREATED_TIME = "createdTime"; 763 private static final String ATTR_PREFIX = "prefix"; 764 765 /** 766 * Global set of specific {@link Uri} permissions that have been granted. 767 * This optimized lookup structure maps from {@link UriPermission#targetUid} 768 * to {@link UriPermission#uri} to {@link UriPermission}. 769 */ 770 @GuardedBy("this") 771 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 772 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 773 774 public static class GrantUri { 775 public final int sourceUserId; 776 public final Uri uri; 777 public boolean prefix; 778 779 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 780 this.sourceUserId = sourceUserId; 781 this.uri = uri; 782 this.prefix = prefix; 783 } 784 785 @Override 786 public int hashCode() { 787 return toString().hashCode(); 788 } 789 790 @Override 791 public boolean equals(Object o) { 792 if (o instanceof GrantUri) { 793 GrantUri other = (GrantUri) o; 794 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 795 && prefix == other.prefix; 796 } 797 return false; 798 } 799 800 @Override 801 public String toString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public String toSafeString() { 808 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 809 if (prefix) result += " [prefix]"; 810 return result; 811 } 812 813 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 814 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 815 ContentProvider.getUriWithoutUserId(uri), false); 816 } 817 } 818 819 CoreSettingsObserver mCoreSettingsObserver; 820 821 /** 822 * Thread-local storage used to carry caller permissions over through 823 * indirect content-provider access. 824 */ 825 private class Identity { 826 public int pid; 827 public int uid; 828 829 Identity(int _pid, int _uid) { 830 pid = _pid; 831 uid = _uid; 832 } 833 } 834 835 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 836 837 /** 838 * All information we have collected about the runtime performance of 839 * any user id that can impact battery performance. 840 */ 841 final BatteryStatsService mBatteryStatsService; 842 843 /** 844 * Information about component usage 845 */ 846 UsageStatsManagerInternal mUsageStatsService; 847 848 /** 849 * Information about and control over application operations 850 */ 851 final AppOpsService mAppOpsService; 852 853 /** 854 * Save recent tasks information across reboots. 855 */ 856 final TaskPersister mTaskPersister; 857 858 /** 859 * Current configuration information. HistoryRecord objects are given 860 * a reference to this object to indicate which configuration they are 861 * currently running in, so this object must be kept immutable. 862 */ 863 Configuration mConfiguration = new Configuration(); 864 865 /** 866 * Current sequencing integer of the configuration, for skipping old 867 * configurations. 868 */ 869 int mConfigurationSeq = 0; 870 871 /** 872 * Hardware-reported OpenGLES version. 873 */ 874 final int GL_ES_VERSION; 875 876 /** 877 * List of initialization arguments to pass to all processes when binding applications to them. 878 * For example, references to the commonly used services. 879 */ 880 HashMap<String, IBinder> mAppBindArgs; 881 882 /** 883 * Temporary to avoid allocations. Protected by main lock. 884 */ 885 final StringBuilder mStringBuilder = new StringBuilder(256); 886 887 /** 888 * Used to control how we initialize the service. 889 */ 890 ComponentName mTopComponent; 891 String mTopAction = Intent.ACTION_MAIN; 892 String mTopData; 893 boolean mProcessesReady = false; 894 boolean mSystemReady = false; 895 boolean mBooting = false; 896 boolean mCallFinishBooting = false; 897 boolean mBootAnimationComplete = false; 898 boolean mWaitingUpdate = false; 899 boolean mDidUpdate = false; 900 boolean mOnBattery = false; 901 boolean mLaunchWarningShown = false; 902 903 Context mContext; 904 905 int mFactoryTest; 906 907 boolean mCheckedForSetup; 908 909 /** 910 * The time at which we will allow normal application switches again, 911 * after a call to {@link #stopAppSwitches()}. 912 */ 913 long mAppSwitchesAllowedTime; 914 915 /** 916 * This is set to true after the first switch after mAppSwitchesAllowedTime 917 * is set; any switches after that will clear the time. 918 */ 919 boolean mDidAppSwitch; 920 921 /** 922 * Last time (in realtime) at which we checked for power usage. 923 */ 924 long mLastPowerCheckRealtime; 925 926 /** 927 * Last time (in uptime) at which we checked for power usage. 928 */ 929 long mLastPowerCheckUptime; 930 931 /** 932 * Set while we are wanting to sleep, to prevent any 933 * activities from being started/resumed. 934 */ 935 private boolean mSleeping = false; 936 937 /** 938 * Set while we are running a voice interaction. This overrides 939 * sleeping while it is active. 940 */ 941 private boolean mRunningVoice = false; 942 943 /** 944 * State of external calls telling us if the device is asleep. 945 */ 946 private boolean mWentToSleep = false; 947 948 /** 949 * State of external call telling us if the lock screen is shown. 950 */ 951 private boolean mLockScreenShown = false; 952 953 /** 954 * Set if we are shutting down the system, similar to sleeping. 955 */ 956 boolean mShuttingDown = false; 957 958 /** 959 * Current sequence id for oom_adj computation traversal. 960 */ 961 int mAdjSeq = 0; 962 963 /** 964 * Current sequence id for process LRU updating. 965 */ 966 int mLruSeq = 0; 967 968 /** 969 * Keep track of the non-cached/empty process we last found, to help 970 * determine how to distribute cached/empty processes next time. 971 */ 972 int mNumNonCachedProcs = 0; 973 974 /** 975 * Keep track of the number of cached hidden procs, to balance oom adj 976 * distribution between those and empty procs. 977 */ 978 int mNumCachedHiddenProcs = 0; 979 980 /** 981 * Keep track of the number of service processes we last found, to 982 * determine on the next iteration which should be B services. 983 */ 984 int mNumServiceProcs = 0; 985 int mNewNumAServiceProcs = 0; 986 int mNewNumServiceProcs = 0; 987 988 /** 989 * Allow the current computed overall memory level of the system to go down? 990 * This is set to false when we are killing processes for reasons other than 991 * memory management, so that the now smaller process list will not be taken as 992 * an indication that memory is tighter. 993 */ 994 boolean mAllowLowerMemLevel = false; 995 996 /** 997 * The last computed memory level, for holding when we are in a state that 998 * processes are going away for other reasons. 999 */ 1000 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1001 1002 /** 1003 * The last total number of process we have, to determine if changes actually look 1004 * like a shrinking number of process due to lower RAM. 1005 */ 1006 int mLastNumProcesses; 1007 1008 /** 1009 * The uptime of the last time we performed idle maintenance. 1010 */ 1011 long mLastIdleTime = SystemClock.uptimeMillis(); 1012 1013 /** 1014 * Total time spent with RAM that has been added in the past since the last idle time. 1015 */ 1016 long mLowRamTimeSinceLastIdle = 0; 1017 1018 /** 1019 * If RAM is currently low, when that horrible situation started. 1020 */ 1021 long mLowRamStartTime = 0; 1022 1023 /** 1024 * For reporting to battery stats the current top application. 1025 */ 1026 private String mCurResumedPackage = null; 1027 private int mCurResumedUid = -1; 1028 1029 /** 1030 * For reporting to battery stats the apps currently running foreground 1031 * service. The ProcessMap is package/uid tuples; each of these contain 1032 * an array of the currently foreground processes. 1033 */ 1034 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1035 = new ProcessMap<ArrayList<ProcessRecord>>(); 1036 1037 /** 1038 * This is set if we had to do a delayed dexopt of an app before launching 1039 * it, to increase the ANR timeouts in that case. 1040 */ 1041 boolean mDidDexOpt; 1042 1043 /** 1044 * Set if the systemServer made a call to enterSafeMode. 1045 */ 1046 boolean mSafeMode; 1047 1048 String mDebugApp = null; 1049 boolean mWaitForDebugger = false; 1050 boolean mDebugTransient = false; 1051 String mOrigDebugApp = null; 1052 boolean mOrigWaitForDebugger = false; 1053 boolean mAlwaysFinishActivities = false; 1054 IActivityController mController = null; 1055 String mProfileApp = null; 1056 ProcessRecord mProfileProc = null; 1057 String mProfileFile; 1058 ParcelFileDescriptor mProfileFd; 1059 int mSamplingInterval = 0; 1060 boolean mAutoStopProfiler = false; 1061 int mProfileType = 0; 1062 String mOpenGlTraceApp = null; 1063 1064 static class ProcessChangeItem { 1065 static final int CHANGE_ACTIVITIES = 1<<0; 1066 static final int CHANGE_PROCESS_STATE = 1<<1; 1067 int changes; 1068 int uid; 1069 int pid; 1070 int processState; 1071 boolean foregroundActivities; 1072 } 1073 1074 final RemoteCallbackList<IProcessObserver> mProcessObservers 1075 = new RemoteCallbackList<IProcessObserver>(); 1076 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1077 1078 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1079 = new ArrayList<ProcessChangeItem>(); 1080 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1081 = new ArrayList<ProcessChangeItem>(); 1082 1083 /** 1084 * Runtime CPU use collection thread. This object's lock is used to 1085 * perform synchronization with the thread (notifying it to run). 1086 */ 1087 final Thread mProcessCpuThread; 1088 1089 /** 1090 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1091 * Must acquire this object's lock when accessing it. 1092 * NOTE: this lock will be held while doing long operations (trawling 1093 * through all processes in /proc), so it should never be acquired by 1094 * any critical paths such as when holding the main activity manager lock. 1095 */ 1096 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1097 MONITOR_THREAD_CPU_USAGE); 1098 final AtomicLong mLastCpuTime = new AtomicLong(0); 1099 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1100 1101 long mLastWriteTime = 0; 1102 1103 /** 1104 * Used to retain an update lock when the foreground activity is in 1105 * immersive mode. 1106 */ 1107 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1108 1109 /** 1110 * Set to true after the system has finished booting. 1111 */ 1112 boolean mBooted = false; 1113 1114 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1115 int mProcessLimitOverride = -1; 1116 1117 WindowManagerService mWindowManager; 1118 1119 final ActivityThread mSystemThread; 1120 1121 // Holds the current foreground user's id 1122 int mCurrentUserId = 0; 1123 // Holds the target user's id during a user switch 1124 int mTargetUserId = UserHandle.USER_NULL; 1125 // If there are multiple profiles for the current user, their ids are here 1126 // Currently only the primary user can have managed profiles 1127 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1128 1129 /** 1130 * Mapping from each known user ID to the profile group ID it is associated with. 1131 */ 1132 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1133 1134 private UserManagerService mUserManager; 1135 1136 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1137 final ProcessRecord mApp; 1138 final int mPid; 1139 final IApplicationThread mAppThread; 1140 1141 AppDeathRecipient(ProcessRecord app, int pid, 1142 IApplicationThread thread) { 1143 if (localLOGV) Slog.v( 1144 TAG, "New death recipient " + this 1145 + " for thread " + thread.asBinder()); 1146 mApp = app; 1147 mPid = pid; 1148 mAppThread = thread; 1149 } 1150 1151 @Override 1152 public void binderDied() { 1153 if (localLOGV) Slog.v( 1154 TAG, "Death received in " + this 1155 + " for thread " + mAppThread.asBinder()); 1156 synchronized(ActivityManagerService.this) { 1157 appDiedLocked(mApp, mPid, mAppThread); 1158 } 1159 } 1160 } 1161 1162 static final int SHOW_ERROR_MSG = 1; 1163 static final int SHOW_NOT_RESPONDING_MSG = 2; 1164 static final int SHOW_FACTORY_ERROR_MSG = 3; 1165 static final int UPDATE_CONFIGURATION_MSG = 4; 1166 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1167 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1168 static final int SERVICE_TIMEOUT_MSG = 12; 1169 static final int UPDATE_TIME_ZONE = 13; 1170 static final int SHOW_UID_ERROR_MSG = 14; 1171 static final int IM_FEELING_LUCKY_MSG = 15; 1172 static final int PROC_START_TIMEOUT_MSG = 20; 1173 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1174 static final int KILL_APPLICATION_MSG = 22; 1175 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1176 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1177 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1178 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1179 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1180 static final int CLEAR_DNS_CACHE_MSG = 28; 1181 static final int UPDATE_HTTP_PROXY_MSG = 29; 1182 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1183 static final int DISPATCH_PROCESSES_CHANGED = 31; 1184 static final int DISPATCH_PROCESS_DIED = 32; 1185 static final int REPORT_MEM_USAGE_MSG = 33; 1186 static final int REPORT_USER_SWITCH_MSG = 34; 1187 static final int CONTINUE_USER_SWITCH_MSG = 35; 1188 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1189 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1190 static final int PERSIST_URI_GRANTS_MSG = 38; 1191 static final int REQUEST_ALL_PSS_MSG = 39; 1192 static final int START_PROFILES_MSG = 40; 1193 static final int UPDATE_TIME = 41; 1194 static final int SYSTEM_USER_START_MSG = 42; 1195 static final int SYSTEM_USER_CURRENT_MSG = 43; 1196 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1197 static final int FINISH_BOOTING_MSG = 45; 1198 static final int START_USER_SWITCH_MSG = 46; 1199 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1200 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50; 1201 1202 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1203 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1204 static final int FIRST_COMPAT_MODE_MSG = 300; 1205 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1206 1207 AlertDialog mUidAlert; 1208 CompatModeDialog mCompatModeDialog; 1209 long mLastMemUsageReportTime = 0; 1210 1211 private LockToAppRequestDialog mLockToAppRequest; 1212 1213 /** 1214 * Flag whether the current user is a "monkey", i.e. whether 1215 * the UI is driven by a UI automation tool. 1216 */ 1217 private boolean mUserIsMonkey; 1218 1219 /** Flag whether the device has a Recents UI */ 1220 boolean mHasRecents; 1221 1222 /** The dimensions of the thumbnails in the Recents UI. */ 1223 int mThumbnailWidth; 1224 int mThumbnailHeight; 1225 1226 final ServiceThread mHandlerThread; 1227 final MainHandler mHandler; 1228 1229 final class MainHandler extends Handler { 1230 public MainHandler(Looper looper) { 1231 super(looper, null, true); 1232 } 1233 1234 @Override 1235 public void handleMessage(Message msg) { 1236 switch (msg.what) { 1237 case SHOW_ERROR_MSG: { 1238 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1239 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1240 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1241 synchronized (ActivityManagerService.this) { 1242 ProcessRecord proc = (ProcessRecord)data.get("app"); 1243 AppErrorResult res = (AppErrorResult) data.get("result"); 1244 if (proc != null && proc.crashDialog != null) { 1245 Slog.e(TAG, "App already has crash dialog: " + proc); 1246 if (res != null) { 1247 res.set(0); 1248 } 1249 return; 1250 } 1251 boolean isBackground = (UserHandle.getAppId(proc.uid) 1252 >= Process.FIRST_APPLICATION_UID 1253 && proc.pid != MY_PID); 1254 for (int userId : mCurrentProfileIds) { 1255 isBackground &= (proc.userId != userId); 1256 } 1257 if (isBackground && !showBackground) { 1258 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1259 if (res != null) { 1260 res.set(0); 1261 } 1262 return; 1263 } 1264 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1265 Dialog d = new AppErrorDialog(mContext, 1266 ActivityManagerService.this, res, proc); 1267 d.show(); 1268 proc.crashDialog = d; 1269 } else { 1270 // The device is asleep, so just pretend that the user 1271 // saw a crash dialog and hit "force quit". 1272 if (res != null) { 1273 res.set(0); 1274 } 1275 } 1276 } 1277 1278 ensureBootCompleted(); 1279 } break; 1280 case SHOW_NOT_RESPONDING_MSG: { 1281 synchronized (ActivityManagerService.this) { 1282 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1283 ProcessRecord proc = (ProcessRecord)data.get("app"); 1284 if (proc != null && proc.anrDialog != null) { 1285 Slog.e(TAG, "App already has anr dialog: " + proc); 1286 return; 1287 } 1288 1289 Intent intent = new Intent("android.intent.action.ANR"); 1290 if (!mProcessesReady) { 1291 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1292 | Intent.FLAG_RECEIVER_FOREGROUND); 1293 } 1294 broadcastIntentLocked(null, null, intent, 1295 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1296 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1297 1298 if (mShowDialogs) { 1299 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1300 mContext, proc, (ActivityRecord)data.get("activity"), 1301 msg.arg1 != 0); 1302 d.show(); 1303 proc.anrDialog = d; 1304 } else { 1305 // Just kill the app if there is no dialog to be shown. 1306 killAppAtUsersRequest(proc, null); 1307 } 1308 } 1309 1310 ensureBootCompleted(); 1311 } break; 1312 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1313 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1314 synchronized (ActivityManagerService.this) { 1315 ProcessRecord proc = (ProcessRecord) data.get("app"); 1316 if (proc == null) { 1317 Slog.e(TAG, "App not found when showing strict mode dialog."); 1318 break; 1319 } 1320 if (proc.crashDialog != null) { 1321 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1322 return; 1323 } 1324 AppErrorResult res = (AppErrorResult) data.get("result"); 1325 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1326 Dialog d = new StrictModeViolationDialog(mContext, 1327 ActivityManagerService.this, res, proc); 1328 d.show(); 1329 proc.crashDialog = d; 1330 } else { 1331 // The device is asleep, so just pretend that the user 1332 // saw a crash dialog and hit "force quit". 1333 res.set(0); 1334 } 1335 } 1336 ensureBootCompleted(); 1337 } break; 1338 case SHOW_FACTORY_ERROR_MSG: { 1339 Dialog d = new FactoryErrorDialog( 1340 mContext, msg.getData().getCharSequence("msg")); 1341 d.show(); 1342 ensureBootCompleted(); 1343 } break; 1344 case UPDATE_CONFIGURATION_MSG: { 1345 final ContentResolver resolver = mContext.getContentResolver(); 1346 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1347 } break; 1348 case GC_BACKGROUND_PROCESSES_MSG: { 1349 synchronized (ActivityManagerService.this) { 1350 performAppGcsIfAppropriateLocked(); 1351 } 1352 } break; 1353 case WAIT_FOR_DEBUGGER_MSG: { 1354 synchronized (ActivityManagerService.this) { 1355 ProcessRecord app = (ProcessRecord)msg.obj; 1356 if (msg.arg1 != 0) { 1357 if (!app.waitedForDebugger) { 1358 Dialog d = new AppWaitingForDebuggerDialog( 1359 ActivityManagerService.this, 1360 mContext, app); 1361 app.waitDialog = d; 1362 app.waitedForDebugger = true; 1363 d.show(); 1364 } 1365 } else { 1366 if (app.waitDialog != null) { 1367 app.waitDialog.dismiss(); 1368 app.waitDialog = null; 1369 } 1370 } 1371 } 1372 } break; 1373 case SERVICE_TIMEOUT_MSG: { 1374 if (mDidDexOpt) { 1375 mDidDexOpt = false; 1376 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1377 nmsg.obj = msg.obj; 1378 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1379 return; 1380 } 1381 mServices.serviceTimeout((ProcessRecord)msg.obj); 1382 } break; 1383 case UPDATE_TIME_ZONE: { 1384 synchronized (ActivityManagerService.this) { 1385 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1386 ProcessRecord r = mLruProcesses.get(i); 1387 if (r.thread != null) { 1388 try { 1389 r.thread.updateTimeZone(); 1390 } catch (RemoteException ex) { 1391 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1392 } 1393 } 1394 } 1395 } 1396 } break; 1397 case CLEAR_DNS_CACHE_MSG: { 1398 synchronized (ActivityManagerService.this) { 1399 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1400 ProcessRecord r = mLruProcesses.get(i); 1401 if (r.thread != null) { 1402 try { 1403 r.thread.clearDnsCache(); 1404 } catch (RemoteException ex) { 1405 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1406 } 1407 } 1408 } 1409 } 1410 } break; 1411 case UPDATE_HTTP_PROXY_MSG: { 1412 ProxyInfo proxy = (ProxyInfo)msg.obj; 1413 String host = ""; 1414 String port = ""; 1415 String exclList = ""; 1416 Uri pacFileUrl = Uri.EMPTY; 1417 if (proxy != null) { 1418 host = proxy.getHost(); 1419 port = Integer.toString(proxy.getPort()); 1420 exclList = proxy.getExclusionListAsString(); 1421 pacFileUrl = proxy.getPacFileUrl(); 1422 } 1423 synchronized (ActivityManagerService.this) { 1424 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1425 ProcessRecord r = mLruProcesses.get(i); 1426 if (r.thread != null) { 1427 try { 1428 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1429 } catch (RemoteException ex) { 1430 Slog.w(TAG, "Failed to update http proxy for: " + 1431 r.info.processName); 1432 } 1433 } 1434 } 1435 } 1436 } break; 1437 case SHOW_UID_ERROR_MSG: { 1438 String title = "System UIDs Inconsistent"; 1439 String text = "UIDs on the system are inconsistent, you need to wipe your" 1440 + " data partition or your device will be unstable."; 1441 Log.e(TAG, title + ": " + text); 1442 if (mShowDialogs) { 1443 // XXX This is a temporary dialog, no need to localize. 1444 AlertDialog d = new BaseErrorDialog(mContext); 1445 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1446 d.setCancelable(false); 1447 d.setTitle(title); 1448 d.setMessage(text); 1449 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1450 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1451 mUidAlert = d; 1452 d.show(); 1453 } 1454 } break; 1455 case IM_FEELING_LUCKY_MSG: { 1456 if (mUidAlert != null) { 1457 mUidAlert.dismiss(); 1458 mUidAlert = null; 1459 } 1460 } break; 1461 case PROC_START_TIMEOUT_MSG: { 1462 if (mDidDexOpt) { 1463 mDidDexOpt = false; 1464 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1465 nmsg.obj = msg.obj; 1466 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1467 return; 1468 } 1469 ProcessRecord app = (ProcessRecord)msg.obj; 1470 synchronized (ActivityManagerService.this) { 1471 processStartTimedOutLocked(app); 1472 } 1473 } break; 1474 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1475 synchronized (ActivityManagerService.this) { 1476 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1477 } 1478 } break; 1479 case KILL_APPLICATION_MSG: { 1480 synchronized (ActivityManagerService.this) { 1481 int appid = msg.arg1; 1482 boolean restart = (msg.arg2 == 1); 1483 Bundle bundle = (Bundle)msg.obj; 1484 String pkg = bundle.getString("pkg"); 1485 String reason = bundle.getString("reason"); 1486 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1487 false, UserHandle.USER_ALL, reason); 1488 } 1489 } break; 1490 case FINALIZE_PENDING_INTENT_MSG: { 1491 ((PendingIntentRecord)msg.obj).completeFinalize(); 1492 } break; 1493 case POST_HEAVY_NOTIFICATION_MSG: { 1494 INotificationManager inm = NotificationManager.getService(); 1495 if (inm == null) { 1496 return; 1497 } 1498 1499 ActivityRecord root = (ActivityRecord)msg.obj; 1500 ProcessRecord process = root.app; 1501 if (process == null) { 1502 return; 1503 } 1504 1505 try { 1506 Context context = mContext.createPackageContext(process.info.packageName, 0); 1507 String text = mContext.getString(R.string.heavy_weight_notification, 1508 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1509 Notification notification = new Notification(); 1510 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1511 notification.when = 0; 1512 notification.flags = Notification.FLAG_ONGOING_EVENT; 1513 notification.tickerText = text; 1514 notification.defaults = 0; // please be quiet 1515 notification.sound = null; 1516 notification.vibrate = null; 1517 notification.color = mContext.getResources().getColor( 1518 com.android.internal.R.color.system_notification_accent_color); 1519 notification.setLatestEventInfo(context, text, 1520 mContext.getText(R.string.heavy_weight_notification_detail), 1521 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1522 PendingIntent.FLAG_CANCEL_CURRENT, null, 1523 new UserHandle(root.userId))); 1524 1525 try { 1526 int[] outId = new int[1]; 1527 inm.enqueueNotificationWithTag("android", "android", null, 1528 R.string.heavy_weight_notification, 1529 notification, outId, root.userId); 1530 } catch (RuntimeException e) { 1531 Slog.w(ActivityManagerService.TAG, 1532 "Error showing notification for heavy-weight app", e); 1533 } catch (RemoteException e) { 1534 } 1535 } catch (NameNotFoundException e) { 1536 Slog.w(TAG, "Unable to create context for heavy notification", e); 1537 } 1538 } break; 1539 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1540 INotificationManager inm = NotificationManager.getService(); 1541 if (inm == null) { 1542 return; 1543 } 1544 try { 1545 inm.cancelNotificationWithTag("android", null, 1546 R.string.heavy_weight_notification, msg.arg1); 1547 } catch (RuntimeException e) { 1548 Slog.w(ActivityManagerService.TAG, 1549 "Error canceling notification for service", e); 1550 } catch (RemoteException e) { 1551 } 1552 } break; 1553 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1554 synchronized (ActivityManagerService.this) { 1555 checkExcessivePowerUsageLocked(true); 1556 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1557 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1558 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1559 } 1560 } break; 1561 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1562 synchronized (ActivityManagerService.this) { 1563 ActivityRecord ar = (ActivityRecord)msg.obj; 1564 if (mCompatModeDialog != null) { 1565 if (mCompatModeDialog.mAppInfo.packageName.equals( 1566 ar.info.applicationInfo.packageName)) { 1567 return; 1568 } 1569 mCompatModeDialog.dismiss(); 1570 mCompatModeDialog = null; 1571 } 1572 if (ar != null && false) { 1573 if (mCompatModePackages.getPackageAskCompatModeLocked( 1574 ar.packageName)) { 1575 int mode = mCompatModePackages.computeCompatModeLocked( 1576 ar.info.applicationInfo); 1577 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1578 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1579 mCompatModeDialog = new CompatModeDialog( 1580 ActivityManagerService.this, mContext, 1581 ar.info.applicationInfo); 1582 mCompatModeDialog.show(); 1583 } 1584 } 1585 } 1586 } 1587 break; 1588 } 1589 case DISPATCH_PROCESSES_CHANGED: { 1590 dispatchProcessesChanged(); 1591 break; 1592 } 1593 case DISPATCH_PROCESS_DIED: { 1594 final int pid = msg.arg1; 1595 final int uid = msg.arg2; 1596 dispatchProcessDied(pid, uid); 1597 break; 1598 } 1599 case REPORT_MEM_USAGE_MSG: { 1600 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1601 Thread thread = new Thread() { 1602 @Override public void run() { 1603 final SparseArray<ProcessMemInfo> infoMap 1604 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1605 for (int i=0, N=memInfos.size(); i<N; i++) { 1606 ProcessMemInfo mi = memInfos.get(i); 1607 infoMap.put(mi.pid, mi); 1608 } 1609 updateCpuStatsNow(); 1610 synchronized (mProcessCpuTracker) { 1611 final int N = mProcessCpuTracker.countStats(); 1612 for (int i=0; i<N; i++) { 1613 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1614 if (st.vsize > 0) { 1615 long pss = Debug.getPss(st.pid, null); 1616 if (pss > 0) { 1617 if (infoMap.indexOfKey(st.pid) < 0) { 1618 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1619 ProcessList.NATIVE_ADJ, -1, "native", null); 1620 mi.pss = pss; 1621 memInfos.add(mi); 1622 } 1623 } 1624 } 1625 } 1626 } 1627 1628 long totalPss = 0; 1629 for (int i=0, N=memInfos.size(); i<N; i++) { 1630 ProcessMemInfo mi = memInfos.get(i); 1631 if (mi.pss == 0) { 1632 mi.pss = Debug.getPss(mi.pid, null); 1633 } 1634 totalPss += mi.pss; 1635 } 1636 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1637 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1638 if (lhs.oomAdj != rhs.oomAdj) { 1639 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1640 } 1641 if (lhs.pss != rhs.pss) { 1642 return lhs.pss < rhs.pss ? 1 : -1; 1643 } 1644 return 0; 1645 } 1646 }); 1647 1648 StringBuilder tag = new StringBuilder(128); 1649 StringBuilder stack = new StringBuilder(128); 1650 tag.append("Low on memory -- "); 1651 appendMemBucket(tag, totalPss, "total", false); 1652 appendMemBucket(stack, totalPss, "total", true); 1653 1654 StringBuilder logBuilder = new StringBuilder(1024); 1655 logBuilder.append("Low on memory:\n"); 1656 1657 boolean firstLine = true; 1658 int lastOomAdj = Integer.MIN_VALUE; 1659 for (int i=0, N=memInfos.size(); i<N; i++) { 1660 ProcessMemInfo mi = memInfos.get(i); 1661 1662 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1663 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1664 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1665 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1666 if (lastOomAdj != mi.oomAdj) { 1667 lastOomAdj = mi.oomAdj; 1668 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1669 tag.append(" / "); 1670 } 1671 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1672 if (firstLine) { 1673 stack.append(":"); 1674 firstLine = false; 1675 } 1676 stack.append("\n\t at "); 1677 } else { 1678 stack.append("$"); 1679 } 1680 } else { 1681 tag.append(" "); 1682 stack.append("$"); 1683 } 1684 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1685 appendMemBucket(tag, mi.pss, mi.name, false); 1686 } 1687 appendMemBucket(stack, mi.pss, mi.name, true); 1688 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1689 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1690 stack.append("("); 1691 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1692 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1693 stack.append(DUMP_MEM_OOM_LABEL[k]); 1694 stack.append(":"); 1695 stack.append(DUMP_MEM_OOM_ADJ[k]); 1696 } 1697 } 1698 stack.append(")"); 1699 } 1700 } 1701 1702 logBuilder.append(" "); 1703 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1704 logBuilder.append(' '); 1705 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1706 logBuilder.append(' '); 1707 ProcessList.appendRamKb(logBuilder, mi.pss); 1708 logBuilder.append(" kB: "); 1709 logBuilder.append(mi.name); 1710 logBuilder.append(" ("); 1711 logBuilder.append(mi.pid); 1712 logBuilder.append(") "); 1713 logBuilder.append(mi.adjType); 1714 logBuilder.append('\n'); 1715 if (mi.adjReason != null) { 1716 logBuilder.append(" "); 1717 logBuilder.append(mi.adjReason); 1718 logBuilder.append('\n'); 1719 } 1720 } 1721 1722 logBuilder.append(" "); 1723 ProcessList.appendRamKb(logBuilder, totalPss); 1724 logBuilder.append(" kB: TOTAL\n"); 1725 1726 long[] infos = new long[Debug.MEMINFO_COUNT]; 1727 Debug.getMemInfo(infos); 1728 logBuilder.append(" MemInfo: "); 1729 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1730 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1731 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1732 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1733 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1734 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1735 logBuilder.append(" ZRAM: "); 1736 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1737 logBuilder.append(" kB RAM, "); 1738 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1739 logBuilder.append(" kB swap total, "); 1740 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1741 logBuilder.append(" kB swap free\n"); 1742 } 1743 Slog.i(TAG, logBuilder.toString()); 1744 1745 StringBuilder dropBuilder = new StringBuilder(1024); 1746 /* 1747 StringWriter oomSw = new StringWriter(); 1748 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1749 StringWriter catSw = new StringWriter(); 1750 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1751 String[] emptyArgs = new String[] { }; 1752 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1753 oomPw.flush(); 1754 String oomString = oomSw.toString(); 1755 */ 1756 dropBuilder.append(stack); 1757 dropBuilder.append('\n'); 1758 dropBuilder.append('\n'); 1759 dropBuilder.append(logBuilder); 1760 dropBuilder.append('\n'); 1761 /* 1762 dropBuilder.append(oomString); 1763 dropBuilder.append('\n'); 1764 */ 1765 StringWriter catSw = new StringWriter(); 1766 synchronized (ActivityManagerService.this) { 1767 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1768 String[] emptyArgs = new String[] { }; 1769 catPw.println(); 1770 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1771 catPw.println(); 1772 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1773 false, false, null); 1774 catPw.println(); 1775 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1776 catPw.flush(); 1777 } 1778 dropBuilder.append(catSw.toString()); 1779 addErrorToDropBox("lowmem", null, "system_server", null, 1780 null, tag.toString(), dropBuilder.toString(), null, null); 1781 //Slog.i(TAG, "Sent to dropbox:"); 1782 //Slog.i(TAG, dropBuilder.toString()); 1783 synchronized (ActivityManagerService.this) { 1784 long now = SystemClock.uptimeMillis(); 1785 if (mLastMemUsageReportTime < now) { 1786 mLastMemUsageReportTime = now; 1787 } 1788 } 1789 } 1790 }; 1791 thread.start(); 1792 break; 1793 } 1794 case START_USER_SWITCH_MSG: { 1795 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1796 break; 1797 } 1798 case REPORT_USER_SWITCH_MSG: { 1799 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1800 break; 1801 } 1802 case CONTINUE_USER_SWITCH_MSG: { 1803 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1804 break; 1805 } 1806 case USER_SWITCH_TIMEOUT_MSG: { 1807 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1808 break; 1809 } 1810 case IMMERSIVE_MODE_LOCK_MSG: { 1811 final boolean nextState = (msg.arg1 != 0); 1812 if (mUpdateLock.isHeld() != nextState) { 1813 if (DEBUG_IMMERSIVE) { 1814 final ActivityRecord r = (ActivityRecord) msg.obj; 1815 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1816 } 1817 if (nextState) { 1818 mUpdateLock.acquire(); 1819 } else { 1820 mUpdateLock.release(); 1821 } 1822 } 1823 break; 1824 } 1825 case PERSIST_URI_GRANTS_MSG: { 1826 writeGrantedUriPermissions(); 1827 break; 1828 } 1829 case REQUEST_ALL_PSS_MSG: { 1830 synchronized (ActivityManagerService.this) { 1831 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1832 } 1833 break; 1834 } 1835 case START_PROFILES_MSG: { 1836 synchronized (ActivityManagerService.this) { 1837 startProfilesLocked(); 1838 } 1839 break; 1840 } 1841 case UPDATE_TIME: { 1842 synchronized (ActivityManagerService.this) { 1843 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1844 ProcessRecord r = mLruProcesses.get(i); 1845 if (r.thread != null) { 1846 try { 1847 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1848 } catch (RemoteException ex) { 1849 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1850 } 1851 } 1852 } 1853 } 1854 break; 1855 } 1856 case SYSTEM_USER_START_MSG: { 1857 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1858 Integer.toString(msg.arg1), msg.arg1); 1859 mSystemServiceManager.startUser(msg.arg1); 1860 break; 1861 } 1862 case SYSTEM_USER_CURRENT_MSG: { 1863 mBatteryStatsService.noteEvent( 1864 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1865 Integer.toString(msg.arg2), msg.arg2); 1866 mBatteryStatsService.noteEvent( 1867 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1868 Integer.toString(msg.arg1), msg.arg1); 1869 mSystemServiceManager.switchUser(msg.arg1); 1870 mLockToAppRequest.clearPrompt(); 1871 break; 1872 } 1873 case ENTER_ANIMATION_COMPLETE_MSG: { 1874 synchronized (ActivityManagerService.this) { 1875 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1876 if (r != null && r.app != null && r.app.thread != null) { 1877 try { 1878 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1879 } catch (RemoteException e) { 1880 } 1881 } 1882 } 1883 break; 1884 } 1885 case FINISH_BOOTING_MSG: { 1886 if (msg.arg1 != 0) { 1887 finishBooting(); 1888 } 1889 if (msg.arg2 != 0) { 1890 enableScreenAfterBoot(); 1891 } 1892 break; 1893 } 1894 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1895 try { 1896 Locale l = (Locale) msg.obj; 1897 IBinder service = ServiceManager.getService("mount"); 1898 IMountService mountService = IMountService.Stub.asInterface(service); 1899 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1900 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1901 } catch (RemoteException e) { 1902 Log.e(TAG, "Error storing locale for decryption UI", e); 1903 } 1904 break; 1905 } 1906 case NOTIFY_CLEARTEXT_NETWORK_MSG: { 1907 final int uid = msg.arg1; 1908 final byte[] firstPacket = (byte[]) msg.obj; 1909 1910 synchronized (mPidsSelfLocked) { 1911 for (int i = 0; i < mPidsSelfLocked.size(); i++) { 1912 final ProcessRecord p = mPidsSelfLocked.valueAt(i); 1913 if (p.uid == uid) { 1914 try { 1915 p.thread.notifyCleartextNetwork(firstPacket); 1916 } catch (RemoteException ignored) { 1917 } 1918 } 1919 } 1920 } 1921 break; 1922 } 1923 } 1924 } 1925 }; 1926 1927 static final int COLLECT_PSS_BG_MSG = 1; 1928 1929 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1930 @Override 1931 public void handleMessage(Message msg) { 1932 switch (msg.what) { 1933 case COLLECT_PSS_BG_MSG: { 1934 long start = SystemClock.uptimeMillis(); 1935 MemInfoReader memInfo = null; 1936 synchronized (ActivityManagerService.this) { 1937 if (mFullPssPending) { 1938 mFullPssPending = false; 1939 memInfo = new MemInfoReader(); 1940 } 1941 } 1942 if (memInfo != null) { 1943 updateCpuStatsNow(); 1944 long nativeTotalPss = 0; 1945 synchronized (mProcessCpuTracker) { 1946 final int N = mProcessCpuTracker.countStats(); 1947 for (int j=0; j<N; j++) { 1948 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1949 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1950 // This is definitely an application process; skip it. 1951 continue; 1952 } 1953 synchronized (mPidsSelfLocked) { 1954 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1955 // This is one of our own processes; skip it. 1956 continue; 1957 } 1958 } 1959 nativeTotalPss += Debug.getPss(st.pid, null); 1960 } 1961 } 1962 memInfo.readMemInfo(); 1963 synchronized (ActivityManagerService.this) { 1964 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1965 + (SystemClock.uptimeMillis()-start) + "ms"); 1966 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1967 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1968 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1969 +memInfo.getSlabSizeKb(), 1970 nativeTotalPss); 1971 } 1972 } 1973 1974 int i=0, num=0; 1975 long[] tmp = new long[1]; 1976 do { 1977 ProcessRecord proc; 1978 int procState; 1979 int pid; 1980 synchronized (ActivityManagerService.this) { 1981 if (i >= mPendingPssProcesses.size()) { 1982 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1983 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1984 mPendingPssProcesses.clear(); 1985 return; 1986 } 1987 proc = mPendingPssProcesses.get(i); 1988 procState = proc.pssProcState; 1989 if (proc.thread != null && procState == proc.setProcState) { 1990 pid = proc.pid; 1991 } else { 1992 proc = null; 1993 pid = 0; 1994 } 1995 i++; 1996 } 1997 if (proc != null) { 1998 long pss = Debug.getPss(pid, tmp); 1999 synchronized (ActivityManagerService.this) { 2000 if (proc.thread != null && proc.setProcState == procState 2001 && proc.pid == pid) { 2002 num++; 2003 proc.lastPssTime = SystemClock.uptimeMillis(); 2004 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 2005 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 2006 + ": " + pss + " lastPss=" + proc.lastPss 2007 + " state=" + ProcessList.makeProcStateString(procState)); 2008 if (proc.initialIdlePss == 0) { 2009 proc.initialIdlePss = pss; 2010 } 2011 proc.lastPss = pss; 2012 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 2013 proc.lastCachedPss = pss; 2014 } 2015 } 2016 } 2017 } 2018 } while (true); 2019 } 2020 } 2021 } 2022 }; 2023 2024 /** 2025 * Monitor for package changes and update our internal state. 2026 */ 2027 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 2028 @Override 2029 public void onPackageRemoved(String packageName, int uid) { 2030 // Remove all tasks with activities in the specified package from the list of recent tasks 2031 final int eventUserId = getChangingUserId(); 2032 synchronized (ActivityManagerService.this) { 2033 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2034 TaskRecord tr = mRecentTasks.get(i); 2035 if (tr.userId != eventUserId) continue; 2036 2037 ComponentName cn = tr.intent.getComponent(); 2038 if (cn != null && cn.getPackageName().equals(packageName)) { 2039 // If the package name matches, remove the task and kill the process 2040 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2041 } 2042 } 2043 } 2044 } 2045 2046 @Override 2047 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2048 onPackageModified(packageName); 2049 return true; 2050 } 2051 2052 @Override 2053 public void onPackageModified(String packageName) { 2054 final int eventUserId = getChangingUserId(); 2055 final IPackageManager pm = AppGlobals.getPackageManager(); 2056 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2057 new ArrayList<Pair<Intent, Integer>>(); 2058 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2059 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2060 // Copy the list of recent tasks so that we don't hold onto the lock on 2061 // ActivityManagerService for long periods while checking if components exist. 2062 synchronized (ActivityManagerService.this) { 2063 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2064 TaskRecord tr = mRecentTasks.get(i); 2065 if (tr.userId != eventUserId) continue; 2066 2067 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2068 } 2069 } 2070 // Check the recent tasks and filter out all tasks with components that no longer exist. 2071 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2072 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2073 ComponentName cn = p.first.getComponent(); 2074 if (cn != null && cn.getPackageName().equals(packageName)) { 2075 if (componentsKnownToExist.contains(cn)) { 2076 // If we know that the component still exists in the package, then skip 2077 continue; 2078 } 2079 try { 2080 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 2081 if (info != null) { 2082 componentsKnownToExist.add(cn); 2083 } else { 2084 tasksToRemove.add(p.second); 2085 } 2086 } catch (RemoteException e) { 2087 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 2088 } 2089 } 2090 } 2091 // Prune all the tasks with removed components from the list of recent tasks 2092 synchronized (ActivityManagerService.this) { 2093 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2094 // Remove the task but don't kill the process (since other components in that 2095 // package may still be running and in the background) 2096 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2097 } 2098 } 2099 } 2100 2101 @Override 2102 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2103 // Force stop the specified packages 2104 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2105 if (packages != null) { 2106 for (String pkg : packages) { 2107 synchronized (ActivityManagerService.this) { 2108 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2109 userId, "finished booting")) { 2110 return true; 2111 } 2112 } 2113 } 2114 } 2115 return false; 2116 } 2117 }; 2118 2119 public void setSystemProcess() { 2120 try { 2121 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2122 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2123 ServiceManager.addService("meminfo", new MemBinder(this)); 2124 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2125 ServiceManager.addService("dbinfo", new DbBinder(this)); 2126 if (MONITOR_CPU_USAGE) { 2127 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2128 } 2129 ServiceManager.addService("permission", new PermissionController(this)); 2130 2131 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2132 "android", STOCK_PM_FLAGS); 2133 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2134 2135 synchronized (this) { 2136 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2137 app.persistent = true; 2138 app.pid = MY_PID; 2139 app.maxAdj = ProcessList.SYSTEM_ADJ; 2140 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2141 mProcessNames.put(app.processName, app.uid, app); 2142 synchronized (mPidsSelfLocked) { 2143 mPidsSelfLocked.put(app.pid, app); 2144 } 2145 updateLruProcessLocked(app, false, null); 2146 updateOomAdjLocked(); 2147 } 2148 } catch (PackageManager.NameNotFoundException e) { 2149 throw new RuntimeException( 2150 "Unable to find android system package", e); 2151 } 2152 } 2153 2154 public void setWindowManager(WindowManagerService wm) { 2155 mWindowManager = wm; 2156 mStackSupervisor.setWindowManager(wm); 2157 } 2158 2159 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2160 mUsageStatsService = usageStatsManager; 2161 } 2162 2163 public void startObservingNativeCrashes() { 2164 final NativeCrashListener ncl = new NativeCrashListener(this); 2165 ncl.start(); 2166 } 2167 2168 public IAppOpsService getAppOpsService() { 2169 return mAppOpsService; 2170 } 2171 2172 static class MemBinder extends Binder { 2173 ActivityManagerService mActivityManagerService; 2174 MemBinder(ActivityManagerService activityManagerService) { 2175 mActivityManagerService = activityManagerService; 2176 } 2177 2178 @Override 2179 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2180 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2181 != PackageManager.PERMISSION_GRANTED) { 2182 pw.println("Permission Denial: can't dump meminfo from from pid=" 2183 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2184 + " without permission " + android.Manifest.permission.DUMP); 2185 return; 2186 } 2187 2188 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2189 } 2190 } 2191 2192 static class GraphicsBinder extends Binder { 2193 ActivityManagerService mActivityManagerService; 2194 GraphicsBinder(ActivityManagerService activityManagerService) { 2195 mActivityManagerService = activityManagerService; 2196 } 2197 2198 @Override 2199 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2200 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2201 != PackageManager.PERMISSION_GRANTED) { 2202 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2203 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2204 + " without permission " + android.Manifest.permission.DUMP); 2205 return; 2206 } 2207 2208 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2209 } 2210 } 2211 2212 static class DbBinder extends Binder { 2213 ActivityManagerService mActivityManagerService; 2214 DbBinder(ActivityManagerService activityManagerService) { 2215 mActivityManagerService = activityManagerService; 2216 } 2217 2218 @Override 2219 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2220 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2221 != PackageManager.PERMISSION_GRANTED) { 2222 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2223 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2224 + " without permission " + android.Manifest.permission.DUMP); 2225 return; 2226 } 2227 2228 mActivityManagerService.dumpDbInfo(fd, pw, args); 2229 } 2230 } 2231 2232 static class CpuBinder extends Binder { 2233 ActivityManagerService mActivityManagerService; 2234 CpuBinder(ActivityManagerService activityManagerService) { 2235 mActivityManagerService = activityManagerService; 2236 } 2237 2238 @Override 2239 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2240 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2241 != PackageManager.PERMISSION_GRANTED) { 2242 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2243 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2244 + " without permission " + android.Manifest.permission.DUMP); 2245 return; 2246 } 2247 2248 synchronized (mActivityManagerService.mProcessCpuTracker) { 2249 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2250 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2251 SystemClock.uptimeMillis())); 2252 } 2253 } 2254 } 2255 2256 public static final class Lifecycle extends SystemService { 2257 private final ActivityManagerService mService; 2258 2259 public Lifecycle(Context context) { 2260 super(context); 2261 mService = new ActivityManagerService(context); 2262 } 2263 2264 @Override 2265 public void onStart() { 2266 mService.start(); 2267 } 2268 2269 public ActivityManagerService getService() { 2270 return mService; 2271 } 2272 } 2273 2274 // Note: This method is invoked on the main thread but may need to attach various 2275 // handlers to other threads. So take care to be explicit about the looper. 2276 public ActivityManagerService(Context systemContext) { 2277 mContext = systemContext; 2278 mFactoryTest = FactoryTest.getMode(); 2279 mSystemThread = ActivityThread.currentActivityThread(); 2280 2281 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2282 2283 mHandlerThread = new ServiceThread(TAG, 2284 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2285 mHandlerThread.start(); 2286 mHandler = new MainHandler(mHandlerThread.getLooper()); 2287 2288 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2289 "foreground", BROADCAST_FG_TIMEOUT, false); 2290 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2291 "background", BROADCAST_BG_TIMEOUT, true); 2292 mBroadcastQueues[0] = mFgBroadcastQueue; 2293 mBroadcastQueues[1] = mBgBroadcastQueue; 2294 2295 mServices = new ActiveServices(this); 2296 mProviderMap = new ProviderMap(this); 2297 2298 // TODO: Move creation of battery stats service outside of activity manager service. 2299 File dataDir = Environment.getDataDirectory(); 2300 File systemDir = new File(dataDir, "system"); 2301 systemDir.mkdirs(); 2302 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2303 mBatteryStatsService.getActiveStatistics().readLocked(); 2304 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2305 mOnBattery = DEBUG_POWER ? true 2306 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2307 mBatteryStatsService.getActiveStatistics().setCallback(this); 2308 2309 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2310 2311 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2312 2313 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2314 2315 // User 0 is the first and only user that runs at boot. 2316 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2317 mUserLru.add(Integer.valueOf(0)); 2318 updateStartedUserArrayLocked(); 2319 2320 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2321 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2322 2323 mConfiguration.setToDefaults(); 2324 mConfiguration.setLocale(Locale.getDefault()); 2325 2326 mConfigurationSeq = mConfiguration.seq = 1; 2327 mProcessCpuTracker.init(); 2328 2329 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2330 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2331 mStackSupervisor = new ActivityStackSupervisor(this); 2332 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2333 2334 mProcessCpuThread = new Thread("CpuTracker") { 2335 @Override 2336 public void run() { 2337 while (true) { 2338 try { 2339 try { 2340 synchronized(this) { 2341 final long now = SystemClock.uptimeMillis(); 2342 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2343 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2344 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2345 // + ", write delay=" + nextWriteDelay); 2346 if (nextWriteDelay < nextCpuDelay) { 2347 nextCpuDelay = nextWriteDelay; 2348 } 2349 if (nextCpuDelay > 0) { 2350 mProcessCpuMutexFree.set(true); 2351 this.wait(nextCpuDelay); 2352 } 2353 } 2354 } catch (InterruptedException e) { 2355 } 2356 updateCpuStatsNow(); 2357 } catch (Exception e) { 2358 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2359 } 2360 } 2361 } 2362 }; 2363 2364 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2365 2366 Watchdog.getInstance().addMonitor(this); 2367 Watchdog.getInstance().addThread(mHandler); 2368 } 2369 2370 public void setSystemServiceManager(SystemServiceManager mgr) { 2371 mSystemServiceManager = mgr; 2372 } 2373 2374 public void setInstaller(Installer installer) { 2375 mInstaller = installer; 2376 } 2377 2378 private void start() { 2379 Process.removeAllProcessGroups(); 2380 mProcessCpuThread.start(); 2381 2382 mBatteryStatsService.publish(mContext); 2383 mAppOpsService.publish(mContext); 2384 Slog.d("AppOps", "AppOpsService published"); 2385 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2386 } 2387 2388 public void initPowerManagement() { 2389 mStackSupervisor.initPowerManagement(); 2390 mBatteryStatsService.initPowerManagement(); 2391 } 2392 2393 @Override 2394 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2395 throws RemoteException { 2396 if (code == SYSPROPS_TRANSACTION) { 2397 // We need to tell all apps about the system property change. 2398 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2399 synchronized(this) { 2400 final int NP = mProcessNames.getMap().size(); 2401 for (int ip=0; ip<NP; ip++) { 2402 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2403 final int NA = apps.size(); 2404 for (int ia=0; ia<NA; ia++) { 2405 ProcessRecord app = apps.valueAt(ia); 2406 if (app.thread != null) { 2407 procs.add(app.thread.asBinder()); 2408 } 2409 } 2410 } 2411 } 2412 2413 int N = procs.size(); 2414 for (int i=0; i<N; i++) { 2415 Parcel data2 = Parcel.obtain(); 2416 try { 2417 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2418 } catch (RemoteException e) { 2419 } 2420 data2.recycle(); 2421 } 2422 } 2423 try { 2424 return super.onTransact(code, data, reply, flags); 2425 } catch (RuntimeException e) { 2426 // The activity manager only throws security exceptions, so let's 2427 // log all others. 2428 if (!(e instanceof SecurityException)) { 2429 Slog.wtf(TAG, "Activity Manager Crash", e); 2430 } 2431 throw e; 2432 } 2433 } 2434 2435 void updateCpuStats() { 2436 final long now = SystemClock.uptimeMillis(); 2437 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2438 return; 2439 } 2440 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2441 synchronized (mProcessCpuThread) { 2442 mProcessCpuThread.notify(); 2443 } 2444 } 2445 } 2446 2447 void updateCpuStatsNow() { 2448 synchronized (mProcessCpuTracker) { 2449 mProcessCpuMutexFree.set(false); 2450 final long now = SystemClock.uptimeMillis(); 2451 boolean haveNewCpuStats = false; 2452 2453 if (MONITOR_CPU_USAGE && 2454 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2455 mLastCpuTime.set(now); 2456 haveNewCpuStats = true; 2457 mProcessCpuTracker.update(); 2458 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2459 //Slog.i(TAG, "Total CPU usage: " 2460 // + mProcessCpu.getTotalCpuPercent() + "%"); 2461 2462 // Slog the cpu usage if the property is set. 2463 if ("true".equals(SystemProperties.get("events.cpu"))) { 2464 int user = mProcessCpuTracker.getLastUserTime(); 2465 int system = mProcessCpuTracker.getLastSystemTime(); 2466 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2467 int irq = mProcessCpuTracker.getLastIrqTime(); 2468 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2469 int idle = mProcessCpuTracker.getLastIdleTime(); 2470 2471 int total = user + system + iowait + irq + softIrq + idle; 2472 if (total == 0) total = 1; 2473 2474 EventLog.writeEvent(EventLogTags.CPU, 2475 ((user+system+iowait+irq+softIrq) * 100) / total, 2476 (user * 100) / total, 2477 (system * 100) / total, 2478 (iowait * 100) / total, 2479 (irq * 100) / total, 2480 (softIrq * 100) / total); 2481 } 2482 } 2483 2484 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2485 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2486 synchronized(bstats) { 2487 synchronized(mPidsSelfLocked) { 2488 if (haveNewCpuStats) { 2489 if (mOnBattery) { 2490 int perc = bstats.startAddingCpuLocked(); 2491 int totalUTime = 0; 2492 int totalSTime = 0; 2493 final int N = mProcessCpuTracker.countStats(); 2494 for (int i=0; i<N; i++) { 2495 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2496 if (!st.working) { 2497 continue; 2498 } 2499 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2500 int otherUTime = (st.rel_utime*perc)/100; 2501 int otherSTime = (st.rel_stime*perc)/100; 2502 totalUTime += otherUTime; 2503 totalSTime += otherSTime; 2504 if (pr != null) { 2505 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2506 if (ps == null || !ps.isActive()) { 2507 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2508 pr.info.uid, pr.processName); 2509 } 2510 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2511 st.rel_stime-otherSTime); 2512 ps.addSpeedStepTimes(cpuSpeedTimes); 2513 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2514 } else { 2515 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2516 if (ps == null || !ps.isActive()) { 2517 st.batteryStats = ps = bstats.getProcessStatsLocked( 2518 bstats.mapUid(st.uid), st.name); 2519 } 2520 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2521 st.rel_stime-otherSTime); 2522 ps.addSpeedStepTimes(cpuSpeedTimes); 2523 } 2524 } 2525 bstats.finishAddingCpuLocked(perc, totalUTime, 2526 totalSTime, cpuSpeedTimes); 2527 } 2528 } 2529 } 2530 2531 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2532 mLastWriteTime = now; 2533 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2534 } 2535 } 2536 } 2537 } 2538 2539 @Override 2540 public void batteryNeedsCpuUpdate() { 2541 updateCpuStatsNow(); 2542 } 2543 2544 @Override 2545 public void batteryPowerChanged(boolean onBattery) { 2546 // When plugging in, update the CPU stats first before changing 2547 // the plug state. 2548 updateCpuStatsNow(); 2549 synchronized (this) { 2550 synchronized(mPidsSelfLocked) { 2551 mOnBattery = DEBUG_POWER ? true : onBattery; 2552 } 2553 } 2554 } 2555 2556 /** 2557 * Initialize the application bind args. These are passed to each 2558 * process when the bindApplication() IPC is sent to the process. They're 2559 * lazily setup to make sure the services are running when they're asked for. 2560 */ 2561 private HashMap<String, IBinder> getCommonServicesLocked() { 2562 if (mAppBindArgs == null) { 2563 mAppBindArgs = new HashMap<String, IBinder>(); 2564 2565 // Setup the application init args 2566 mAppBindArgs.put("package", ServiceManager.getService("package")); 2567 mAppBindArgs.put("window", ServiceManager.getService("window")); 2568 mAppBindArgs.put(Context.ALARM_SERVICE, 2569 ServiceManager.getService(Context.ALARM_SERVICE)); 2570 } 2571 return mAppBindArgs; 2572 } 2573 2574 final void setFocusedActivityLocked(ActivityRecord r) { 2575 if (mFocusedActivity != r) { 2576 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2577 mFocusedActivity = r; 2578 if (r.task != null && r.task.voiceInteractor != null) { 2579 startRunningVoiceLocked(); 2580 } else { 2581 finishRunningVoiceLocked(); 2582 } 2583 mStackSupervisor.setFocusedStack(r); 2584 if (r != null) { 2585 mWindowManager.setFocusedApp(r.appToken, true); 2586 } 2587 applyUpdateLockStateLocked(r); 2588 } 2589 } 2590 2591 final void clearFocusedActivity(ActivityRecord r) { 2592 if (mFocusedActivity == r) { 2593 mFocusedActivity = null; 2594 } 2595 } 2596 2597 @Override 2598 public void setFocusedStack(int stackId) { 2599 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2600 synchronized (ActivityManagerService.this) { 2601 ActivityStack stack = mStackSupervisor.getStack(stackId); 2602 if (stack != null) { 2603 ActivityRecord r = stack.topRunningActivityLocked(null); 2604 if (r != null) { 2605 setFocusedActivityLocked(r); 2606 } 2607 } 2608 } 2609 } 2610 2611 @Override 2612 public void notifyActivityDrawn(IBinder token) { 2613 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2614 synchronized (this) { 2615 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2616 if (r != null) { 2617 r.task.stack.notifyActivityDrawnLocked(r); 2618 } 2619 } 2620 } 2621 2622 final void applyUpdateLockStateLocked(ActivityRecord r) { 2623 // Modifications to the UpdateLock state are done on our handler, outside 2624 // the activity manager's locks. The new state is determined based on the 2625 // state *now* of the relevant activity record. The object is passed to 2626 // the handler solely for logging detail, not to be consulted/modified. 2627 final boolean nextState = r != null && r.immersive; 2628 mHandler.sendMessage( 2629 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2630 } 2631 2632 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2633 Message msg = Message.obtain(); 2634 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2635 msg.obj = r.task.askedCompatMode ? null : r; 2636 mHandler.sendMessage(msg); 2637 } 2638 2639 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2640 String what, Object obj, ProcessRecord srcApp) { 2641 app.lastActivityTime = now; 2642 2643 if (app.activities.size() > 0) { 2644 // Don't want to touch dependent processes that are hosting activities. 2645 return index; 2646 } 2647 2648 int lrui = mLruProcesses.lastIndexOf(app); 2649 if (lrui < 0) { 2650 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2651 + what + " " + obj + " from " + srcApp); 2652 return index; 2653 } 2654 2655 if (lrui >= index) { 2656 // Don't want to cause this to move dependent processes *back* in the 2657 // list as if they were less frequently used. 2658 return index; 2659 } 2660 2661 if (lrui >= mLruProcessActivityStart) { 2662 // Don't want to touch dependent processes that are hosting activities. 2663 return index; 2664 } 2665 2666 mLruProcesses.remove(lrui); 2667 if (index > 0) { 2668 index--; 2669 } 2670 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2671 + " in LRU list: " + app); 2672 mLruProcesses.add(index, app); 2673 return index; 2674 } 2675 2676 final void removeLruProcessLocked(ProcessRecord app) { 2677 int lrui = mLruProcesses.lastIndexOf(app); 2678 if (lrui >= 0) { 2679 if (!app.killed) { 2680 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2681 Process.killProcessQuiet(app.pid); 2682 Process.killProcessGroup(app.info.uid, app.pid); 2683 } 2684 if (lrui <= mLruProcessActivityStart) { 2685 mLruProcessActivityStart--; 2686 } 2687 if (lrui <= mLruProcessServiceStart) { 2688 mLruProcessServiceStart--; 2689 } 2690 mLruProcesses.remove(lrui); 2691 } 2692 } 2693 2694 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2695 ProcessRecord client) { 2696 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2697 || app.treatLikeActivity; 2698 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2699 if (!activityChange && hasActivity) { 2700 // The process has activities, so we are only allowing activity-based adjustments 2701 // to move it. It should be kept in the front of the list with other 2702 // processes that have activities, and we don't want those to change their 2703 // order except due to activity operations. 2704 return; 2705 } 2706 2707 mLruSeq++; 2708 final long now = SystemClock.uptimeMillis(); 2709 app.lastActivityTime = now; 2710 2711 // First a quick reject: if the app is already at the position we will 2712 // put it, then there is nothing to do. 2713 if (hasActivity) { 2714 final int N = mLruProcesses.size(); 2715 if (N > 0 && mLruProcesses.get(N-1) == app) { 2716 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2717 return; 2718 } 2719 } else { 2720 if (mLruProcessServiceStart > 0 2721 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2722 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2723 return; 2724 } 2725 } 2726 2727 int lrui = mLruProcesses.lastIndexOf(app); 2728 2729 if (app.persistent && lrui >= 0) { 2730 // We don't care about the position of persistent processes, as long as 2731 // they are in the list. 2732 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2733 return; 2734 } 2735 2736 /* In progress: compute new position first, so we can avoid doing work 2737 if the process is not actually going to move. Not yet working. 2738 int addIndex; 2739 int nextIndex; 2740 boolean inActivity = false, inService = false; 2741 if (hasActivity) { 2742 // Process has activities, put it at the very tipsy-top. 2743 addIndex = mLruProcesses.size(); 2744 nextIndex = mLruProcessServiceStart; 2745 inActivity = true; 2746 } else if (hasService) { 2747 // Process has services, put it at the top of the service list. 2748 addIndex = mLruProcessActivityStart; 2749 nextIndex = mLruProcessServiceStart; 2750 inActivity = true; 2751 inService = true; 2752 } else { 2753 // Process not otherwise of interest, it goes to the top of the non-service area. 2754 addIndex = mLruProcessServiceStart; 2755 if (client != null) { 2756 int clientIndex = mLruProcesses.lastIndexOf(client); 2757 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2758 + app); 2759 if (clientIndex >= 0 && addIndex > clientIndex) { 2760 addIndex = clientIndex; 2761 } 2762 } 2763 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2764 } 2765 2766 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2767 + mLruProcessActivityStart + "): " + app); 2768 */ 2769 2770 if (lrui >= 0) { 2771 if (lrui < mLruProcessActivityStart) { 2772 mLruProcessActivityStart--; 2773 } 2774 if (lrui < mLruProcessServiceStart) { 2775 mLruProcessServiceStart--; 2776 } 2777 /* 2778 if (addIndex > lrui) { 2779 addIndex--; 2780 } 2781 if (nextIndex > lrui) { 2782 nextIndex--; 2783 } 2784 */ 2785 mLruProcesses.remove(lrui); 2786 } 2787 2788 /* 2789 mLruProcesses.add(addIndex, app); 2790 if (inActivity) { 2791 mLruProcessActivityStart++; 2792 } 2793 if (inService) { 2794 mLruProcessActivityStart++; 2795 } 2796 */ 2797 2798 int nextIndex; 2799 if (hasActivity) { 2800 final int N = mLruProcesses.size(); 2801 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2802 // Process doesn't have activities, but has clients with 2803 // activities... move it up, but one below the top (the top 2804 // should always have a real activity). 2805 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2806 mLruProcesses.add(N-1, app); 2807 // To keep it from spamming the LRU list (by making a bunch of clients), 2808 // we will push down any other entries owned by the app. 2809 final int uid = app.info.uid; 2810 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2811 ProcessRecord subProc = mLruProcesses.get(i); 2812 if (subProc.info.uid == uid) { 2813 // We want to push this one down the list. If the process after 2814 // it is for the same uid, however, don't do so, because we don't 2815 // want them internally to be re-ordered. 2816 if (mLruProcesses.get(i-1).info.uid != uid) { 2817 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2818 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2819 ProcessRecord tmp = mLruProcesses.get(i); 2820 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2821 mLruProcesses.set(i-1, tmp); 2822 i--; 2823 } 2824 } else { 2825 // A gap, we can stop here. 2826 break; 2827 } 2828 } 2829 } else { 2830 // Process has activities, put it at the very tipsy-top. 2831 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2832 mLruProcesses.add(app); 2833 } 2834 nextIndex = mLruProcessServiceStart; 2835 } else if (hasService) { 2836 // Process has services, put it at the top of the service list. 2837 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2838 mLruProcesses.add(mLruProcessActivityStart, app); 2839 nextIndex = mLruProcessServiceStart; 2840 mLruProcessActivityStart++; 2841 } else { 2842 // Process not otherwise of interest, it goes to the top of the non-service area. 2843 int index = mLruProcessServiceStart; 2844 if (client != null) { 2845 // If there is a client, don't allow the process to be moved up higher 2846 // in the list than that client. 2847 int clientIndex = mLruProcesses.lastIndexOf(client); 2848 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2849 + " when updating " + app); 2850 if (clientIndex <= lrui) { 2851 // Don't allow the client index restriction to push it down farther in the 2852 // list than it already is. 2853 clientIndex = lrui; 2854 } 2855 if (clientIndex >= 0 && index > clientIndex) { 2856 index = clientIndex; 2857 } 2858 } 2859 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2860 mLruProcesses.add(index, app); 2861 nextIndex = index-1; 2862 mLruProcessActivityStart++; 2863 mLruProcessServiceStart++; 2864 } 2865 2866 // If the app is currently using a content provider or service, 2867 // bump those processes as well. 2868 for (int j=app.connections.size()-1; j>=0; j--) { 2869 ConnectionRecord cr = app.connections.valueAt(j); 2870 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2871 && cr.binding.service.app != null 2872 && cr.binding.service.app.lruSeq != mLruSeq 2873 && !cr.binding.service.app.persistent) { 2874 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2875 "service connection", cr, app); 2876 } 2877 } 2878 for (int j=app.conProviders.size()-1; j>=0; j--) { 2879 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2880 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2881 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2882 "provider reference", cpr, app); 2883 } 2884 } 2885 } 2886 2887 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2888 if (uid == Process.SYSTEM_UID) { 2889 // The system gets to run in any process. If there are multiple 2890 // processes with the same uid, just pick the first (this 2891 // should never happen). 2892 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2893 if (procs == null) return null; 2894 final int N = procs.size(); 2895 for (int i = 0; i < N; i++) { 2896 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2897 } 2898 } 2899 ProcessRecord proc = mProcessNames.get(processName, uid); 2900 if (false && proc != null && !keepIfLarge 2901 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2902 && proc.lastCachedPss >= 4000) { 2903 // Turn this condition on to cause killing to happen regularly, for testing. 2904 if (proc.baseProcessTracker != null) { 2905 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2906 } 2907 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2908 } else if (proc != null && !keepIfLarge 2909 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2910 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2911 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2912 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2913 if (proc.baseProcessTracker != null) { 2914 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2915 } 2916 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2917 } 2918 } 2919 return proc; 2920 } 2921 2922 void ensurePackageDexOpt(String packageName) { 2923 IPackageManager pm = AppGlobals.getPackageManager(); 2924 try { 2925 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2926 mDidDexOpt = true; 2927 } 2928 } catch (RemoteException e) { 2929 } 2930 } 2931 2932 boolean isNextTransitionForward() { 2933 int transit = mWindowManager.getPendingAppTransition(); 2934 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2935 || transit == AppTransition.TRANSIT_TASK_OPEN 2936 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2937 } 2938 2939 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2940 String processName, String abiOverride, int uid, Runnable crashHandler) { 2941 synchronized(this) { 2942 ApplicationInfo info = new ApplicationInfo(); 2943 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2944 // For isolated processes, the former contains the parent's uid and the latter the 2945 // actual uid of the isolated process. 2946 // In the special case introduced by this method (which is, starting an isolated 2947 // process directly from the SystemServer without an actual parent app process) the 2948 // closest thing to a parent's uid is SYSTEM_UID. 2949 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2950 // the |isolated| logic in the ProcessRecord constructor. 2951 info.uid = Process.SYSTEM_UID; 2952 info.processName = processName; 2953 info.className = entryPoint; 2954 info.packageName = "android"; 2955 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2956 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2957 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2958 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2959 crashHandler); 2960 return proc != null ? proc.pid : 0; 2961 } 2962 } 2963 2964 final ProcessRecord startProcessLocked(String processName, 2965 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2966 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2967 boolean isolated, boolean keepIfLarge) { 2968 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2969 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2970 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2971 null /* crashHandler */); 2972 } 2973 2974 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2975 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2976 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2977 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2978 long startTime = SystemClock.elapsedRealtime(); 2979 ProcessRecord app; 2980 if (!isolated) { 2981 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2982 checkTime(startTime, "startProcess: after getProcessRecord"); 2983 } else { 2984 // If this is an isolated process, it can't re-use an existing process. 2985 app = null; 2986 } 2987 // We don't have to do anything more if: 2988 // (1) There is an existing application record; and 2989 // (2) The caller doesn't think it is dead, OR there is no thread 2990 // object attached to it so we know it couldn't have crashed; and 2991 // (3) There is a pid assigned to it, so it is either starting or 2992 // already running. 2993 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2994 + " app=" + app + " knownToBeDead=" + knownToBeDead 2995 + " thread=" + (app != null ? app.thread : null) 2996 + " pid=" + (app != null ? app.pid : -1)); 2997 if (app != null && app.pid > 0) { 2998 if (!knownToBeDead || app.thread == null) { 2999 // We already have the app running, or are waiting for it to 3000 // come up (we have a pid but not yet its thread), so keep it. 3001 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 3002 // If this is a new package in the process, add the package to the list 3003 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3004 checkTime(startTime, "startProcess: done, added package to proc"); 3005 return app; 3006 } 3007 3008 // An application record is attached to a previous process, 3009 // clean it up now. 3010 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 3011 checkTime(startTime, "startProcess: bad proc running, killing"); 3012 Process.killProcessGroup(app.info.uid, app.pid); 3013 handleAppDiedLocked(app, true, true); 3014 checkTime(startTime, "startProcess: done killing old proc"); 3015 } 3016 3017 String hostingNameStr = hostingName != null 3018 ? hostingName.flattenToShortString() : null; 3019 3020 if (!isolated) { 3021 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 3022 // If we are in the background, then check to see if this process 3023 // is bad. If so, we will just silently fail. 3024 if (mBadProcesses.get(info.processName, info.uid) != null) { 3025 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3026 + "/" + info.processName); 3027 return null; 3028 } 3029 } else { 3030 // When the user is explicitly starting a process, then clear its 3031 // crash count so that we won't make it bad until they see at 3032 // least one crash dialog again, and make the process good again 3033 // if it had been bad. 3034 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3035 + "/" + info.processName); 3036 mProcessCrashTimes.remove(info.processName, info.uid); 3037 if (mBadProcesses.get(info.processName, info.uid) != null) { 3038 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3039 UserHandle.getUserId(info.uid), info.uid, 3040 info.processName); 3041 mBadProcesses.remove(info.processName, info.uid); 3042 if (app != null) { 3043 app.bad = false; 3044 } 3045 } 3046 } 3047 } 3048 3049 if (app == null) { 3050 checkTime(startTime, "startProcess: creating new process record"); 3051 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3052 if (app == null) { 3053 Slog.w(TAG, "Failed making new process record for " 3054 + processName + "/" + info.uid + " isolated=" + isolated); 3055 return null; 3056 } 3057 app.crashHandler = crashHandler; 3058 mProcessNames.put(processName, app.uid, app); 3059 if (isolated) { 3060 mIsolatedProcesses.put(app.uid, app); 3061 } 3062 checkTime(startTime, "startProcess: done creating new process record"); 3063 } else { 3064 // If this is a new package in the process, add the package to the list 3065 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3066 checkTime(startTime, "startProcess: added package to existing proc"); 3067 } 3068 3069 // If the system is not ready yet, then hold off on starting this 3070 // process until it is. 3071 if (!mProcessesReady 3072 && !isAllowedWhileBooting(info) 3073 && !allowWhileBooting) { 3074 if (!mProcessesOnHold.contains(app)) { 3075 mProcessesOnHold.add(app); 3076 } 3077 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3078 checkTime(startTime, "startProcess: returning with proc on hold"); 3079 return app; 3080 } 3081 3082 checkTime(startTime, "startProcess: stepping in to startProcess"); 3083 startProcessLocked( 3084 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3085 checkTime(startTime, "startProcess: done starting proc!"); 3086 return (app.pid != 0) ? app : null; 3087 } 3088 3089 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3090 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3091 } 3092 3093 private final void startProcessLocked(ProcessRecord app, 3094 String hostingType, String hostingNameStr) { 3095 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3096 null /* entryPoint */, null /* entryPointArgs */); 3097 } 3098 3099 private final void startProcessLocked(ProcessRecord app, String hostingType, 3100 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3101 long startTime = SystemClock.elapsedRealtime(); 3102 if (app.pid > 0 && app.pid != MY_PID) { 3103 checkTime(startTime, "startProcess: removing from pids map"); 3104 synchronized (mPidsSelfLocked) { 3105 mPidsSelfLocked.remove(app.pid); 3106 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3107 } 3108 checkTime(startTime, "startProcess: done removing from pids map"); 3109 app.setPid(0); 3110 } 3111 3112 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3113 "startProcessLocked removing on hold: " + app); 3114 mProcessesOnHold.remove(app); 3115 3116 checkTime(startTime, "startProcess: starting to update cpu stats"); 3117 updateCpuStats(); 3118 checkTime(startTime, "startProcess: done updating cpu stats"); 3119 3120 try { 3121 int uid = app.uid; 3122 3123 int[] gids = null; 3124 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3125 if (!app.isolated) { 3126 int[] permGids = null; 3127 try { 3128 checkTime(startTime, "startProcess: getting gids from package manager"); 3129 final PackageManager pm = mContext.getPackageManager(); 3130 permGids = pm.getPackageGids(app.info.packageName); 3131 3132 if (Environment.isExternalStorageEmulated()) { 3133 checkTime(startTime, "startProcess: checking external storage perm"); 3134 if (pm.checkPermission( 3135 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3136 app.info.packageName) == PERMISSION_GRANTED) { 3137 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3138 } else { 3139 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3140 } 3141 } 3142 } catch (PackageManager.NameNotFoundException e) { 3143 Slog.w(TAG, "Unable to retrieve gids", e); 3144 } 3145 3146 /* 3147 * Add shared application and profile GIDs so applications can share some 3148 * resources like shared libraries and access user-wide resources 3149 */ 3150 if (permGids == null) { 3151 gids = new int[2]; 3152 } else { 3153 gids = new int[permGids.length + 2]; 3154 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3155 } 3156 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3157 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3158 } 3159 checkTime(startTime, "startProcess: building args"); 3160 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3161 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3162 && mTopComponent != null 3163 && app.processName.equals(mTopComponent.getPackageName())) { 3164 uid = 0; 3165 } 3166 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3167 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3168 uid = 0; 3169 } 3170 } 3171 int debugFlags = 0; 3172 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3173 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3174 // Also turn on CheckJNI for debuggable apps. It's quite 3175 // awkward to turn on otherwise. 3176 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3177 } 3178 // Run the app in safe mode if its manifest requests so or the 3179 // system is booted in safe mode. 3180 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3181 mSafeMode == true) { 3182 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3183 } 3184 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3185 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3186 } 3187 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3188 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3189 } 3190 if ("1".equals(SystemProperties.get("debug.assert"))) { 3191 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3192 } 3193 3194 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3195 if (requiredAbi == null) { 3196 requiredAbi = Build.SUPPORTED_ABIS[0]; 3197 } 3198 3199 String instructionSet = null; 3200 if (app.info.primaryCpuAbi != null) { 3201 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3202 } 3203 3204 // Start the process. It will either succeed and return a result containing 3205 // the PID of the new process, or else throw a RuntimeException. 3206 boolean isActivityProcess = (entryPoint == null); 3207 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3208 checkTime(startTime, "startProcess: asking zygote to start proc"); 3209 Process.ProcessStartResult startResult = Process.start(entryPoint, 3210 app.processName, uid, uid, gids, debugFlags, mountExternal, 3211 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3212 app.info.dataDir, entryPointArgs); 3213 checkTime(startTime, "startProcess: returned from zygote!"); 3214 3215 if (app.isolated) { 3216 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3217 } 3218 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3219 checkTime(startTime, "startProcess: done updating battery stats"); 3220 3221 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3222 UserHandle.getUserId(uid), startResult.pid, uid, 3223 app.processName, hostingType, 3224 hostingNameStr != null ? hostingNameStr : ""); 3225 3226 if (app.persistent) { 3227 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3228 } 3229 3230 checkTime(startTime, "startProcess: building log message"); 3231 StringBuilder buf = mStringBuilder; 3232 buf.setLength(0); 3233 buf.append("Start proc "); 3234 buf.append(app.processName); 3235 if (!isActivityProcess) { 3236 buf.append(" ["); 3237 buf.append(entryPoint); 3238 buf.append("]"); 3239 } 3240 buf.append(" for "); 3241 buf.append(hostingType); 3242 if (hostingNameStr != null) { 3243 buf.append(" "); 3244 buf.append(hostingNameStr); 3245 } 3246 buf.append(": pid="); 3247 buf.append(startResult.pid); 3248 buf.append(" uid="); 3249 buf.append(uid); 3250 buf.append(" gids={"); 3251 if (gids != null) { 3252 for (int gi=0; gi<gids.length; gi++) { 3253 if (gi != 0) buf.append(", "); 3254 buf.append(gids[gi]); 3255 3256 } 3257 } 3258 buf.append("}"); 3259 if (requiredAbi != null) { 3260 buf.append(" abi="); 3261 buf.append(requiredAbi); 3262 } 3263 Slog.i(TAG, buf.toString()); 3264 app.setPid(startResult.pid); 3265 app.usingWrapper = startResult.usingWrapper; 3266 app.removed = false; 3267 app.killed = false; 3268 app.killedByAm = false; 3269 checkTime(startTime, "startProcess: starting to update pids map"); 3270 synchronized (mPidsSelfLocked) { 3271 this.mPidsSelfLocked.put(startResult.pid, app); 3272 if (isActivityProcess) { 3273 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3274 msg.obj = app; 3275 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3276 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3277 } 3278 } 3279 checkTime(startTime, "startProcess: done updating pids map"); 3280 } catch (RuntimeException e) { 3281 // XXX do better error recovery. 3282 app.setPid(0); 3283 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3284 if (app.isolated) { 3285 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3286 } 3287 Slog.e(TAG, "Failure starting process " + app.processName, e); 3288 } 3289 } 3290 3291 void updateUsageStats(ActivityRecord component, boolean resumed) { 3292 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3293 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3294 if (resumed) { 3295 if (mUsageStatsService != null) { 3296 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3297 UsageEvents.Event.MOVE_TO_FOREGROUND); 3298 } 3299 synchronized (stats) { 3300 stats.noteActivityResumedLocked(component.app.uid); 3301 } 3302 } else { 3303 if (mUsageStatsService != null) { 3304 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3305 UsageEvents.Event.MOVE_TO_BACKGROUND); 3306 } 3307 synchronized (stats) { 3308 stats.noteActivityPausedLocked(component.app.uid); 3309 } 3310 } 3311 } 3312 3313 Intent getHomeIntent() { 3314 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3315 intent.setComponent(mTopComponent); 3316 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3317 intent.addCategory(Intent.CATEGORY_HOME); 3318 } 3319 return intent; 3320 } 3321 3322 boolean startHomeActivityLocked(int userId) { 3323 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3324 && mTopAction == null) { 3325 // We are running in factory test mode, but unable to find 3326 // the factory test app, so just sit around displaying the 3327 // error message and don't try to start anything. 3328 return false; 3329 } 3330 Intent intent = getHomeIntent(); 3331 ActivityInfo aInfo = 3332 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3333 if (aInfo != null) { 3334 intent.setComponent(new ComponentName( 3335 aInfo.applicationInfo.packageName, aInfo.name)); 3336 // Don't do this if the home app is currently being 3337 // instrumented. 3338 aInfo = new ActivityInfo(aInfo); 3339 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3340 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3341 aInfo.applicationInfo.uid, true); 3342 if (app == null || app.instrumentationClass == null) { 3343 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3344 mStackSupervisor.startHomeActivity(intent, aInfo); 3345 } 3346 } 3347 3348 return true; 3349 } 3350 3351 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3352 ActivityInfo ai = null; 3353 ComponentName comp = intent.getComponent(); 3354 try { 3355 if (comp != null) { 3356 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3357 } else { 3358 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3359 intent, 3360 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3361 flags, userId); 3362 3363 if (info != null) { 3364 ai = info.activityInfo; 3365 } 3366 } 3367 } catch (RemoteException e) { 3368 // ignore 3369 } 3370 3371 return ai; 3372 } 3373 3374 /** 3375 * Starts the "new version setup screen" if appropriate. 3376 */ 3377 void startSetupActivityLocked() { 3378 // Only do this once per boot. 3379 if (mCheckedForSetup) { 3380 return; 3381 } 3382 3383 // We will show this screen if the current one is a different 3384 // version than the last one shown, and we are not running in 3385 // low-level factory test mode. 3386 final ContentResolver resolver = mContext.getContentResolver(); 3387 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3388 Settings.Global.getInt(resolver, 3389 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3390 mCheckedForSetup = true; 3391 3392 // See if we should be showing the platform update setup UI. 3393 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3394 List<ResolveInfo> ris = mContext.getPackageManager() 3395 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3396 3397 // We don't allow third party apps to replace this. 3398 ResolveInfo ri = null; 3399 for (int i=0; ris != null && i<ris.size(); i++) { 3400 if ((ris.get(i).activityInfo.applicationInfo.flags 3401 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3402 ri = ris.get(i); 3403 break; 3404 } 3405 } 3406 3407 if (ri != null) { 3408 String vers = ri.activityInfo.metaData != null 3409 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3410 : null; 3411 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3412 vers = ri.activityInfo.applicationInfo.metaData.getString( 3413 Intent.METADATA_SETUP_VERSION); 3414 } 3415 String lastVers = Settings.Secure.getString( 3416 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3417 if (vers != null && !vers.equals(lastVers)) { 3418 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3419 intent.setComponent(new ComponentName( 3420 ri.activityInfo.packageName, ri.activityInfo.name)); 3421 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3422 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3423 null); 3424 } 3425 } 3426 } 3427 } 3428 3429 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3430 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3431 } 3432 3433 void enforceNotIsolatedCaller(String caller) { 3434 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3435 throw new SecurityException("Isolated process not allowed to call " + caller); 3436 } 3437 } 3438 3439 void enforceShellRestriction(String restriction, int userHandle) { 3440 if (Binder.getCallingUid() == Process.SHELL_UID) { 3441 if (userHandle < 0 3442 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3443 throw new SecurityException("Shell does not have permission to access user " 3444 + userHandle); 3445 } 3446 } 3447 } 3448 3449 @Override 3450 public int getFrontActivityScreenCompatMode() { 3451 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3452 synchronized (this) { 3453 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3454 } 3455 } 3456 3457 @Override 3458 public void setFrontActivityScreenCompatMode(int mode) { 3459 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3460 "setFrontActivityScreenCompatMode"); 3461 synchronized (this) { 3462 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3463 } 3464 } 3465 3466 @Override 3467 public int getPackageScreenCompatMode(String packageName) { 3468 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3469 synchronized (this) { 3470 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3471 } 3472 } 3473 3474 @Override 3475 public void setPackageScreenCompatMode(String packageName, int mode) { 3476 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3477 "setPackageScreenCompatMode"); 3478 synchronized (this) { 3479 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3480 } 3481 } 3482 3483 @Override 3484 public boolean getPackageAskScreenCompat(String packageName) { 3485 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3486 synchronized (this) { 3487 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3488 } 3489 } 3490 3491 @Override 3492 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3493 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3494 "setPackageAskScreenCompat"); 3495 synchronized (this) { 3496 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3497 } 3498 } 3499 3500 private void dispatchProcessesChanged() { 3501 int N; 3502 synchronized (this) { 3503 N = mPendingProcessChanges.size(); 3504 if (mActiveProcessChanges.length < N) { 3505 mActiveProcessChanges = new ProcessChangeItem[N]; 3506 } 3507 mPendingProcessChanges.toArray(mActiveProcessChanges); 3508 mAvailProcessChanges.addAll(mPendingProcessChanges); 3509 mPendingProcessChanges.clear(); 3510 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3511 } 3512 3513 int i = mProcessObservers.beginBroadcast(); 3514 while (i > 0) { 3515 i--; 3516 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3517 if (observer != null) { 3518 try { 3519 for (int j=0; j<N; j++) { 3520 ProcessChangeItem item = mActiveProcessChanges[j]; 3521 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3522 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3523 + item.pid + " uid=" + item.uid + ": " 3524 + item.foregroundActivities); 3525 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3526 item.foregroundActivities); 3527 } 3528 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3529 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3530 + item.pid + " uid=" + item.uid + ": " + item.processState); 3531 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3532 } 3533 } 3534 } catch (RemoteException e) { 3535 } 3536 } 3537 } 3538 mProcessObservers.finishBroadcast(); 3539 } 3540 3541 private void dispatchProcessDied(int pid, int uid) { 3542 int i = mProcessObservers.beginBroadcast(); 3543 while (i > 0) { 3544 i--; 3545 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3546 if (observer != null) { 3547 try { 3548 observer.onProcessDied(pid, uid); 3549 } catch (RemoteException e) { 3550 } 3551 } 3552 } 3553 mProcessObservers.finishBroadcast(); 3554 } 3555 3556 @Override 3557 public final int startActivity(IApplicationThread caller, String callingPackage, 3558 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3559 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3560 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3561 resultWho, requestCode, startFlags, profilerInfo, options, 3562 UserHandle.getCallingUserId()); 3563 } 3564 3565 @Override 3566 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3567 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3568 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3569 enforceNotIsolatedCaller("startActivity"); 3570 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3571 false, ALLOW_FULL_ONLY, "startActivity", null); 3572 // TODO: Switch to user app stacks here. 3573 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3574 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3575 profilerInfo, null, null, options, userId, null, null); 3576 } 3577 3578 @Override 3579 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3580 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3581 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3582 3583 // This is very dangerous -- it allows you to perform a start activity (including 3584 // permission grants) as any app that may launch one of your own activities. So 3585 // we will only allow this to be done from activities that are part of the core framework, 3586 // and then only when they are running as the system. 3587 final ActivityRecord sourceRecord; 3588 final int targetUid; 3589 final String targetPackage; 3590 synchronized (this) { 3591 if (resultTo == null) { 3592 throw new SecurityException("Must be called from an activity"); 3593 } 3594 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3595 if (sourceRecord == null) { 3596 throw new SecurityException("Called with bad activity token: " + resultTo); 3597 } 3598 if (!sourceRecord.info.packageName.equals("android")) { 3599 throw new SecurityException( 3600 "Must be called from an activity that is declared in the android package"); 3601 } 3602 if (sourceRecord.app == null) { 3603 throw new SecurityException("Called without a process attached to activity"); 3604 } 3605 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3606 // This is still okay, as long as this activity is running under the 3607 // uid of the original calling activity. 3608 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3609 throw new SecurityException( 3610 "Calling activity in uid " + sourceRecord.app.uid 3611 + " must be system uid or original calling uid " 3612 + sourceRecord.launchedFromUid); 3613 } 3614 } 3615 targetUid = sourceRecord.launchedFromUid; 3616 targetPackage = sourceRecord.launchedFromPackage; 3617 } 3618 3619 if (userId == UserHandle.USER_NULL) { 3620 userId = UserHandle.getUserId(sourceRecord.app.uid); 3621 } 3622 3623 // TODO: Switch to user app stacks here. 3624 try { 3625 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3626 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3627 null, null, options, userId, null, null); 3628 return ret; 3629 } catch (SecurityException e) { 3630 // XXX need to figure out how to propagate to original app. 3631 // A SecurityException here is generally actually a fault of the original 3632 // calling activity (such as a fairly granting permissions), so propagate it 3633 // back to them. 3634 /* 3635 StringBuilder msg = new StringBuilder(); 3636 msg.append("While launching"); 3637 msg.append(intent.toString()); 3638 msg.append(": "); 3639 msg.append(e.getMessage()); 3640 */ 3641 throw e; 3642 } 3643 } 3644 3645 @Override 3646 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3647 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3648 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3649 enforceNotIsolatedCaller("startActivityAndWait"); 3650 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3651 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3652 WaitResult res = new WaitResult(); 3653 // TODO: Switch to user app stacks here. 3654 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3655 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3656 options, userId, null, null); 3657 return res; 3658 } 3659 3660 @Override 3661 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3662 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3663 int startFlags, Configuration config, Bundle options, int userId) { 3664 enforceNotIsolatedCaller("startActivityWithConfig"); 3665 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3666 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3667 // TODO: Switch to user app stacks here. 3668 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3669 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3670 null, null, config, options, userId, null, null); 3671 return ret; 3672 } 3673 3674 @Override 3675 public int startActivityIntentSender(IApplicationThread caller, 3676 IntentSender intent, Intent fillInIntent, String resolvedType, 3677 IBinder resultTo, String resultWho, int requestCode, 3678 int flagsMask, int flagsValues, Bundle options) { 3679 enforceNotIsolatedCaller("startActivityIntentSender"); 3680 // Refuse possible leaked file descriptors 3681 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3682 throw new IllegalArgumentException("File descriptors passed in Intent"); 3683 } 3684 3685 IIntentSender sender = intent.getTarget(); 3686 if (!(sender instanceof PendingIntentRecord)) { 3687 throw new IllegalArgumentException("Bad PendingIntent object"); 3688 } 3689 3690 PendingIntentRecord pir = (PendingIntentRecord)sender; 3691 3692 synchronized (this) { 3693 // If this is coming from the currently resumed activity, it is 3694 // effectively saying that app switches are allowed at this point. 3695 final ActivityStack stack = getFocusedStack(); 3696 if (stack.mResumedActivity != null && 3697 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3698 mAppSwitchesAllowedTime = 0; 3699 } 3700 } 3701 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3702 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3703 return ret; 3704 } 3705 3706 @Override 3707 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3708 Intent intent, String resolvedType, IVoiceInteractionSession session, 3709 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3710 Bundle options, int userId) { 3711 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3712 != PackageManager.PERMISSION_GRANTED) { 3713 String msg = "Permission Denial: startVoiceActivity() from pid=" 3714 + Binder.getCallingPid() 3715 + ", uid=" + Binder.getCallingUid() 3716 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3717 Slog.w(TAG, msg); 3718 throw new SecurityException(msg); 3719 } 3720 if (session == null || interactor == null) { 3721 throw new NullPointerException("null session or interactor"); 3722 } 3723 userId = handleIncomingUser(callingPid, callingUid, userId, 3724 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3725 // TODO: Switch to user app stacks here. 3726 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3727 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3728 null, options, userId, null, null); 3729 } 3730 3731 @Override 3732 public boolean startNextMatchingActivity(IBinder callingActivity, 3733 Intent intent, Bundle options) { 3734 // Refuse possible leaked file descriptors 3735 if (intent != null && intent.hasFileDescriptors() == true) { 3736 throw new IllegalArgumentException("File descriptors passed in Intent"); 3737 } 3738 3739 synchronized (this) { 3740 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3741 if (r == null) { 3742 ActivityOptions.abort(options); 3743 return false; 3744 } 3745 if (r.app == null || r.app.thread == null) { 3746 // The caller is not running... d'oh! 3747 ActivityOptions.abort(options); 3748 return false; 3749 } 3750 intent = new Intent(intent); 3751 // The caller is not allowed to change the data. 3752 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3753 // And we are resetting to find the next component... 3754 intent.setComponent(null); 3755 3756 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3757 3758 ActivityInfo aInfo = null; 3759 try { 3760 List<ResolveInfo> resolves = 3761 AppGlobals.getPackageManager().queryIntentActivities( 3762 intent, r.resolvedType, 3763 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3764 UserHandle.getCallingUserId()); 3765 3766 // Look for the original activity in the list... 3767 final int N = resolves != null ? resolves.size() : 0; 3768 for (int i=0; i<N; i++) { 3769 ResolveInfo rInfo = resolves.get(i); 3770 if (rInfo.activityInfo.packageName.equals(r.packageName) 3771 && rInfo.activityInfo.name.equals(r.info.name)) { 3772 // We found the current one... the next matching is 3773 // after it. 3774 i++; 3775 if (i<N) { 3776 aInfo = resolves.get(i).activityInfo; 3777 } 3778 if (debug) { 3779 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3780 + "/" + r.info.name); 3781 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3782 + "/" + aInfo.name); 3783 } 3784 break; 3785 } 3786 } 3787 } catch (RemoteException e) { 3788 } 3789 3790 if (aInfo == null) { 3791 // Nobody who is next! 3792 ActivityOptions.abort(options); 3793 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3794 return false; 3795 } 3796 3797 intent.setComponent(new ComponentName( 3798 aInfo.applicationInfo.packageName, aInfo.name)); 3799 intent.setFlags(intent.getFlags()&~( 3800 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3801 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3802 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3803 Intent.FLAG_ACTIVITY_NEW_TASK)); 3804 3805 // Okay now we need to start the new activity, replacing the 3806 // currently running activity. This is a little tricky because 3807 // we want to start the new one as if the current one is finished, 3808 // but not finish the current one first so that there is no flicker. 3809 // And thus... 3810 final boolean wasFinishing = r.finishing; 3811 r.finishing = true; 3812 3813 // Propagate reply information over to the new activity. 3814 final ActivityRecord resultTo = r.resultTo; 3815 final String resultWho = r.resultWho; 3816 final int requestCode = r.requestCode; 3817 r.resultTo = null; 3818 if (resultTo != null) { 3819 resultTo.removeResultsLocked(r, resultWho, requestCode); 3820 } 3821 3822 final long origId = Binder.clearCallingIdentity(); 3823 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3824 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3825 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3826 -1, r.launchedFromUid, 0, options, false, null, null, null); 3827 Binder.restoreCallingIdentity(origId); 3828 3829 r.finishing = wasFinishing; 3830 if (res != ActivityManager.START_SUCCESS) { 3831 return false; 3832 } 3833 return true; 3834 } 3835 } 3836 3837 @Override 3838 public final int startActivityFromRecents(int taskId, Bundle options) { 3839 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3840 String msg = "Permission Denial: startActivityFromRecents called without " + 3841 START_TASKS_FROM_RECENTS; 3842 Slog.w(TAG, msg); 3843 throw new SecurityException(msg); 3844 } 3845 return startActivityFromRecentsInner(taskId, options); 3846 } 3847 3848 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3849 final TaskRecord task; 3850 final int callingUid; 3851 final String callingPackage; 3852 final Intent intent; 3853 final int userId; 3854 synchronized (this) { 3855 task = recentTaskForIdLocked(taskId); 3856 if (task == null) { 3857 throw new IllegalArgumentException("Task " + taskId + " not found."); 3858 } 3859 callingUid = task.mCallingUid; 3860 callingPackage = task.mCallingPackage; 3861 intent = task.intent; 3862 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3863 userId = task.userId; 3864 } 3865 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3866 options, userId, null, task); 3867 } 3868 3869 final int startActivityInPackage(int uid, String callingPackage, 3870 Intent intent, String resolvedType, IBinder resultTo, 3871 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3872 IActivityContainer container, TaskRecord inTask) { 3873 3874 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3875 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3876 3877 // TODO: Switch to user app stacks here. 3878 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3879 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3880 null, null, null, options, userId, container, inTask); 3881 return ret; 3882 } 3883 3884 @Override 3885 public final int startActivities(IApplicationThread caller, String callingPackage, 3886 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3887 int userId) { 3888 enforceNotIsolatedCaller("startActivities"); 3889 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3890 false, ALLOW_FULL_ONLY, "startActivity", null); 3891 // TODO: Switch to user app stacks here. 3892 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3893 resolvedTypes, resultTo, options, userId); 3894 return ret; 3895 } 3896 3897 final int startActivitiesInPackage(int uid, String callingPackage, 3898 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3899 Bundle options, int userId) { 3900 3901 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3902 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3903 // TODO: Switch to user app stacks here. 3904 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3905 resultTo, options, userId); 3906 return ret; 3907 } 3908 3909 //explicitly remove thd old information in mRecentTasks when removing existing user. 3910 private void removeRecentTasksForUserLocked(int userId) { 3911 if(userId <= 0) { 3912 Slog.i(TAG, "Can't remove recent task on user " + userId); 3913 return; 3914 } 3915 3916 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3917 TaskRecord tr = mRecentTasks.get(i); 3918 if (tr.userId == userId) { 3919 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3920 + " when finishing user" + userId); 3921 mRecentTasks.remove(i); 3922 tr.removedFromRecents(mTaskPersister); 3923 } 3924 } 3925 3926 // Remove tasks from persistent storage. 3927 mTaskPersister.wakeup(null, true); 3928 } 3929 3930 // Sort by taskId 3931 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3932 @Override 3933 public int compare(TaskRecord lhs, TaskRecord rhs) { 3934 return rhs.taskId - lhs.taskId; 3935 } 3936 }; 3937 3938 // Extract the affiliates of the chain containing mRecentTasks[start]. 3939 private int processNextAffiliateChain(int start) { 3940 final TaskRecord startTask = mRecentTasks.get(start); 3941 final int affiliateId = startTask.mAffiliatedTaskId; 3942 3943 // Quick identification of isolated tasks. I.e. those not launched behind. 3944 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3945 startTask.mNextAffiliate == null) { 3946 // There is still a slim chance that there are other tasks that point to this task 3947 // and that the chain is so messed up that this task no longer points to them but 3948 // the gain of this optimization outweighs the risk. 3949 startTask.inRecents = true; 3950 return start + 1; 3951 } 3952 3953 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3954 mTmpRecents.clear(); 3955 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3956 final TaskRecord task = mRecentTasks.get(i); 3957 if (task.mAffiliatedTaskId == affiliateId) { 3958 mRecentTasks.remove(i); 3959 mTmpRecents.add(task); 3960 } 3961 } 3962 3963 // Sort them all by taskId. That is the order they were create in and that order will 3964 // always be correct. 3965 Collections.sort(mTmpRecents, mTaskRecordComparator); 3966 3967 // Go through and fix up the linked list. 3968 // The first one is the end of the chain and has no next. 3969 final TaskRecord first = mTmpRecents.get(0); 3970 first.inRecents = true; 3971 if (first.mNextAffiliate != null) { 3972 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3973 first.setNextAffiliate(null); 3974 mTaskPersister.wakeup(first, false); 3975 } 3976 // Everything in the middle is doubly linked from next to prev. 3977 final int tmpSize = mTmpRecents.size(); 3978 for (int i = 0; i < tmpSize - 1; ++i) { 3979 final TaskRecord next = mTmpRecents.get(i); 3980 final TaskRecord prev = mTmpRecents.get(i + 1); 3981 if (next.mPrevAffiliate != prev) { 3982 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3983 " setting prev=" + prev); 3984 next.setPrevAffiliate(prev); 3985 mTaskPersister.wakeup(next, false); 3986 } 3987 if (prev.mNextAffiliate != next) { 3988 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3989 " setting next=" + next); 3990 prev.setNextAffiliate(next); 3991 mTaskPersister.wakeup(prev, false); 3992 } 3993 prev.inRecents = true; 3994 } 3995 // The last one is the beginning of the list and has no prev. 3996 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3997 if (last.mPrevAffiliate != null) { 3998 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3999 last.setPrevAffiliate(null); 4000 mTaskPersister.wakeup(last, false); 4001 } 4002 4003 // Insert the group back into mRecentTasks at start. 4004 mRecentTasks.addAll(start, mTmpRecents); 4005 4006 // Let the caller know where we left off. 4007 return start + tmpSize; 4008 } 4009 4010 /** 4011 * Update the recent tasks lists: make sure tasks should still be here (their 4012 * applications / activities still exist), update their availability, fixup ordering 4013 * of affiliations. 4014 */ 4015 void cleanupRecentTasksLocked(int userId) { 4016 if (mRecentTasks == null) { 4017 // Happens when called from the packagemanager broadcast before boot. 4018 return; 4019 } 4020 4021 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 4022 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 4023 final IPackageManager pm = AppGlobals.getPackageManager(); 4024 final ActivityInfo dummyAct = new ActivityInfo(); 4025 final ApplicationInfo dummyApp = new ApplicationInfo(); 4026 4027 int N = mRecentTasks.size(); 4028 4029 int[] users = userId == UserHandle.USER_ALL 4030 ? getUsersLocked() : new int[] { userId }; 4031 for (int user : users) { 4032 for (int i = 0; i < N; i++) { 4033 TaskRecord task = mRecentTasks.get(i); 4034 if (task.userId != user) { 4035 // Only look at tasks for the user ID of interest. 4036 continue; 4037 } 4038 if (task.autoRemoveRecents && task.getTopActivity() == null) { 4039 // This situation is broken, and we should just get rid of it now. 4040 mRecentTasks.remove(i); 4041 task.removedFromRecents(mTaskPersister); 4042 i--; 4043 N--; 4044 Slog.w(TAG, "Removing auto-remove without activity: " + task); 4045 continue; 4046 } 4047 // Check whether this activity is currently available. 4048 if (task.realActivity != null) { 4049 ActivityInfo ai = availActCache.get(task.realActivity); 4050 if (ai == null) { 4051 try { 4052 ai = pm.getActivityInfo(task.realActivity, 4053 PackageManager.GET_UNINSTALLED_PACKAGES 4054 | PackageManager.GET_DISABLED_COMPONENTS, user); 4055 } catch (RemoteException e) { 4056 // Will never happen. 4057 continue; 4058 } 4059 if (ai == null) { 4060 ai = dummyAct; 4061 } 4062 availActCache.put(task.realActivity, ai); 4063 } 4064 if (ai == dummyAct) { 4065 // This could be either because the activity no longer exists, or the 4066 // app is temporarily gone. For the former we want to remove the recents 4067 // entry; for the latter we want to mark it as unavailable. 4068 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4069 if (app == null) { 4070 try { 4071 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4072 PackageManager.GET_UNINSTALLED_PACKAGES 4073 | PackageManager.GET_DISABLED_COMPONENTS, user); 4074 } catch (RemoteException e) { 4075 // Will never happen. 4076 continue; 4077 } 4078 if (app == null) { 4079 app = dummyApp; 4080 } 4081 availAppCache.put(task.realActivity.getPackageName(), app); 4082 } 4083 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4084 // Doesn't exist any more! Good-bye. 4085 mRecentTasks.remove(i); 4086 task.removedFromRecents(mTaskPersister); 4087 i--; 4088 N--; 4089 Slog.w(TAG, "Removing no longer valid recent: " + task); 4090 continue; 4091 } else { 4092 // Otherwise just not available for now. 4093 if (task.isAvailable) { 4094 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4095 + task); 4096 } 4097 task.isAvailable = false; 4098 } 4099 } else { 4100 if (!ai.enabled || !ai.applicationInfo.enabled 4101 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4102 if (task.isAvailable) { 4103 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4104 + task + " (enabled=" + ai.enabled + "/" 4105 + ai.applicationInfo.enabled + " flags=" 4106 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4107 } 4108 task.isAvailable = false; 4109 } else { 4110 if (!task.isAvailable) { 4111 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4112 + task); 4113 } 4114 task.isAvailable = true; 4115 } 4116 } 4117 } 4118 } 4119 } 4120 4121 // Verify the affiliate chain for each task. 4122 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4123 } 4124 4125 mTmpRecents.clear(); 4126 // mRecentTasks is now in sorted, affiliated order. 4127 } 4128 4129 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4130 int N = mRecentTasks.size(); 4131 TaskRecord top = task; 4132 int topIndex = taskIndex; 4133 while (top.mNextAffiliate != null && topIndex > 0) { 4134 top = top.mNextAffiliate; 4135 topIndex--; 4136 } 4137 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4138 + topIndex + " from intial " + taskIndex); 4139 // Find the end of the chain, doing a sanity check along the way. 4140 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4141 int endIndex = topIndex; 4142 TaskRecord prev = top; 4143 while (endIndex < N) { 4144 TaskRecord cur = mRecentTasks.get(endIndex); 4145 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4146 + endIndex + " " + cur); 4147 if (cur == top) { 4148 // Verify start of the chain. 4149 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4150 Slog.wtf(TAG, "Bad chain @" + endIndex 4151 + ": first task has next affiliate: " + prev); 4152 sane = false; 4153 break; 4154 } 4155 } else { 4156 // Verify middle of the chain's next points back to the one before. 4157 if (cur.mNextAffiliate != prev 4158 || cur.mNextAffiliateTaskId != prev.taskId) { 4159 Slog.wtf(TAG, "Bad chain @" + endIndex 4160 + ": middle task " + cur + " @" + endIndex 4161 + " has bad next affiliate " 4162 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4163 + ", expected " + prev); 4164 sane = false; 4165 break; 4166 } 4167 } 4168 if (cur.mPrevAffiliateTaskId == -1) { 4169 // Chain ends here. 4170 if (cur.mPrevAffiliate != null) { 4171 Slog.wtf(TAG, "Bad chain @" + endIndex 4172 + ": last task " + cur + " has previous affiliate " 4173 + cur.mPrevAffiliate); 4174 sane = false; 4175 } 4176 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4177 break; 4178 } else { 4179 // Verify middle of the chain's prev points to a valid item. 4180 if (cur.mPrevAffiliate == null) { 4181 Slog.wtf(TAG, "Bad chain @" + endIndex 4182 + ": task " + cur + " has previous affiliate " 4183 + cur.mPrevAffiliate + " but should be id " 4184 + cur.mPrevAffiliate); 4185 sane = false; 4186 break; 4187 } 4188 } 4189 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4190 Slog.wtf(TAG, "Bad chain @" + endIndex 4191 + ": task " + cur + " has affiliated id " 4192 + cur.mAffiliatedTaskId + " but should be " 4193 + task.mAffiliatedTaskId); 4194 sane = false; 4195 break; 4196 } 4197 prev = cur; 4198 endIndex++; 4199 if (endIndex >= N) { 4200 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4201 + ": last task " + prev); 4202 sane = false; 4203 break; 4204 } 4205 } 4206 if (sane) { 4207 if (endIndex < taskIndex) { 4208 Slog.wtf(TAG, "Bad chain @" + endIndex 4209 + ": did not extend to task " + task + " @" + taskIndex); 4210 sane = false; 4211 } 4212 } 4213 if (sane) { 4214 // All looks good, we can just move all of the affiliated tasks 4215 // to the top. 4216 for (int i=topIndex; i<=endIndex; i++) { 4217 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4218 + " from " + i + " to " + (i-topIndex)); 4219 TaskRecord cur = mRecentTasks.remove(i); 4220 mRecentTasks.add(i-topIndex, cur); 4221 } 4222 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4223 + " to " + endIndex); 4224 return true; 4225 } 4226 4227 // Whoops, couldn't do it. 4228 return false; 4229 } 4230 4231 final void addRecentTaskLocked(TaskRecord task) { 4232 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4233 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4234 4235 int N = mRecentTasks.size(); 4236 // Quick case: check if the top-most recent task is the same. 4237 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4238 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4239 return; 4240 } 4241 // Another quick case: check if this is part of a set of affiliated 4242 // tasks that are at the top. 4243 if (isAffiliated && N > 0 && task.inRecents 4244 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4245 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4246 + " at top when adding " + task); 4247 return; 4248 } 4249 // Another quick case: never add voice sessions. 4250 if (task.voiceSession != null) { 4251 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4252 return; 4253 } 4254 4255 boolean needAffiliationFix = false; 4256 4257 // Slightly less quick case: the task is already in recents, so all we need 4258 // to do is move it. 4259 if (task.inRecents) { 4260 int taskIndex = mRecentTasks.indexOf(task); 4261 if (taskIndex >= 0) { 4262 if (!isAffiliated) { 4263 // Simple case: this is not an affiliated task, so we just move it to the front. 4264 mRecentTasks.remove(taskIndex); 4265 mRecentTasks.add(0, task); 4266 notifyTaskPersisterLocked(task, false); 4267 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4268 + " from " + taskIndex); 4269 return; 4270 } else { 4271 // More complicated: need to keep all affiliated tasks together. 4272 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4273 // All went well. 4274 return; 4275 } 4276 4277 // Uh oh... something bad in the affiliation chain, try to rebuild 4278 // everything and then go through our general path of adding a new task. 4279 needAffiliationFix = true; 4280 } 4281 } else { 4282 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4283 needAffiliationFix = true; 4284 } 4285 } 4286 4287 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4288 trimRecentsForTask(task, true); 4289 4290 N = mRecentTasks.size(); 4291 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4292 final TaskRecord tr = mRecentTasks.remove(N - 1); 4293 tr.removedFromRecents(mTaskPersister); 4294 N--; 4295 } 4296 task.inRecents = true; 4297 if (!isAffiliated || needAffiliationFix) { 4298 // If this is a simple non-affiliated task, or we had some failure trying to 4299 // handle it as part of an affilated task, then just place it at the top. 4300 mRecentTasks.add(0, task); 4301 } else if (isAffiliated) { 4302 // If this is a new affiliated task, then move all of the affiliated tasks 4303 // to the front and insert this new one. 4304 TaskRecord other = task.mNextAffiliate; 4305 if (other == null) { 4306 other = task.mPrevAffiliate; 4307 } 4308 if (other != null) { 4309 int otherIndex = mRecentTasks.indexOf(other); 4310 if (otherIndex >= 0) { 4311 // Insert new task at appropriate location. 4312 int taskIndex; 4313 if (other == task.mNextAffiliate) { 4314 // We found the index of our next affiliation, which is who is 4315 // before us in the list, so add after that point. 4316 taskIndex = otherIndex+1; 4317 } else { 4318 // We found the index of our previous affiliation, which is who is 4319 // after us in the list, so add at their position. 4320 taskIndex = otherIndex; 4321 } 4322 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4323 + taskIndex + ": " + task); 4324 mRecentTasks.add(taskIndex, task); 4325 4326 // Now move everything to the front. 4327 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4328 // All went well. 4329 return; 4330 } 4331 4332 // Uh oh... something bad in the affiliation chain, try to rebuild 4333 // everything and then go through our general path of adding a new task. 4334 needAffiliationFix = true; 4335 } else { 4336 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4337 + other); 4338 needAffiliationFix = true; 4339 } 4340 } else { 4341 if (DEBUG_RECENTS) Slog.d(TAG, 4342 "addRecent: adding affiliated task without next/prev:" + task); 4343 needAffiliationFix = true; 4344 } 4345 } 4346 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4347 4348 if (needAffiliationFix) { 4349 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4350 cleanupRecentTasksLocked(task.userId); 4351 } 4352 } 4353 4354 /** 4355 * If needed, remove oldest existing entries in recents that are for the same kind 4356 * of task as the given one. 4357 */ 4358 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4359 int N = mRecentTasks.size(); 4360 final Intent intent = task.intent; 4361 final boolean document = intent != null && intent.isDocument(); 4362 4363 int maxRecents = task.maxRecents - 1; 4364 for (int i=0; i<N; i++) { 4365 final TaskRecord tr = mRecentTasks.get(i); 4366 if (task != tr) { 4367 if (task.userId != tr.userId) { 4368 continue; 4369 } 4370 if (i > MAX_RECENT_BITMAPS) { 4371 tr.freeLastThumbnail(); 4372 } 4373 final Intent trIntent = tr.intent; 4374 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4375 (intent == null || !intent.filterEquals(trIntent))) { 4376 continue; 4377 } 4378 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4379 if (document && trIsDocument) { 4380 // These are the same document activity (not necessarily the same doc). 4381 if (maxRecents > 0) { 4382 --maxRecents; 4383 continue; 4384 } 4385 // Hit the maximum number of documents for this task. Fall through 4386 // and remove this document from recents. 4387 } else if (document || trIsDocument) { 4388 // Only one of these is a document. Not the droid we're looking for. 4389 continue; 4390 } 4391 } 4392 4393 if (!doTrim) { 4394 // If the caller is not actually asking for a trim, just tell them we reached 4395 // a point where the trim would happen. 4396 return i; 4397 } 4398 4399 // Either task and tr are the same or, their affinities match or their intents match 4400 // and neither of them is a document, or they are documents using the same activity 4401 // and their maxRecents has been reached. 4402 tr.disposeThumbnail(); 4403 mRecentTasks.remove(i); 4404 if (task != tr) { 4405 tr.removedFromRecents(mTaskPersister); 4406 } 4407 i--; 4408 N--; 4409 if (task.intent == null) { 4410 // If the new recent task we are adding is not fully 4411 // specified, then replace it with the existing recent task. 4412 task = tr; 4413 } 4414 notifyTaskPersisterLocked(tr, false); 4415 } 4416 4417 return -1; 4418 } 4419 4420 @Override 4421 public void reportActivityFullyDrawn(IBinder token) { 4422 synchronized (this) { 4423 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4424 if (r == null) { 4425 return; 4426 } 4427 r.reportFullyDrawnLocked(); 4428 } 4429 } 4430 4431 @Override 4432 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4433 synchronized (this) { 4434 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4435 if (r == null) { 4436 return; 4437 } 4438 final long origId = Binder.clearCallingIdentity(); 4439 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4440 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4441 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4442 if (config != null) { 4443 r.frozenBeforeDestroy = true; 4444 if (!updateConfigurationLocked(config, r, false, false)) { 4445 mStackSupervisor.resumeTopActivitiesLocked(); 4446 } 4447 } 4448 Binder.restoreCallingIdentity(origId); 4449 } 4450 } 4451 4452 @Override 4453 public int getRequestedOrientation(IBinder token) { 4454 synchronized (this) { 4455 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4456 if (r == null) { 4457 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4458 } 4459 return mWindowManager.getAppOrientation(r.appToken); 4460 } 4461 } 4462 4463 /** 4464 * This is the internal entry point for handling Activity.finish(). 4465 * 4466 * @param token The Binder token referencing the Activity we want to finish. 4467 * @param resultCode Result code, if any, from this Activity. 4468 * @param resultData Result data (Intent), if any, from this Activity. 4469 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4470 * the root Activity in the task. 4471 * 4472 * @return Returns true if the activity successfully finished, or false if it is still running. 4473 */ 4474 @Override 4475 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4476 boolean finishTask) { 4477 // Refuse possible leaked file descriptors 4478 if (resultData != null && resultData.hasFileDescriptors() == true) { 4479 throw new IllegalArgumentException("File descriptors passed in Intent"); 4480 } 4481 4482 synchronized(this) { 4483 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4484 if (r == null) { 4485 return true; 4486 } 4487 // Keep track of the root activity of the task before we finish it 4488 TaskRecord tr = r.task; 4489 ActivityRecord rootR = tr.getRootActivity(); 4490 // Do not allow task to finish in Lock Task mode. 4491 if (tr == mStackSupervisor.mLockTaskModeTask) { 4492 if (rootR == r) { 4493 mStackSupervisor.showLockTaskToast(); 4494 return false; 4495 } 4496 } 4497 if (mController != null) { 4498 // Find the first activity that is not finishing. 4499 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4500 if (next != null) { 4501 // ask watcher if this is allowed 4502 boolean resumeOK = true; 4503 try { 4504 resumeOK = mController.activityResuming(next.packageName); 4505 } catch (RemoteException e) { 4506 mController = null; 4507 Watchdog.getInstance().setActivityController(null); 4508 } 4509 4510 if (!resumeOK) { 4511 return false; 4512 } 4513 } 4514 } 4515 final long origId = Binder.clearCallingIdentity(); 4516 try { 4517 boolean res; 4518 if (finishTask && r == rootR) { 4519 // If requested, remove the task that is associated to this activity only if it 4520 // was the root activity in the task. The result code and data is ignored because 4521 // we don't support returning them across task boundaries. 4522 res = removeTaskByIdLocked(tr.taskId, 0); 4523 } else { 4524 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4525 resultData, "app-request", true); 4526 } 4527 return res; 4528 } finally { 4529 Binder.restoreCallingIdentity(origId); 4530 } 4531 } 4532 } 4533 4534 @Override 4535 public final void finishHeavyWeightApp() { 4536 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4537 != PackageManager.PERMISSION_GRANTED) { 4538 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4539 + Binder.getCallingPid() 4540 + ", uid=" + Binder.getCallingUid() 4541 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4542 Slog.w(TAG, msg); 4543 throw new SecurityException(msg); 4544 } 4545 4546 synchronized(this) { 4547 if (mHeavyWeightProcess == null) { 4548 return; 4549 } 4550 4551 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4552 mHeavyWeightProcess.activities); 4553 for (int i=0; i<activities.size(); i++) { 4554 ActivityRecord r = activities.get(i); 4555 if (!r.finishing) { 4556 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4557 null, "finish-heavy", true); 4558 } 4559 } 4560 4561 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4562 mHeavyWeightProcess.userId, 0)); 4563 mHeavyWeightProcess = null; 4564 } 4565 } 4566 4567 @Override 4568 public void crashApplication(int uid, int initialPid, String packageName, 4569 String message) { 4570 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4571 != PackageManager.PERMISSION_GRANTED) { 4572 String msg = "Permission Denial: crashApplication() from pid=" 4573 + Binder.getCallingPid() 4574 + ", uid=" + Binder.getCallingUid() 4575 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4576 Slog.w(TAG, msg); 4577 throw new SecurityException(msg); 4578 } 4579 4580 synchronized(this) { 4581 ProcessRecord proc = null; 4582 4583 // Figure out which process to kill. We don't trust that initialPid 4584 // still has any relation to current pids, so must scan through the 4585 // list. 4586 synchronized (mPidsSelfLocked) { 4587 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4588 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4589 if (p.uid != uid) { 4590 continue; 4591 } 4592 if (p.pid == initialPid) { 4593 proc = p; 4594 break; 4595 } 4596 if (p.pkgList.containsKey(packageName)) { 4597 proc = p; 4598 } 4599 } 4600 } 4601 4602 if (proc == null) { 4603 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4604 + " initialPid=" + initialPid 4605 + " packageName=" + packageName); 4606 return; 4607 } 4608 4609 if (proc.thread != null) { 4610 if (proc.pid == Process.myPid()) { 4611 Log.w(TAG, "crashApplication: trying to crash self!"); 4612 return; 4613 } 4614 long ident = Binder.clearCallingIdentity(); 4615 try { 4616 proc.thread.scheduleCrash(message); 4617 } catch (RemoteException e) { 4618 } 4619 Binder.restoreCallingIdentity(ident); 4620 } 4621 } 4622 } 4623 4624 @Override 4625 public final void finishSubActivity(IBinder token, String resultWho, 4626 int requestCode) { 4627 synchronized(this) { 4628 final long origId = Binder.clearCallingIdentity(); 4629 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4630 if (r != null) { 4631 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4632 } 4633 Binder.restoreCallingIdentity(origId); 4634 } 4635 } 4636 4637 @Override 4638 public boolean finishActivityAffinity(IBinder token) { 4639 synchronized(this) { 4640 final long origId = Binder.clearCallingIdentity(); 4641 try { 4642 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4643 4644 ActivityRecord rootR = r.task.getRootActivity(); 4645 // Do not allow task to finish in Lock Task mode. 4646 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4647 if (rootR == r) { 4648 mStackSupervisor.showLockTaskToast(); 4649 return false; 4650 } 4651 } 4652 boolean res = false; 4653 if (r != null) { 4654 res = r.task.stack.finishActivityAffinityLocked(r); 4655 } 4656 return res; 4657 } finally { 4658 Binder.restoreCallingIdentity(origId); 4659 } 4660 } 4661 } 4662 4663 @Override 4664 public void finishVoiceTask(IVoiceInteractionSession session) { 4665 synchronized(this) { 4666 final long origId = Binder.clearCallingIdentity(); 4667 try { 4668 mStackSupervisor.finishVoiceTask(session); 4669 } finally { 4670 Binder.restoreCallingIdentity(origId); 4671 } 4672 } 4673 4674 } 4675 4676 @Override 4677 public boolean releaseActivityInstance(IBinder token) { 4678 synchronized(this) { 4679 final long origId = Binder.clearCallingIdentity(); 4680 try { 4681 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4682 if (r.task == null || r.task.stack == null) { 4683 return false; 4684 } 4685 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4686 } finally { 4687 Binder.restoreCallingIdentity(origId); 4688 } 4689 } 4690 } 4691 4692 @Override 4693 public void releaseSomeActivities(IApplicationThread appInt) { 4694 synchronized(this) { 4695 final long origId = Binder.clearCallingIdentity(); 4696 try { 4697 ProcessRecord app = getRecordForAppLocked(appInt); 4698 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4699 } finally { 4700 Binder.restoreCallingIdentity(origId); 4701 } 4702 } 4703 } 4704 4705 @Override 4706 public boolean willActivityBeVisible(IBinder token) { 4707 synchronized(this) { 4708 ActivityStack stack = ActivityRecord.getStackLocked(token); 4709 if (stack != null) { 4710 return stack.willActivityBeVisibleLocked(token); 4711 } 4712 return false; 4713 } 4714 } 4715 4716 @Override 4717 public void overridePendingTransition(IBinder token, String packageName, 4718 int enterAnim, int exitAnim) { 4719 synchronized(this) { 4720 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4721 if (self == null) { 4722 return; 4723 } 4724 4725 final long origId = Binder.clearCallingIdentity(); 4726 4727 if (self.state == ActivityState.RESUMED 4728 || self.state == ActivityState.PAUSING) { 4729 mWindowManager.overridePendingAppTransition(packageName, 4730 enterAnim, exitAnim, null); 4731 } 4732 4733 Binder.restoreCallingIdentity(origId); 4734 } 4735 } 4736 4737 /** 4738 * Main function for removing an existing process from the activity manager 4739 * as a result of that process going away. Clears out all connections 4740 * to the process. 4741 */ 4742 private final void handleAppDiedLocked(ProcessRecord app, 4743 boolean restarting, boolean allowRestart) { 4744 int pid = app.pid; 4745 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4746 if (!kept && !restarting) { 4747 removeLruProcessLocked(app); 4748 if (pid > 0) { 4749 ProcessList.remove(pid); 4750 } 4751 } 4752 4753 if (mProfileProc == app) { 4754 clearProfilerLocked(); 4755 } 4756 4757 // Remove this application's activities from active lists. 4758 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4759 4760 app.activities.clear(); 4761 4762 if (app.instrumentationClass != null) { 4763 Slog.w(TAG, "Crash of app " + app.processName 4764 + " running instrumentation " + app.instrumentationClass); 4765 Bundle info = new Bundle(); 4766 info.putString("shortMsg", "Process crashed."); 4767 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4768 } 4769 4770 if (!restarting) { 4771 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4772 // If there was nothing to resume, and we are not already 4773 // restarting this process, but there is a visible activity that 4774 // is hosted by the process... then make sure all visible 4775 // activities are running, taking care of restarting this 4776 // process. 4777 if (hasVisibleActivities) { 4778 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4779 } 4780 } 4781 } 4782 } 4783 4784 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4785 IBinder threadBinder = thread.asBinder(); 4786 // Find the application record. 4787 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4788 ProcessRecord rec = mLruProcesses.get(i); 4789 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4790 return i; 4791 } 4792 } 4793 return -1; 4794 } 4795 4796 final ProcessRecord getRecordForAppLocked( 4797 IApplicationThread thread) { 4798 if (thread == null) { 4799 return null; 4800 } 4801 4802 int appIndex = getLRURecordIndexForAppLocked(thread); 4803 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4804 } 4805 4806 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4807 // If there are no longer any background processes running, 4808 // and the app that died was not running instrumentation, 4809 // then tell everyone we are now low on memory. 4810 boolean haveBg = false; 4811 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4812 ProcessRecord rec = mLruProcesses.get(i); 4813 if (rec.thread != null 4814 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4815 haveBg = true; 4816 break; 4817 } 4818 } 4819 4820 if (!haveBg) { 4821 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4822 if (doReport) { 4823 long now = SystemClock.uptimeMillis(); 4824 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4825 doReport = false; 4826 } else { 4827 mLastMemUsageReportTime = now; 4828 } 4829 } 4830 final ArrayList<ProcessMemInfo> memInfos 4831 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4832 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4833 long now = SystemClock.uptimeMillis(); 4834 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4835 ProcessRecord rec = mLruProcesses.get(i); 4836 if (rec == dyingProc || rec.thread == null) { 4837 continue; 4838 } 4839 if (doReport) { 4840 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4841 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4842 } 4843 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4844 // The low memory report is overriding any current 4845 // state for a GC request. Make sure to do 4846 // heavy/important/visible/foreground processes first. 4847 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4848 rec.lastRequestedGc = 0; 4849 } else { 4850 rec.lastRequestedGc = rec.lastLowMemory; 4851 } 4852 rec.reportLowMemory = true; 4853 rec.lastLowMemory = now; 4854 mProcessesToGc.remove(rec); 4855 addProcessToGcListLocked(rec); 4856 } 4857 } 4858 if (doReport) { 4859 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4860 mHandler.sendMessage(msg); 4861 } 4862 scheduleAppGcsLocked(); 4863 } 4864 } 4865 4866 final void appDiedLocked(ProcessRecord app) { 4867 appDiedLocked(app, app.pid, app.thread); 4868 } 4869 4870 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4871 // First check if this ProcessRecord is actually active for the pid. 4872 synchronized (mPidsSelfLocked) { 4873 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4874 if (curProc != app) { 4875 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4876 return; 4877 } 4878 } 4879 4880 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4881 synchronized (stats) { 4882 stats.noteProcessDiedLocked(app.info.uid, pid); 4883 } 4884 4885 if (!app.killed) { 4886 Process.killProcessQuiet(pid); 4887 Process.killProcessGroup(app.info.uid, pid); 4888 app.killed = true; 4889 } 4890 4891 // Clean up already done if the process has been re-started. 4892 if (app.pid == pid && app.thread != null && 4893 app.thread.asBinder() == thread.asBinder()) { 4894 boolean doLowMem = app.instrumentationClass == null; 4895 boolean doOomAdj = doLowMem; 4896 if (!app.killedByAm) { 4897 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4898 + ") has died"); 4899 mAllowLowerMemLevel = true; 4900 } else { 4901 // Note that we always want to do oom adj to update our state with the 4902 // new number of procs. 4903 mAllowLowerMemLevel = false; 4904 doLowMem = false; 4905 } 4906 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4907 if (DEBUG_CLEANUP) Slog.v( 4908 TAG, "Dying app: " + app + ", pid: " + pid 4909 + ", thread: " + thread.asBinder()); 4910 handleAppDiedLocked(app, false, true); 4911 4912 if (doOomAdj) { 4913 updateOomAdjLocked(); 4914 } 4915 if (doLowMem) { 4916 doLowMemReportIfNeededLocked(app); 4917 } 4918 } else if (app.pid != pid) { 4919 // A new process has already been started. 4920 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4921 + ") has died and restarted (pid " + app.pid + ")."); 4922 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4923 } else if (DEBUG_PROCESSES) { 4924 Slog.d(TAG, "Received spurious death notification for thread " 4925 + thread.asBinder()); 4926 } 4927 } 4928 4929 /** 4930 * If a stack trace dump file is configured, dump process stack traces. 4931 * @param clearTraces causes the dump file to be erased prior to the new 4932 * traces being written, if true; when false, the new traces will be 4933 * appended to any existing file content. 4934 * @param firstPids of dalvik VM processes to dump stack traces for first 4935 * @param lastPids of dalvik VM processes to dump stack traces for last 4936 * @param nativeProcs optional list of native process names to dump stack crawls 4937 * @return file containing stack traces, or null if no dump file is configured 4938 */ 4939 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4940 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4941 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4942 if (tracesPath == null || tracesPath.length() == 0) { 4943 return null; 4944 } 4945 4946 File tracesFile = new File(tracesPath); 4947 try { 4948 File tracesDir = tracesFile.getParentFile(); 4949 if (!tracesDir.exists()) { 4950 tracesDir.mkdirs(); 4951 if (!SELinux.restorecon(tracesDir)) { 4952 return null; 4953 } 4954 } 4955 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4956 4957 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4958 tracesFile.createNewFile(); 4959 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4960 } catch (IOException e) { 4961 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4962 return null; 4963 } 4964 4965 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4966 return tracesFile; 4967 } 4968 4969 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4970 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4971 // Use a FileObserver to detect when traces finish writing. 4972 // The order of traces is considered important to maintain for legibility. 4973 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4974 @Override 4975 public synchronized void onEvent(int event, String path) { notify(); } 4976 }; 4977 4978 try { 4979 observer.startWatching(); 4980 4981 // First collect all of the stacks of the most important pids. 4982 if (firstPids != null) { 4983 try { 4984 int num = firstPids.size(); 4985 for (int i = 0; i < num; i++) { 4986 synchronized (observer) { 4987 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4988 observer.wait(200); // Wait for write-close, give up after 200msec 4989 } 4990 } 4991 } catch (InterruptedException e) { 4992 Slog.wtf(TAG, e); 4993 } 4994 } 4995 4996 // Next collect the stacks of the native pids 4997 if (nativeProcs != null) { 4998 int[] pids = Process.getPidsForCommands(nativeProcs); 4999 if (pids != null) { 5000 for (int pid : pids) { 5001 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 5002 } 5003 } 5004 } 5005 5006 // Lastly, measure CPU usage. 5007 if (processCpuTracker != null) { 5008 processCpuTracker.init(); 5009 System.gc(); 5010 processCpuTracker.update(); 5011 try { 5012 synchronized (processCpuTracker) { 5013 processCpuTracker.wait(500); // measure over 1/2 second. 5014 } 5015 } catch (InterruptedException e) { 5016 } 5017 processCpuTracker.update(); 5018 5019 // We'll take the stack crawls of just the top apps using CPU. 5020 final int N = processCpuTracker.countWorkingStats(); 5021 int numProcs = 0; 5022 for (int i=0; i<N && numProcs<5; i++) { 5023 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5024 if (lastPids.indexOfKey(stats.pid) >= 0) { 5025 numProcs++; 5026 try { 5027 synchronized (observer) { 5028 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 5029 observer.wait(200); // Wait for write-close, give up after 200msec 5030 } 5031 } catch (InterruptedException e) { 5032 Slog.wtf(TAG, e); 5033 } 5034 5035 } 5036 } 5037 } 5038 } finally { 5039 observer.stopWatching(); 5040 } 5041 } 5042 5043 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5044 if (true || IS_USER_BUILD) { 5045 return; 5046 } 5047 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5048 if (tracesPath == null || tracesPath.length() == 0) { 5049 return; 5050 } 5051 5052 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5053 StrictMode.allowThreadDiskWrites(); 5054 try { 5055 final File tracesFile = new File(tracesPath); 5056 final File tracesDir = tracesFile.getParentFile(); 5057 final File tracesTmp = new File(tracesDir, "__tmp__"); 5058 try { 5059 if (!tracesDir.exists()) { 5060 tracesDir.mkdirs(); 5061 if (!SELinux.restorecon(tracesDir.getPath())) { 5062 return; 5063 } 5064 } 5065 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5066 5067 if (tracesFile.exists()) { 5068 tracesTmp.delete(); 5069 tracesFile.renameTo(tracesTmp); 5070 } 5071 StringBuilder sb = new StringBuilder(); 5072 Time tobj = new Time(); 5073 tobj.set(System.currentTimeMillis()); 5074 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5075 sb.append(": "); 5076 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5077 sb.append(" since "); 5078 sb.append(msg); 5079 FileOutputStream fos = new FileOutputStream(tracesFile); 5080 fos.write(sb.toString().getBytes()); 5081 if (app == null) { 5082 fos.write("\n*** No application process!".getBytes()); 5083 } 5084 fos.close(); 5085 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5086 } catch (IOException e) { 5087 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5088 return; 5089 } 5090 5091 if (app != null) { 5092 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5093 firstPids.add(app.pid); 5094 dumpStackTraces(tracesPath, firstPids, null, null, null); 5095 } 5096 5097 File lastTracesFile = null; 5098 File curTracesFile = null; 5099 for (int i=9; i>=0; i--) { 5100 String name = String.format(Locale.US, "slow%02d.txt", i); 5101 curTracesFile = new File(tracesDir, name); 5102 if (curTracesFile.exists()) { 5103 if (lastTracesFile != null) { 5104 curTracesFile.renameTo(lastTracesFile); 5105 } else { 5106 curTracesFile.delete(); 5107 } 5108 } 5109 lastTracesFile = curTracesFile; 5110 } 5111 tracesFile.renameTo(curTracesFile); 5112 if (tracesTmp.exists()) { 5113 tracesTmp.renameTo(tracesFile); 5114 } 5115 } finally { 5116 StrictMode.setThreadPolicy(oldPolicy); 5117 } 5118 } 5119 5120 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5121 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5122 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5123 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5124 5125 if (mController != null) { 5126 try { 5127 // 0 == continue, -1 = kill process immediately 5128 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5129 if (res < 0 && app.pid != MY_PID) { 5130 app.kill("anr", true); 5131 } 5132 } catch (RemoteException e) { 5133 mController = null; 5134 Watchdog.getInstance().setActivityController(null); 5135 } 5136 } 5137 5138 long anrTime = SystemClock.uptimeMillis(); 5139 if (MONITOR_CPU_USAGE) { 5140 updateCpuStatsNow(); 5141 } 5142 5143 synchronized (this) { 5144 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5145 if (mShuttingDown) { 5146 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5147 return; 5148 } else if (app.notResponding) { 5149 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5150 return; 5151 } else if (app.crashing) { 5152 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5153 return; 5154 } 5155 5156 // In case we come through here for the same app before completing 5157 // this one, mark as anring now so we will bail out. 5158 app.notResponding = true; 5159 5160 // Log the ANR to the event log. 5161 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5162 app.processName, app.info.flags, annotation); 5163 5164 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5165 firstPids.add(app.pid); 5166 5167 int parentPid = app.pid; 5168 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5169 if (parentPid != app.pid) firstPids.add(parentPid); 5170 5171 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5172 5173 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5174 ProcessRecord r = mLruProcesses.get(i); 5175 if (r != null && r.thread != null) { 5176 int pid = r.pid; 5177 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5178 if (r.persistent) { 5179 firstPids.add(pid); 5180 } else { 5181 lastPids.put(pid, Boolean.TRUE); 5182 } 5183 } 5184 } 5185 } 5186 } 5187 5188 // Log the ANR to the main log. 5189 StringBuilder info = new StringBuilder(); 5190 info.setLength(0); 5191 info.append("ANR in ").append(app.processName); 5192 if (activity != null && activity.shortComponentName != null) { 5193 info.append(" (").append(activity.shortComponentName).append(")"); 5194 } 5195 info.append("\n"); 5196 info.append("PID: ").append(app.pid).append("\n"); 5197 if (annotation != null) { 5198 info.append("Reason: ").append(annotation).append("\n"); 5199 } 5200 if (parent != null && parent != activity) { 5201 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5202 } 5203 5204 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5205 5206 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5207 NATIVE_STACKS_OF_INTEREST); 5208 5209 String cpuInfo = null; 5210 if (MONITOR_CPU_USAGE) { 5211 updateCpuStatsNow(); 5212 synchronized (mProcessCpuTracker) { 5213 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5214 } 5215 info.append(processCpuTracker.printCurrentLoad()); 5216 info.append(cpuInfo); 5217 } 5218 5219 info.append(processCpuTracker.printCurrentState(anrTime)); 5220 5221 Slog.e(TAG, info.toString()); 5222 if (tracesFile == null) { 5223 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5224 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5225 } 5226 5227 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5228 cpuInfo, tracesFile, null); 5229 5230 if (mController != null) { 5231 try { 5232 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5233 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5234 if (res != 0) { 5235 if (res < 0 && app.pid != MY_PID) { 5236 app.kill("anr", true); 5237 } else { 5238 synchronized (this) { 5239 mServices.scheduleServiceTimeoutLocked(app); 5240 } 5241 } 5242 return; 5243 } 5244 } catch (RemoteException e) { 5245 mController = null; 5246 Watchdog.getInstance().setActivityController(null); 5247 } 5248 } 5249 5250 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5251 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5252 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5253 5254 synchronized (this) { 5255 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5256 app.kill("bg anr", true); 5257 return; 5258 } 5259 5260 // Set the app's notResponding state, and look up the errorReportReceiver 5261 makeAppNotRespondingLocked(app, 5262 activity != null ? activity.shortComponentName : null, 5263 annotation != null ? "ANR " + annotation : "ANR", 5264 info.toString()); 5265 5266 // Bring up the infamous App Not Responding dialog 5267 Message msg = Message.obtain(); 5268 HashMap<String, Object> map = new HashMap<String, Object>(); 5269 msg.what = SHOW_NOT_RESPONDING_MSG; 5270 msg.obj = map; 5271 msg.arg1 = aboveSystem ? 1 : 0; 5272 map.put("app", app); 5273 if (activity != null) { 5274 map.put("activity", activity); 5275 } 5276 5277 mHandler.sendMessage(msg); 5278 } 5279 } 5280 5281 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5282 if (!mLaunchWarningShown) { 5283 mLaunchWarningShown = true; 5284 mHandler.post(new Runnable() { 5285 @Override 5286 public void run() { 5287 synchronized (ActivityManagerService.this) { 5288 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5289 d.show(); 5290 mHandler.postDelayed(new Runnable() { 5291 @Override 5292 public void run() { 5293 synchronized (ActivityManagerService.this) { 5294 d.dismiss(); 5295 mLaunchWarningShown = false; 5296 } 5297 } 5298 }, 4000); 5299 } 5300 } 5301 }); 5302 } 5303 } 5304 5305 @Override 5306 public boolean clearApplicationUserData(final String packageName, 5307 final IPackageDataObserver observer, int userId) { 5308 enforceNotIsolatedCaller("clearApplicationUserData"); 5309 int uid = Binder.getCallingUid(); 5310 int pid = Binder.getCallingPid(); 5311 userId = handleIncomingUser(pid, uid, 5312 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5313 long callingId = Binder.clearCallingIdentity(); 5314 try { 5315 IPackageManager pm = AppGlobals.getPackageManager(); 5316 int pkgUid = -1; 5317 synchronized(this) { 5318 try { 5319 pkgUid = pm.getPackageUid(packageName, userId); 5320 } catch (RemoteException e) { 5321 } 5322 if (pkgUid == -1) { 5323 Slog.w(TAG, "Invalid packageName: " + packageName); 5324 if (observer != null) { 5325 try { 5326 observer.onRemoveCompleted(packageName, false); 5327 } catch (RemoteException e) { 5328 Slog.i(TAG, "Observer no longer exists."); 5329 } 5330 } 5331 return false; 5332 } 5333 if (uid == pkgUid || checkComponentPermission( 5334 android.Manifest.permission.CLEAR_APP_USER_DATA, 5335 pid, uid, -1, true) 5336 == PackageManager.PERMISSION_GRANTED) { 5337 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5338 } else { 5339 throw new SecurityException("PID " + pid + " does not have permission " 5340 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5341 + " of package " + packageName); 5342 } 5343 5344 // Remove all tasks match the cleared application package and user 5345 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5346 final TaskRecord tr = mRecentTasks.get(i); 5347 final String taskPackageName = 5348 tr.getBaseIntent().getComponent().getPackageName(); 5349 if (tr.userId != userId) continue; 5350 if (!taskPackageName.equals(packageName)) continue; 5351 removeTaskByIdLocked(tr.taskId, 0); 5352 } 5353 } 5354 5355 try { 5356 // Clear application user data 5357 pm.clearApplicationUserData(packageName, observer, userId); 5358 5359 synchronized(this) { 5360 // Remove all permissions granted from/to this package 5361 removeUriPermissionsForPackageLocked(packageName, userId, true); 5362 } 5363 5364 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5365 Uri.fromParts("package", packageName, null)); 5366 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5367 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5368 null, null, 0, null, null, null, false, false, userId); 5369 } catch (RemoteException e) { 5370 } 5371 } finally { 5372 Binder.restoreCallingIdentity(callingId); 5373 } 5374 return true; 5375 } 5376 5377 @Override 5378 public void killBackgroundProcesses(final String packageName, int userId) { 5379 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5380 != PackageManager.PERMISSION_GRANTED && 5381 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5382 != PackageManager.PERMISSION_GRANTED) { 5383 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5384 + Binder.getCallingPid() 5385 + ", uid=" + Binder.getCallingUid() 5386 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5387 Slog.w(TAG, msg); 5388 throw new SecurityException(msg); 5389 } 5390 5391 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5392 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5393 long callingId = Binder.clearCallingIdentity(); 5394 try { 5395 IPackageManager pm = AppGlobals.getPackageManager(); 5396 synchronized(this) { 5397 int appId = -1; 5398 try { 5399 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5400 } catch (RemoteException e) { 5401 } 5402 if (appId == -1) { 5403 Slog.w(TAG, "Invalid packageName: " + packageName); 5404 return; 5405 } 5406 killPackageProcessesLocked(packageName, appId, userId, 5407 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5408 } 5409 } finally { 5410 Binder.restoreCallingIdentity(callingId); 5411 } 5412 } 5413 5414 @Override 5415 public void killAllBackgroundProcesses() { 5416 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5417 != PackageManager.PERMISSION_GRANTED) { 5418 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5419 + Binder.getCallingPid() 5420 + ", uid=" + Binder.getCallingUid() 5421 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5422 Slog.w(TAG, msg); 5423 throw new SecurityException(msg); 5424 } 5425 5426 long callingId = Binder.clearCallingIdentity(); 5427 try { 5428 synchronized(this) { 5429 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5430 final int NP = mProcessNames.getMap().size(); 5431 for (int ip=0; ip<NP; ip++) { 5432 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5433 final int NA = apps.size(); 5434 for (int ia=0; ia<NA; ia++) { 5435 ProcessRecord app = apps.valueAt(ia); 5436 if (app.persistent) { 5437 // we don't kill persistent processes 5438 continue; 5439 } 5440 if (app.removed) { 5441 procs.add(app); 5442 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5443 app.removed = true; 5444 procs.add(app); 5445 } 5446 } 5447 } 5448 5449 int N = procs.size(); 5450 for (int i=0; i<N; i++) { 5451 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5452 } 5453 mAllowLowerMemLevel = true; 5454 updateOomAdjLocked(); 5455 doLowMemReportIfNeededLocked(null); 5456 } 5457 } finally { 5458 Binder.restoreCallingIdentity(callingId); 5459 } 5460 } 5461 5462 @Override 5463 public void forceStopPackage(final String packageName, int userId) { 5464 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5465 != PackageManager.PERMISSION_GRANTED) { 5466 String msg = "Permission Denial: forceStopPackage() from pid=" 5467 + Binder.getCallingPid() 5468 + ", uid=" + Binder.getCallingUid() 5469 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5470 Slog.w(TAG, msg); 5471 throw new SecurityException(msg); 5472 } 5473 final int callingPid = Binder.getCallingPid(); 5474 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5475 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5476 long callingId = Binder.clearCallingIdentity(); 5477 try { 5478 IPackageManager pm = AppGlobals.getPackageManager(); 5479 synchronized(this) { 5480 int[] users = userId == UserHandle.USER_ALL 5481 ? getUsersLocked() : new int[] { userId }; 5482 for (int user : users) { 5483 int pkgUid = -1; 5484 try { 5485 pkgUid = pm.getPackageUid(packageName, user); 5486 } catch (RemoteException e) { 5487 } 5488 if (pkgUid == -1) { 5489 Slog.w(TAG, "Invalid packageName: " + packageName); 5490 continue; 5491 } 5492 try { 5493 pm.setPackageStoppedState(packageName, true, user); 5494 } catch (RemoteException e) { 5495 } catch (IllegalArgumentException e) { 5496 Slog.w(TAG, "Failed trying to unstop package " 5497 + packageName + ": " + e); 5498 } 5499 if (isUserRunningLocked(user, false)) { 5500 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5501 } 5502 } 5503 } 5504 } finally { 5505 Binder.restoreCallingIdentity(callingId); 5506 } 5507 } 5508 5509 @Override 5510 public void addPackageDependency(String packageName) { 5511 synchronized (this) { 5512 int callingPid = Binder.getCallingPid(); 5513 if (callingPid == Process.myPid()) { 5514 // Yeah, um, no. 5515 Slog.w(TAG, "Can't addPackageDependency on system process"); 5516 return; 5517 } 5518 ProcessRecord proc; 5519 synchronized (mPidsSelfLocked) { 5520 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5521 } 5522 if (proc != null) { 5523 if (proc.pkgDeps == null) { 5524 proc.pkgDeps = new ArraySet<String>(1); 5525 } 5526 proc.pkgDeps.add(packageName); 5527 } 5528 } 5529 } 5530 5531 /* 5532 * The pkg name and app id have to be specified. 5533 */ 5534 @Override 5535 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5536 if (pkg == null) { 5537 return; 5538 } 5539 // Make sure the uid is valid. 5540 if (appid < 0) { 5541 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5542 return; 5543 } 5544 int callerUid = Binder.getCallingUid(); 5545 // Only the system server can kill an application 5546 if (callerUid == Process.SYSTEM_UID) { 5547 // Post an aysnc message to kill the application 5548 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5549 msg.arg1 = appid; 5550 msg.arg2 = 0; 5551 Bundle bundle = new Bundle(); 5552 bundle.putString("pkg", pkg); 5553 bundle.putString("reason", reason); 5554 msg.obj = bundle; 5555 mHandler.sendMessage(msg); 5556 } else { 5557 throw new SecurityException(callerUid + " cannot kill pkg: " + 5558 pkg); 5559 } 5560 } 5561 5562 @Override 5563 public void closeSystemDialogs(String reason) { 5564 enforceNotIsolatedCaller("closeSystemDialogs"); 5565 5566 final int pid = Binder.getCallingPid(); 5567 final int uid = Binder.getCallingUid(); 5568 final long origId = Binder.clearCallingIdentity(); 5569 try { 5570 synchronized (this) { 5571 // Only allow this from foreground processes, so that background 5572 // applications can't abuse it to prevent system UI from being shown. 5573 if (uid >= Process.FIRST_APPLICATION_UID) { 5574 ProcessRecord proc; 5575 synchronized (mPidsSelfLocked) { 5576 proc = mPidsSelfLocked.get(pid); 5577 } 5578 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5579 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5580 + " from background process " + proc); 5581 return; 5582 } 5583 } 5584 closeSystemDialogsLocked(reason); 5585 } 5586 } finally { 5587 Binder.restoreCallingIdentity(origId); 5588 } 5589 } 5590 5591 void closeSystemDialogsLocked(String reason) { 5592 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5593 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5594 | Intent.FLAG_RECEIVER_FOREGROUND); 5595 if (reason != null) { 5596 intent.putExtra("reason", reason); 5597 } 5598 mWindowManager.closeSystemDialogs(reason); 5599 5600 mStackSupervisor.closeSystemDialogsLocked(); 5601 5602 broadcastIntentLocked(null, null, intent, null, 5603 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5604 Process.SYSTEM_UID, UserHandle.USER_ALL); 5605 } 5606 5607 @Override 5608 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5609 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5610 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5611 for (int i=pids.length-1; i>=0; i--) { 5612 ProcessRecord proc; 5613 int oomAdj; 5614 synchronized (this) { 5615 synchronized (mPidsSelfLocked) { 5616 proc = mPidsSelfLocked.get(pids[i]); 5617 oomAdj = proc != null ? proc.setAdj : 0; 5618 } 5619 } 5620 infos[i] = new Debug.MemoryInfo(); 5621 Debug.getMemoryInfo(pids[i], infos[i]); 5622 if (proc != null) { 5623 synchronized (this) { 5624 if (proc.thread != null && proc.setAdj == oomAdj) { 5625 // Record this for posterity if the process has been stable. 5626 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5627 infos[i].getTotalUss(), false, proc.pkgList); 5628 } 5629 } 5630 } 5631 } 5632 return infos; 5633 } 5634 5635 @Override 5636 public long[] getProcessPss(int[] pids) { 5637 enforceNotIsolatedCaller("getProcessPss"); 5638 long[] pss = new long[pids.length]; 5639 for (int i=pids.length-1; i>=0; i--) { 5640 ProcessRecord proc; 5641 int oomAdj; 5642 synchronized (this) { 5643 synchronized (mPidsSelfLocked) { 5644 proc = mPidsSelfLocked.get(pids[i]); 5645 oomAdj = proc != null ? proc.setAdj : 0; 5646 } 5647 } 5648 long[] tmpUss = new long[1]; 5649 pss[i] = Debug.getPss(pids[i], tmpUss); 5650 if (proc != null) { 5651 synchronized (this) { 5652 if (proc.thread != null && proc.setAdj == oomAdj) { 5653 // Record this for posterity if the process has been stable. 5654 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5655 } 5656 } 5657 } 5658 } 5659 return pss; 5660 } 5661 5662 @Override 5663 public void killApplicationProcess(String processName, int uid) { 5664 if (processName == null) { 5665 return; 5666 } 5667 5668 int callerUid = Binder.getCallingUid(); 5669 // Only the system server can kill an application 5670 if (callerUid == Process.SYSTEM_UID) { 5671 synchronized (this) { 5672 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5673 if (app != null && app.thread != null) { 5674 try { 5675 app.thread.scheduleSuicide(); 5676 } catch (RemoteException e) { 5677 // If the other end already died, then our work here is done. 5678 } 5679 } else { 5680 Slog.w(TAG, "Process/uid not found attempting kill of " 5681 + processName + " / " + uid); 5682 } 5683 } 5684 } else { 5685 throw new SecurityException(callerUid + " cannot kill app process: " + 5686 processName); 5687 } 5688 } 5689 5690 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5691 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5692 false, true, false, false, UserHandle.getUserId(uid), reason); 5693 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5694 Uri.fromParts("package", packageName, null)); 5695 if (!mProcessesReady) { 5696 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5697 | Intent.FLAG_RECEIVER_FOREGROUND); 5698 } 5699 intent.putExtra(Intent.EXTRA_UID, uid); 5700 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5701 broadcastIntentLocked(null, null, intent, 5702 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5703 false, false, 5704 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5705 } 5706 5707 private void forceStopUserLocked(int userId, String reason) { 5708 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5709 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5710 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5711 | Intent.FLAG_RECEIVER_FOREGROUND); 5712 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5713 broadcastIntentLocked(null, null, intent, 5714 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5715 false, false, 5716 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5717 } 5718 5719 private final boolean killPackageProcessesLocked(String packageName, int appId, 5720 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5721 boolean doit, boolean evenPersistent, String reason) { 5722 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5723 5724 // Remove all processes this package may have touched: all with the 5725 // same UID (except for the system or root user), and all whose name 5726 // matches the package name. 5727 final int NP = mProcessNames.getMap().size(); 5728 for (int ip=0; ip<NP; ip++) { 5729 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5730 final int NA = apps.size(); 5731 for (int ia=0; ia<NA; ia++) { 5732 ProcessRecord app = apps.valueAt(ia); 5733 if (app.persistent && !evenPersistent) { 5734 // we don't kill persistent processes 5735 continue; 5736 } 5737 if (app.removed) { 5738 if (doit) { 5739 procs.add(app); 5740 } 5741 continue; 5742 } 5743 5744 // Skip process if it doesn't meet our oom adj requirement. 5745 if (app.setAdj < minOomAdj) { 5746 continue; 5747 } 5748 5749 // If no package is specified, we call all processes under the 5750 // give user id. 5751 if (packageName == null) { 5752 if (app.userId != userId) { 5753 continue; 5754 } 5755 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5756 continue; 5757 } 5758 // Package has been specified, we want to hit all processes 5759 // that match it. We need to qualify this by the processes 5760 // that are running under the specified app and user ID. 5761 } else { 5762 final boolean isDep = app.pkgDeps != null 5763 && app.pkgDeps.contains(packageName); 5764 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5765 continue; 5766 } 5767 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5768 continue; 5769 } 5770 if (!app.pkgList.containsKey(packageName) && !isDep) { 5771 continue; 5772 } 5773 } 5774 5775 // Process has passed all conditions, kill it! 5776 if (!doit) { 5777 return true; 5778 } 5779 app.removed = true; 5780 procs.add(app); 5781 } 5782 } 5783 5784 int N = procs.size(); 5785 for (int i=0; i<N; i++) { 5786 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5787 } 5788 updateOomAdjLocked(); 5789 return N > 0; 5790 } 5791 5792 private final boolean forceStopPackageLocked(String name, int appId, 5793 boolean callerWillRestart, boolean purgeCache, boolean doit, 5794 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5795 int i; 5796 int N; 5797 5798 if (userId == UserHandle.USER_ALL && name == null) { 5799 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5800 } 5801 5802 if (appId < 0 && name != null) { 5803 try { 5804 appId = UserHandle.getAppId( 5805 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5806 } catch (RemoteException e) { 5807 } 5808 } 5809 5810 if (doit) { 5811 if (name != null) { 5812 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5813 + " user=" + userId + ": " + reason); 5814 } else { 5815 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5816 } 5817 5818 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5819 for (int ip=pmap.size()-1; ip>=0; ip--) { 5820 SparseArray<Long> ba = pmap.valueAt(ip); 5821 for (i=ba.size()-1; i>=0; i--) { 5822 boolean remove = false; 5823 final int entUid = ba.keyAt(i); 5824 if (name != null) { 5825 if (userId == UserHandle.USER_ALL) { 5826 if (UserHandle.getAppId(entUid) == appId) { 5827 remove = true; 5828 } 5829 } else { 5830 if (entUid == UserHandle.getUid(userId, appId)) { 5831 remove = true; 5832 } 5833 } 5834 } else if (UserHandle.getUserId(entUid) == userId) { 5835 remove = true; 5836 } 5837 if (remove) { 5838 ba.removeAt(i); 5839 } 5840 } 5841 if (ba.size() == 0) { 5842 pmap.removeAt(ip); 5843 } 5844 } 5845 } 5846 5847 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5848 -100, callerWillRestart, true, doit, evenPersistent, 5849 name == null ? ("stop user " + userId) : ("stop " + name)); 5850 5851 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5852 if (!doit) { 5853 return true; 5854 } 5855 didSomething = true; 5856 } 5857 5858 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5859 if (!doit) { 5860 return true; 5861 } 5862 didSomething = true; 5863 } 5864 5865 if (name == null) { 5866 // Remove all sticky broadcasts from this user. 5867 mStickyBroadcasts.remove(userId); 5868 } 5869 5870 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5871 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5872 userId, providers)) { 5873 if (!doit) { 5874 return true; 5875 } 5876 didSomething = true; 5877 } 5878 N = providers.size(); 5879 for (i=0; i<N; i++) { 5880 removeDyingProviderLocked(null, providers.get(i), true); 5881 } 5882 5883 // Remove transient permissions granted from/to this package/user 5884 removeUriPermissionsForPackageLocked(name, userId, false); 5885 5886 if (name == null || uninstalling) { 5887 // Remove pending intents. For now we only do this when force 5888 // stopping users, because we have some problems when doing this 5889 // for packages -- app widgets are not currently cleaned up for 5890 // such packages, so they can be left with bad pending intents. 5891 if (mIntentSenderRecords.size() > 0) { 5892 Iterator<WeakReference<PendingIntentRecord>> it 5893 = mIntentSenderRecords.values().iterator(); 5894 while (it.hasNext()) { 5895 WeakReference<PendingIntentRecord> wpir = it.next(); 5896 if (wpir == null) { 5897 it.remove(); 5898 continue; 5899 } 5900 PendingIntentRecord pir = wpir.get(); 5901 if (pir == null) { 5902 it.remove(); 5903 continue; 5904 } 5905 if (name == null) { 5906 // Stopping user, remove all objects for the user. 5907 if (pir.key.userId != userId) { 5908 // Not the same user, skip it. 5909 continue; 5910 } 5911 } else { 5912 if (UserHandle.getAppId(pir.uid) != appId) { 5913 // Different app id, skip it. 5914 continue; 5915 } 5916 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5917 // Different user, skip it. 5918 continue; 5919 } 5920 if (!pir.key.packageName.equals(name)) { 5921 // Different package, skip it. 5922 continue; 5923 } 5924 } 5925 if (!doit) { 5926 return true; 5927 } 5928 didSomething = true; 5929 it.remove(); 5930 pir.canceled = true; 5931 if (pir.key.activity != null) { 5932 pir.key.activity.pendingResults.remove(pir.ref); 5933 } 5934 } 5935 } 5936 } 5937 5938 if (doit) { 5939 if (purgeCache && name != null) { 5940 AttributeCache ac = AttributeCache.instance(); 5941 if (ac != null) { 5942 ac.removePackage(name); 5943 } 5944 } 5945 if (mBooted) { 5946 mStackSupervisor.resumeTopActivitiesLocked(); 5947 mStackSupervisor.scheduleIdleLocked(); 5948 } 5949 } 5950 5951 return didSomething; 5952 } 5953 5954 private final boolean removeProcessLocked(ProcessRecord app, 5955 boolean callerWillRestart, boolean allowRestart, String reason) { 5956 final String name = app.processName; 5957 final int uid = app.uid; 5958 if (DEBUG_PROCESSES) Slog.d( 5959 TAG, "Force removing proc " + app.toShortString() + " (" + name 5960 + "/" + uid + ")"); 5961 5962 mProcessNames.remove(name, uid); 5963 mIsolatedProcesses.remove(app.uid); 5964 if (mHeavyWeightProcess == app) { 5965 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5966 mHeavyWeightProcess.userId, 0)); 5967 mHeavyWeightProcess = null; 5968 } 5969 boolean needRestart = false; 5970 if (app.pid > 0 && app.pid != MY_PID) { 5971 int pid = app.pid; 5972 synchronized (mPidsSelfLocked) { 5973 mPidsSelfLocked.remove(pid); 5974 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5975 } 5976 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5977 if (app.isolated) { 5978 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5979 } 5980 app.kill(reason, true); 5981 handleAppDiedLocked(app, true, allowRestart); 5982 removeLruProcessLocked(app); 5983 5984 if (app.persistent && !app.isolated) { 5985 if (!callerWillRestart) { 5986 addAppLocked(app.info, false, null /* ABI override */); 5987 } else { 5988 needRestart = true; 5989 } 5990 } 5991 } else { 5992 mRemovedProcesses.add(app); 5993 } 5994 5995 return needRestart; 5996 } 5997 5998 private final void processStartTimedOutLocked(ProcessRecord app) { 5999 final int pid = app.pid; 6000 boolean gone = false; 6001 synchronized (mPidsSelfLocked) { 6002 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 6003 if (knownApp != null && knownApp.thread == null) { 6004 mPidsSelfLocked.remove(pid); 6005 gone = true; 6006 } 6007 } 6008 6009 if (gone) { 6010 Slog.w(TAG, "Process " + app + " failed to attach"); 6011 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 6012 pid, app.uid, app.processName); 6013 mProcessNames.remove(app.processName, app.uid); 6014 mIsolatedProcesses.remove(app.uid); 6015 if (mHeavyWeightProcess == app) { 6016 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6017 mHeavyWeightProcess.userId, 0)); 6018 mHeavyWeightProcess = null; 6019 } 6020 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6021 if (app.isolated) { 6022 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6023 } 6024 // Take care of any launching providers waiting for this process. 6025 checkAppInLaunchingProvidersLocked(app, true); 6026 // Take care of any services that are waiting for the process. 6027 mServices.processStartTimedOutLocked(app); 6028 app.kill("start timeout", true); 6029 removeLruProcessLocked(app); 6030 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6031 Slog.w(TAG, "Unattached app died before backup, skipping"); 6032 try { 6033 IBackupManager bm = IBackupManager.Stub.asInterface( 6034 ServiceManager.getService(Context.BACKUP_SERVICE)); 6035 bm.agentDisconnected(app.info.packageName); 6036 } catch (RemoteException e) { 6037 // Can't happen; the backup manager is local 6038 } 6039 } 6040 if (isPendingBroadcastProcessLocked(pid)) { 6041 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6042 skipPendingBroadcastLocked(pid); 6043 } 6044 } else { 6045 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6046 } 6047 } 6048 6049 private final boolean attachApplicationLocked(IApplicationThread thread, 6050 int pid) { 6051 6052 // Find the application record that is being attached... either via 6053 // the pid if we are running in multiple processes, or just pull the 6054 // next app record if we are emulating process with anonymous threads. 6055 ProcessRecord app; 6056 if (pid != MY_PID && pid >= 0) { 6057 synchronized (mPidsSelfLocked) { 6058 app = mPidsSelfLocked.get(pid); 6059 } 6060 } else { 6061 app = null; 6062 } 6063 6064 if (app == null) { 6065 Slog.w(TAG, "No pending application record for pid " + pid 6066 + " (IApplicationThread " + thread + "); dropping process"); 6067 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6068 if (pid > 0 && pid != MY_PID) { 6069 Process.killProcessQuiet(pid); 6070 //TODO: Process.killProcessGroup(app.info.uid, pid); 6071 } else { 6072 try { 6073 thread.scheduleExit(); 6074 } catch (Exception e) { 6075 // Ignore exceptions. 6076 } 6077 } 6078 return false; 6079 } 6080 6081 // If this application record is still attached to a previous 6082 // process, clean it up now. 6083 if (app.thread != null) { 6084 handleAppDiedLocked(app, true, true); 6085 } 6086 6087 // Tell the process all about itself. 6088 6089 if (localLOGV) Slog.v( 6090 TAG, "Binding process pid " + pid + " to record " + app); 6091 6092 final String processName = app.processName; 6093 try { 6094 AppDeathRecipient adr = new AppDeathRecipient( 6095 app, pid, thread); 6096 thread.asBinder().linkToDeath(adr, 0); 6097 app.deathRecipient = adr; 6098 } catch (RemoteException e) { 6099 app.resetPackageList(mProcessStats); 6100 startProcessLocked(app, "link fail", processName); 6101 return false; 6102 } 6103 6104 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6105 6106 app.makeActive(thread, mProcessStats); 6107 app.curAdj = app.setAdj = -100; 6108 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6109 app.forcingToForeground = null; 6110 updateProcessForegroundLocked(app, false, false); 6111 app.hasShownUi = false; 6112 app.debugging = false; 6113 app.cached = false; 6114 app.killedByAm = false; 6115 6116 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6117 6118 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6119 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6120 6121 if (!normalMode) { 6122 Slog.i(TAG, "Launching preboot mode app: " + app); 6123 } 6124 6125 if (localLOGV) Slog.v( 6126 TAG, "New app record " + app 6127 + " thread=" + thread.asBinder() + " pid=" + pid); 6128 try { 6129 int testMode = IApplicationThread.DEBUG_OFF; 6130 if (mDebugApp != null && mDebugApp.equals(processName)) { 6131 testMode = mWaitForDebugger 6132 ? IApplicationThread.DEBUG_WAIT 6133 : IApplicationThread.DEBUG_ON; 6134 app.debugging = true; 6135 if (mDebugTransient) { 6136 mDebugApp = mOrigDebugApp; 6137 mWaitForDebugger = mOrigWaitForDebugger; 6138 } 6139 } 6140 String profileFile = app.instrumentationProfileFile; 6141 ParcelFileDescriptor profileFd = null; 6142 int samplingInterval = 0; 6143 boolean profileAutoStop = false; 6144 if (mProfileApp != null && mProfileApp.equals(processName)) { 6145 mProfileProc = app; 6146 profileFile = mProfileFile; 6147 profileFd = mProfileFd; 6148 samplingInterval = mSamplingInterval; 6149 profileAutoStop = mAutoStopProfiler; 6150 } 6151 boolean enableOpenGlTrace = false; 6152 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6153 enableOpenGlTrace = true; 6154 mOpenGlTraceApp = null; 6155 } 6156 6157 // If the app is being launched for restore or full backup, set it up specially 6158 boolean isRestrictedBackupMode = false; 6159 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6160 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6161 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6162 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6163 } 6164 6165 ensurePackageDexOpt(app.instrumentationInfo != null 6166 ? app.instrumentationInfo.packageName 6167 : app.info.packageName); 6168 if (app.instrumentationClass != null) { 6169 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6170 } 6171 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6172 + processName + " with config " + mConfiguration); 6173 ApplicationInfo appInfo = app.instrumentationInfo != null 6174 ? app.instrumentationInfo : app.info; 6175 app.compat = compatibilityInfoForPackageLocked(appInfo); 6176 if (profileFd != null) { 6177 profileFd = profileFd.dup(); 6178 } 6179 ProfilerInfo profilerInfo = profileFile == null ? null 6180 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6181 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6182 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6183 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6184 isRestrictedBackupMode || !normalMode, app.persistent, 6185 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6186 mCoreSettingsObserver.getCoreSettingsLocked()); 6187 updateLruProcessLocked(app, false, null); 6188 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6189 } catch (Exception e) { 6190 // todo: Yikes! What should we do? For now we will try to 6191 // start another process, but that could easily get us in 6192 // an infinite loop of restarting processes... 6193 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6194 6195 app.resetPackageList(mProcessStats); 6196 app.unlinkDeathRecipient(); 6197 startProcessLocked(app, "bind fail", processName); 6198 return false; 6199 } 6200 6201 // Remove this record from the list of starting applications. 6202 mPersistentStartingProcesses.remove(app); 6203 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6204 "Attach application locked removing on hold: " + app); 6205 mProcessesOnHold.remove(app); 6206 6207 boolean badApp = false; 6208 boolean didSomething = false; 6209 6210 // See if the top visible activity is waiting to run in this process... 6211 if (normalMode) { 6212 try { 6213 if (mStackSupervisor.attachApplicationLocked(app)) { 6214 didSomething = true; 6215 } 6216 } catch (Exception e) { 6217 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6218 badApp = true; 6219 } 6220 } 6221 6222 // Find any services that should be running in this process... 6223 if (!badApp) { 6224 try { 6225 didSomething |= mServices.attachApplicationLocked(app, processName); 6226 } catch (Exception e) { 6227 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6228 badApp = true; 6229 } 6230 } 6231 6232 // Check if a next-broadcast receiver is in this process... 6233 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6234 try { 6235 didSomething |= sendPendingBroadcastsLocked(app); 6236 } catch (Exception e) { 6237 // If the app died trying to launch the receiver we declare it 'bad' 6238 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6239 badApp = true; 6240 } 6241 } 6242 6243 // Check whether the next backup agent is in this process... 6244 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6245 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6246 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6247 try { 6248 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6249 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6250 mBackupTarget.backupMode); 6251 } catch (Exception e) { 6252 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6253 badApp = true; 6254 } 6255 } 6256 6257 if (badApp) { 6258 app.kill("error during init", true); 6259 handleAppDiedLocked(app, false, true); 6260 return false; 6261 } 6262 6263 if (!didSomething) { 6264 updateOomAdjLocked(); 6265 } 6266 6267 return true; 6268 } 6269 6270 @Override 6271 public final void attachApplication(IApplicationThread thread) { 6272 synchronized (this) { 6273 int callingPid = Binder.getCallingPid(); 6274 final long origId = Binder.clearCallingIdentity(); 6275 attachApplicationLocked(thread, callingPid); 6276 Binder.restoreCallingIdentity(origId); 6277 } 6278 } 6279 6280 @Override 6281 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6282 final long origId = Binder.clearCallingIdentity(); 6283 synchronized (this) { 6284 ActivityStack stack = ActivityRecord.getStackLocked(token); 6285 if (stack != null) { 6286 ActivityRecord r = 6287 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6288 if (stopProfiling) { 6289 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6290 try { 6291 mProfileFd.close(); 6292 } catch (IOException e) { 6293 } 6294 clearProfilerLocked(); 6295 } 6296 } 6297 } 6298 } 6299 Binder.restoreCallingIdentity(origId); 6300 } 6301 6302 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6303 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6304 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6305 } 6306 6307 void enableScreenAfterBoot() { 6308 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6309 SystemClock.uptimeMillis()); 6310 mWindowManager.enableScreenAfterBoot(); 6311 6312 synchronized (this) { 6313 updateEventDispatchingLocked(); 6314 } 6315 } 6316 6317 @Override 6318 public void showBootMessage(final CharSequence msg, final boolean always) { 6319 enforceNotIsolatedCaller("showBootMessage"); 6320 mWindowManager.showBootMessage(msg, always); 6321 } 6322 6323 @Override 6324 public void keyguardWaitingForActivityDrawn() { 6325 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6326 final long token = Binder.clearCallingIdentity(); 6327 try { 6328 synchronized (this) { 6329 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6330 mWindowManager.keyguardWaitingForActivityDrawn(); 6331 if (mLockScreenShown) { 6332 mLockScreenShown = false; 6333 comeOutOfSleepIfNeededLocked(); 6334 } 6335 } 6336 } finally { 6337 Binder.restoreCallingIdentity(token); 6338 } 6339 } 6340 6341 final void finishBooting() { 6342 synchronized (this) { 6343 if (!mBootAnimationComplete) { 6344 mCallFinishBooting = true; 6345 return; 6346 } 6347 mCallFinishBooting = false; 6348 } 6349 6350 ArraySet<String> completedIsas = new ArraySet<String>(); 6351 for (String abi : Build.SUPPORTED_ABIS) { 6352 Process.establishZygoteConnectionForAbi(abi); 6353 final String instructionSet = VMRuntime.getInstructionSet(abi); 6354 if (!completedIsas.contains(instructionSet)) { 6355 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6356 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6357 } 6358 completedIsas.add(instructionSet); 6359 } 6360 } 6361 6362 // Register receivers to handle package update events 6363 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6364 6365 // Let system services know. 6366 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6367 6368 synchronized (this) { 6369 // Ensure that any processes we had put on hold are now started 6370 // up. 6371 final int NP = mProcessesOnHold.size(); 6372 if (NP > 0) { 6373 ArrayList<ProcessRecord> procs = 6374 new ArrayList<ProcessRecord>(mProcessesOnHold); 6375 for (int ip=0; ip<NP; ip++) { 6376 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6377 + procs.get(ip)); 6378 startProcessLocked(procs.get(ip), "on-hold", null); 6379 } 6380 } 6381 6382 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6383 // Start looking for apps that are abusing wake locks. 6384 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6385 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6386 // Tell anyone interested that we are done booting! 6387 SystemProperties.set("sys.boot_completed", "1"); 6388 6389 // And trigger dev.bootcomplete if we are not showing encryption progress 6390 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6391 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6392 SystemProperties.set("dev.bootcomplete", "1"); 6393 } 6394 for (int i=0; i<mStartedUsers.size(); i++) { 6395 UserStartedState uss = mStartedUsers.valueAt(i); 6396 if (uss.mState == UserStartedState.STATE_BOOTING) { 6397 uss.mState = UserStartedState.STATE_RUNNING; 6398 final int userId = mStartedUsers.keyAt(i); 6399 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6400 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6401 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6402 broadcastIntentLocked(null, null, intent, null, 6403 new IIntentReceiver.Stub() { 6404 @Override 6405 public void performReceive(Intent intent, int resultCode, 6406 String data, Bundle extras, boolean ordered, 6407 boolean sticky, int sendingUser) { 6408 synchronized (ActivityManagerService.this) { 6409 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6410 true, false); 6411 } 6412 } 6413 }, 6414 0, null, null, 6415 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6416 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6417 userId); 6418 } 6419 } 6420 scheduleStartProfilesLocked(); 6421 } 6422 } 6423 } 6424 6425 @Override 6426 public void bootAnimationComplete() { 6427 final boolean callFinishBooting; 6428 synchronized (this) { 6429 callFinishBooting = mCallFinishBooting; 6430 mBootAnimationComplete = true; 6431 } 6432 if (callFinishBooting) { 6433 finishBooting(); 6434 } 6435 } 6436 6437 final void ensureBootCompleted() { 6438 boolean booting; 6439 boolean enableScreen; 6440 synchronized (this) { 6441 booting = mBooting; 6442 mBooting = false; 6443 enableScreen = !mBooted; 6444 mBooted = true; 6445 } 6446 6447 if (booting) { 6448 finishBooting(); 6449 } 6450 6451 if (enableScreen) { 6452 enableScreenAfterBoot(); 6453 } 6454 } 6455 6456 @Override 6457 public final void activityResumed(IBinder token) { 6458 final long origId = Binder.clearCallingIdentity(); 6459 synchronized(this) { 6460 ActivityStack stack = ActivityRecord.getStackLocked(token); 6461 if (stack != null) { 6462 ActivityRecord.activityResumedLocked(token); 6463 } 6464 } 6465 Binder.restoreCallingIdentity(origId); 6466 } 6467 6468 @Override 6469 public final void activityPaused(IBinder token) { 6470 final long origId = Binder.clearCallingIdentity(); 6471 synchronized(this) { 6472 ActivityStack stack = ActivityRecord.getStackLocked(token); 6473 if (stack != null) { 6474 stack.activityPausedLocked(token, false); 6475 } 6476 } 6477 Binder.restoreCallingIdentity(origId); 6478 } 6479 6480 @Override 6481 public final void activityStopped(IBinder token, Bundle icicle, 6482 PersistableBundle persistentState, CharSequence description) { 6483 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6484 6485 // Refuse possible leaked file descriptors 6486 if (icicle != null && icicle.hasFileDescriptors()) { 6487 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6488 } 6489 6490 final long origId = Binder.clearCallingIdentity(); 6491 6492 synchronized (this) { 6493 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6494 if (r != null) { 6495 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6496 } 6497 } 6498 6499 trimApplications(); 6500 6501 Binder.restoreCallingIdentity(origId); 6502 } 6503 6504 @Override 6505 public final void activityDestroyed(IBinder token) { 6506 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6507 synchronized (this) { 6508 ActivityStack stack = ActivityRecord.getStackLocked(token); 6509 if (stack != null) { 6510 stack.activityDestroyedLocked(token); 6511 } 6512 } 6513 } 6514 6515 @Override 6516 public final void backgroundResourcesReleased(IBinder token) { 6517 final long origId = Binder.clearCallingIdentity(); 6518 try { 6519 synchronized (this) { 6520 ActivityStack stack = ActivityRecord.getStackLocked(token); 6521 if (stack != null) { 6522 stack.backgroundResourcesReleased(token); 6523 } 6524 } 6525 } finally { 6526 Binder.restoreCallingIdentity(origId); 6527 } 6528 } 6529 6530 @Override 6531 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6532 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6533 } 6534 6535 @Override 6536 public final void notifyEnterAnimationComplete(IBinder token) { 6537 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6538 } 6539 6540 @Override 6541 public String getCallingPackage(IBinder token) { 6542 synchronized (this) { 6543 ActivityRecord r = getCallingRecordLocked(token); 6544 return r != null ? r.info.packageName : null; 6545 } 6546 } 6547 6548 @Override 6549 public ComponentName getCallingActivity(IBinder token) { 6550 synchronized (this) { 6551 ActivityRecord r = getCallingRecordLocked(token); 6552 return r != null ? r.intent.getComponent() : null; 6553 } 6554 } 6555 6556 private ActivityRecord getCallingRecordLocked(IBinder token) { 6557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6558 if (r == null) { 6559 return null; 6560 } 6561 return r.resultTo; 6562 } 6563 6564 @Override 6565 public ComponentName getActivityClassForToken(IBinder token) { 6566 synchronized(this) { 6567 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6568 if (r == null) { 6569 return null; 6570 } 6571 return r.intent.getComponent(); 6572 } 6573 } 6574 6575 @Override 6576 public String getPackageForToken(IBinder token) { 6577 synchronized(this) { 6578 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6579 if (r == null) { 6580 return null; 6581 } 6582 return r.packageName; 6583 } 6584 } 6585 6586 @Override 6587 public IIntentSender getIntentSender(int type, 6588 String packageName, IBinder token, String resultWho, 6589 int requestCode, Intent[] intents, String[] resolvedTypes, 6590 int flags, Bundle options, int userId) { 6591 enforceNotIsolatedCaller("getIntentSender"); 6592 // Refuse possible leaked file descriptors 6593 if (intents != null) { 6594 if (intents.length < 1) { 6595 throw new IllegalArgumentException("Intents array length must be >= 1"); 6596 } 6597 for (int i=0; i<intents.length; i++) { 6598 Intent intent = intents[i]; 6599 if (intent != null) { 6600 if (intent.hasFileDescriptors()) { 6601 throw new IllegalArgumentException("File descriptors passed in Intent"); 6602 } 6603 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6604 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6605 throw new IllegalArgumentException( 6606 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6607 } 6608 intents[i] = new Intent(intent); 6609 } 6610 } 6611 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6612 throw new IllegalArgumentException( 6613 "Intent array length does not match resolvedTypes length"); 6614 } 6615 } 6616 if (options != null) { 6617 if (options.hasFileDescriptors()) { 6618 throw new IllegalArgumentException("File descriptors passed in options"); 6619 } 6620 } 6621 6622 synchronized(this) { 6623 int callingUid = Binder.getCallingUid(); 6624 int origUserId = userId; 6625 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6626 type == ActivityManager.INTENT_SENDER_BROADCAST, 6627 ALLOW_NON_FULL, "getIntentSender", null); 6628 if (origUserId == UserHandle.USER_CURRENT) { 6629 // We don't want to evaluate this until the pending intent is 6630 // actually executed. However, we do want to always do the 6631 // security checking for it above. 6632 userId = UserHandle.USER_CURRENT; 6633 } 6634 try { 6635 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6636 int uid = AppGlobals.getPackageManager() 6637 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6638 if (!UserHandle.isSameApp(callingUid, uid)) { 6639 String msg = "Permission Denial: getIntentSender() from pid=" 6640 + Binder.getCallingPid() 6641 + ", uid=" + Binder.getCallingUid() 6642 + ", (need uid=" + uid + ")" 6643 + " is not allowed to send as package " + packageName; 6644 Slog.w(TAG, msg); 6645 throw new SecurityException(msg); 6646 } 6647 } 6648 6649 return getIntentSenderLocked(type, packageName, callingUid, userId, 6650 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6651 6652 } catch (RemoteException e) { 6653 throw new SecurityException(e); 6654 } 6655 } 6656 } 6657 6658 IIntentSender getIntentSenderLocked(int type, String packageName, 6659 int callingUid, int userId, IBinder token, String resultWho, 6660 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6661 Bundle options) { 6662 if (DEBUG_MU) 6663 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6664 ActivityRecord activity = null; 6665 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6666 activity = ActivityRecord.isInStackLocked(token); 6667 if (activity == null) { 6668 return null; 6669 } 6670 if (activity.finishing) { 6671 return null; 6672 } 6673 } 6674 6675 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6676 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6677 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6678 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6679 |PendingIntent.FLAG_UPDATE_CURRENT); 6680 6681 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6682 type, packageName, activity, resultWho, 6683 requestCode, intents, resolvedTypes, flags, options, userId); 6684 WeakReference<PendingIntentRecord> ref; 6685 ref = mIntentSenderRecords.get(key); 6686 PendingIntentRecord rec = ref != null ? ref.get() : null; 6687 if (rec != null) { 6688 if (!cancelCurrent) { 6689 if (updateCurrent) { 6690 if (rec.key.requestIntent != null) { 6691 rec.key.requestIntent.replaceExtras(intents != null ? 6692 intents[intents.length - 1] : null); 6693 } 6694 if (intents != null) { 6695 intents[intents.length-1] = rec.key.requestIntent; 6696 rec.key.allIntents = intents; 6697 rec.key.allResolvedTypes = resolvedTypes; 6698 } else { 6699 rec.key.allIntents = null; 6700 rec.key.allResolvedTypes = null; 6701 } 6702 } 6703 return rec; 6704 } 6705 rec.canceled = true; 6706 mIntentSenderRecords.remove(key); 6707 } 6708 if (noCreate) { 6709 return rec; 6710 } 6711 rec = new PendingIntentRecord(this, key, callingUid); 6712 mIntentSenderRecords.put(key, rec.ref); 6713 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6714 if (activity.pendingResults == null) { 6715 activity.pendingResults 6716 = new HashSet<WeakReference<PendingIntentRecord>>(); 6717 } 6718 activity.pendingResults.add(rec.ref); 6719 } 6720 return rec; 6721 } 6722 6723 @Override 6724 public void cancelIntentSender(IIntentSender sender) { 6725 if (!(sender instanceof PendingIntentRecord)) { 6726 return; 6727 } 6728 synchronized(this) { 6729 PendingIntentRecord rec = (PendingIntentRecord)sender; 6730 try { 6731 int uid = AppGlobals.getPackageManager() 6732 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6733 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6734 String msg = "Permission Denial: cancelIntentSender() from pid=" 6735 + Binder.getCallingPid() 6736 + ", uid=" + Binder.getCallingUid() 6737 + " is not allowed to cancel packges " 6738 + rec.key.packageName; 6739 Slog.w(TAG, msg); 6740 throw new SecurityException(msg); 6741 } 6742 } catch (RemoteException e) { 6743 throw new SecurityException(e); 6744 } 6745 cancelIntentSenderLocked(rec, true); 6746 } 6747 } 6748 6749 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6750 rec.canceled = true; 6751 mIntentSenderRecords.remove(rec.key); 6752 if (cleanActivity && rec.key.activity != null) { 6753 rec.key.activity.pendingResults.remove(rec.ref); 6754 } 6755 } 6756 6757 @Override 6758 public String getPackageForIntentSender(IIntentSender pendingResult) { 6759 if (!(pendingResult instanceof PendingIntentRecord)) { 6760 return null; 6761 } 6762 try { 6763 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6764 return res.key.packageName; 6765 } catch (ClassCastException e) { 6766 } 6767 return null; 6768 } 6769 6770 @Override 6771 public int getUidForIntentSender(IIntentSender sender) { 6772 if (sender instanceof PendingIntentRecord) { 6773 try { 6774 PendingIntentRecord res = (PendingIntentRecord)sender; 6775 return res.uid; 6776 } catch (ClassCastException e) { 6777 } 6778 } 6779 return -1; 6780 } 6781 6782 @Override 6783 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6784 if (!(pendingResult instanceof PendingIntentRecord)) { 6785 return false; 6786 } 6787 try { 6788 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6789 if (res.key.allIntents == null) { 6790 return false; 6791 } 6792 for (int i=0; i<res.key.allIntents.length; i++) { 6793 Intent intent = res.key.allIntents[i]; 6794 if (intent.getPackage() != null && intent.getComponent() != null) { 6795 return false; 6796 } 6797 } 6798 return true; 6799 } catch (ClassCastException e) { 6800 } 6801 return false; 6802 } 6803 6804 @Override 6805 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6806 if (!(pendingResult instanceof PendingIntentRecord)) { 6807 return false; 6808 } 6809 try { 6810 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6811 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6812 return true; 6813 } 6814 return false; 6815 } catch (ClassCastException e) { 6816 } 6817 return false; 6818 } 6819 6820 @Override 6821 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6822 if (!(pendingResult instanceof PendingIntentRecord)) { 6823 return null; 6824 } 6825 try { 6826 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6827 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6828 } catch (ClassCastException e) { 6829 } 6830 return null; 6831 } 6832 6833 @Override 6834 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6835 if (!(pendingResult instanceof PendingIntentRecord)) { 6836 return null; 6837 } 6838 try { 6839 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6840 Intent intent = res.key.requestIntent; 6841 if (intent != null) { 6842 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6843 || res.lastTagPrefix.equals(prefix))) { 6844 return res.lastTag; 6845 } 6846 res.lastTagPrefix = prefix; 6847 StringBuilder sb = new StringBuilder(128); 6848 if (prefix != null) { 6849 sb.append(prefix); 6850 } 6851 if (intent.getAction() != null) { 6852 sb.append(intent.getAction()); 6853 } else if (intent.getComponent() != null) { 6854 intent.getComponent().appendShortString(sb); 6855 } else { 6856 sb.append("?"); 6857 } 6858 return res.lastTag = sb.toString(); 6859 } 6860 } catch (ClassCastException e) { 6861 } 6862 return null; 6863 } 6864 6865 @Override 6866 public void setProcessLimit(int max) { 6867 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6868 "setProcessLimit()"); 6869 synchronized (this) { 6870 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6871 mProcessLimitOverride = max; 6872 } 6873 trimApplications(); 6874 } 6875 6876 @Override 6877 public int getProcessLimit() { 6878 synchronized (this) { 6879 return mProcessLimitOverride; 6880 } 6881 } 6882 6883 void foregroundTokenDied(ForegroundToken token) { 6884 synchronized (ActivityManagerService.this) { 6885 synchronized (mPidsSelfLocked) { 6886 ForegroundToken cur 6887 = mForegroundProcesses.get(token.pid); 6888 if (cur != token) { 6889 return; 6890 } 6891 mForegroundProcesses.remove(token.pid); 6892 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6893 if (pr == null) { 6894 return; 6895 } 6896 pr.forcingToForeground = null; 6897 updateProcessForegroundLocked(pr, false, false); 6898 } 6899 updateOomAdjLocked(); 6900 } 6901 } 6902 6903 @Override 6904 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6905 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6906 "setProcessForeground()"); 6907 synchronized(this) { 6908 boolean changed = false; 6909 6910 synchronized (mPidsSelfLocked) { 6911 ProcessRecord pr = mPidsSelfLocked.get(pid); 6912 if (pr == null && isForeground) { 6913 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6914 return; 6915 } 6916 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6917 if (oldToken != null) { 6918 oldToken.token.unlinkToDeath(oldToken, 0); 6919 mForegroundProcesses.remove(pid); 6920 if (pr != null) { 6921 pr.forcingToForeground = null; 6922 } 6923 changed = true; 6924 } 6925 if (isForeground && token != null) { 6926 ForegroundToken newToken = new ForegroundToken() { 6927 @Override 6928 public void binderDied() { 6929 foregroundTokenDied(this); 6930 } 6931 }; 6932 newToken.pid = pid; 6933 newToken.token = token; 6934 try { 6935 token.linkToDeath(newToken, 0); 6936 mForegroundProcesses.put(pid, newToken); 6937 pr.forcingToForeground = token; 6938 changed = true; 6939 } catch (RemoteException e) { 6940 // If the process died while doing this, we will later 6941 // do the cleanup with the process death link. 6942 } 6943 } 6944 } 6945 6946 if (changed) { 6947 updateOomAdjLocked(); 6948 } 6949 } 6950 } 6951 6952 // ========================================================= 6953 // PERMISSIONS 6954 // ========================================================= 6955 6956 static class PermissionController extends IPermissionController.Stub { 6957 ActivityManagerService mActivityManagerService; 6958 PermissionController(ActivityManagerService activityManagerService) { 6959 mActivityManagerService = activityManagerService; 6960 } 6961 6962 @Override 6963 public boolean checkPermission(String permission, int pid, int uid) { 6964 return mActivityManagerService.checkPermission(permission, pid, 6965 uid) == PackageManager.PERMISSION_GRANTED; 6966 } 6967 } 6968 6969 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6970 @Override 6971 public int checkComponentPermission(String permission, int pid, int uid, 6972 int owningUid, boolean exported) { 6973 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6974 owningUid, exported); 6975 } 6976 6977 @Override 6978 public Object getAMSLock() { 6979 return ActivityManagerService.this; 6980 } 6981 } 6982 6983 /** 6984 * This can be called with or without the global lock held. 6985 */ 6986 int checkComponentPermission(String permission, int pid, int uid, 6987 int owningUid, boolean exported) { 6988 // We might be performing an operation on behalf of an indirect binder 6989 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6990 // client identity accordingly before proceeding. 6991 Identity tlsIdentity = sCallerIdentity.get(); 6992 if (tlsIdentity != null) { 6993 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6994 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6995 uid = tlsIdentity.uid; 6996 pid = tlsIdentity.pid; 6997 } 6998 6999 if (pid == MY_PID) { 7000 return PackageManager.PERMISSION_GRANTED; 7001 } 7002 7003 return ActivityManager.checkComponentPermission(permission, uid, 7004 owningUid, exported); 7005 } 7006 7007 /** 7008 * As the only public entry point for permissions checking, this method 7009 * can enforce the semantic that requesting a check on a null global 7010 * permission is automatically denied. (Internally a null permission 7011 * string is used when calling {@link #checkComponentPermission} in cases 7012 * when only uid-based security is needed.) 7013 * 7014 * This can be called with or without the global lock held. 7015 */ 7016 @Override 7017 public int checkPermission(String permission, int pid, int uid) { 7018 if (permission == null) { 7019 return PackageManager.PERMISSION_DENIED; 7020 } 7021 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 7022 } 7023 7024 /** 7025 * Binder IPC calls go through the public entry point. 7026 * This can be called with or without the global lock held. 7027 */ 7028 int checkCallingPermission(String permission) { 7029 return checkPermission(permission, 7030 Binder.getCallingPid(), 7031 UserHandle.getAppId(Binder.getCallingUid())); 7032 } 7033 7034 /** 7035 * This can be called with or without the global lock held. 7036 */ 7037 void enforceCallingPermission(String permission, String func) { 7038 if (checkCallingPermission(permission) 7039 == PackageManager.PERMISSION_GRANTED) { 7040 return; 7041 } 7042 7043 String msg = "Permission Denial: " + func + " from pid=" 7044 + Binder.getCallingPid() 7045 + ", uid=" + Binder.getCallingUid() 7046 + " requires " + permission; 7047 Slog.w(TAG, msg); 7048 throw new SecurityException(msg); 7049 } 7050 7051 /** 7052 * Determine if UID is holding permissions required to access {@link Uri} in 7053 * the given {@link ProviderInfo}. Final permission checking is always done 7054 * in {@link ContentProvider}. 7055 */ 7056 private final boolean checkHoldingPermissionsLocked( 7057 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 7058 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7059 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 7060 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 7061 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 7062 != PERMISSION_GRANTED) { 7063 return false; 7064 } 7065 } 7066 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 7067 } 7068 7069 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 7070 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 7071 if (pi.applicationInfo.uid == uid) { 7072 return true; 7073 } else if (!pi.exported) { 7074 return false; 7075 } 7076 7077 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7078 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7079 try { 7080 // check if target holds top-level <provider> permissions 7081 if (!readMet && pi.readPermission != null && considerUidPermissions 7082 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7083 readMet = true; 7084 } 7085 if (!writeMet && pi.writePermission != null && considerUidPermissions 7086 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7087 writeMet = true; 7088 } 7089 7090 // track if unprotected read/write is allowed; any denied 7091 // <path-permission> below removes this ability 7092 boolean allowDefaultRead = pi.readPermission == null; 7093 boolean allowDefaultWrite = pi.writePermission == null; 7094 7095 // check if target holds any <path-permission> that match uri 7096 final PathPermission[] pps = pi.pathPermissions; 7097 if (pps != null) { 7098 final String path = grantUri.uri.getPath(); 7099 int i = pps.length; 7100 while (i > 0 && (!readMet || !writeMet)) { 7101 i--; 7102 PathPermission pp = pps[i]; 7103 if (pp.match(path)) { 7104 if (!readMet) { 7105 final String pprperm = pp.getReadPermission(); 7106 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7107 + pprperm + " for " + pp.getPath() 7108 + ": match=" + pp.match(path) 7109 + " check=" + pm.checkUidPermission(pprperm, uid)); 7110 if (pprperm != null) { 7111 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7112 == PERMISSION_GRANTED) { 7113 readMet = true; 7114 } else { 7115 allowDefaultRead = false; 7116 } 7117 } 7118 } 7119 if (!writeMet) { 7120 final String ppwperm = pp.getWritePermission(); 7121 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7122 + ppwperm + " for " + pp.getPath() 7123 + ": match=" + pp.match(path) 7124 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7125 if (ppwperm != null) { 7126 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7127 == PERMISSION_GRANTED) { 7128 writeMet = true; 7129 } else { 7130 allowDefaultWrite = false; 7131 } 7132 } 7133 } 7134 } 7135 } 7136 } 7137 7138 // grant unprotected <provider> read/write, if not blocked by 7139 // <path-permission> above 7140 if (allowDefaultRead) readMet = true; 7141 if (allowDefaultWrite) writeMet = true; 7142 7143 } catch (RemoteException e) { 7144 return false; 7145 } 7146 7147 return readMet && writeMet; 7148 } 7149 7150 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7151 ProviderInfo pi = null; 7152 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7153 if (cpr != null) { 7154 pi = cpr.info; 7155 } else { 7156 try { 7157 pi = AppGlobals.getPackageManager().resolveContentProvider( 7158 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7159 } catch (RemoteException ex) { 7160 } 7161 } 7162 return pi; 7163 } 7164 7165 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7166 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7167 if (targetUris != null) { 7168 return targetUris.get(grantUri); 7169 } 7170 return null; 7171 } 7172 7173 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7174 String targetPkg, int targetUid, GrantUri grantUri) { 7175 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7176 if (targetUris == null) { 7177 targetUris = Maps.newArrayMap(); 7178 mGrantedUriPermissions.put(targetUid, targetUris); 7179 } 7180 7181 UriPermission perm = targetUris.get(grantUri); 7182 if (perm == null) { 7183 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7184 targetUris.put(grantUri, perm); 7185 } 7186 7187 return perm; 7188 } 7189 7190 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7191 final int modeFlags) { 7192 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7193 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7194 : UriPermission.STRENGTH_OWNED; 7195 7196 // Root gets to do everything. 7197 if (uid == 0) { 7198 return true; 7199 } 7200 7201 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7202 if (perms == null) return false; 7203 7204 // First look for exact match 7205 final UriPermission exactPerm = perms.get(grantUri); 7206 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7207 return true; 7208 } 7209 7210 // No exact match, look for prefixes 7211 final int N = perms.size(); 7212 for (int i = 0; i < N; i++) { 7213 final UriPermission perm = perms.valueAt(i); 7214 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7215 && perm.getStrength(modeFlags) >= minStrength) { 7216 return true; 7217 } 7218 } 7219 7220 return false; 7221 } 7222 7223 /** 7224 * @param uri This uri must NOT contain an embedded userId. 7225 * @param userId The userId in which the uri is to be resolved. 7226 */ 7227 @Override 7228 public int checkUriPermission(Uri uri, int pid, int uid, 7229 final int modeFlags, int userId) { 7230 enforceNotIsolatedCaller("checkUriPermission"); 7231 7232 // Another redirected-binder-call permissions check as in 7233 // {@link checkComponentPermission}. 7234 Identity tlsIdentity = sCallerIdentity.get(); 7235 if (tlsIdentity != null) { 7236 uid = tlsIdentity.uid; 7237 pid = tlsIdentity.pid; 7238 } 7239 7240 // Our own process gets to do everything. 7241 if (pid == MY_PID) { 7242 return PackageManager.PERMISSION_GRANTED; 7243 } 7244 synchronized (this) { 7245 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7246 ? PackageManager.PERMISSION_GRANTED 7247 : PackageManager.PERMISSION_DENIED; 7248 } 7249 } 7250 7251 /** 7252 * Check if the targetPkg can be granted permission to access uri by 7253 * the callingUid using the given modeFlags. Throws a security exception 7254 * if callingUid is not allowed to do this. Returns the uid of the target 7255 * if the URI permission grant should be performed; returns -1 if it is not 7256 * needed (for example targetPkg already has permission to access the URI). 7257 * If you already know the uid of the target, you can supply it in 7258 * lastTargetUid else set that to -1. 7259 */ 7260 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7261 final int modeFlags, int lastTargetUid) { 7262 if (!Intent.isAccessUriMode(modeFlags)) { 7263 return -1; 7264 } 7265 7266 if (targetPkg != null) { 7267 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7268 "Checking grant " + targetPkg + " permission to " + grantUri); 7269 } 7270 7271 final IPackageManager pm = AppGlobals.getPackageManager(); 7272 7273 // If this is not a content: uri, we can't do anything with it. 7274 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7275 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7276 "Can't grant URI permission for non-content URI: " + grantUri); 7277 return -1; 7278 } 7279 7280 final String authority = grantUri.uri.getAuthority(); 7281 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7282 if (pi == null) { 7283 Slog.w(TAG, "No content provider found for permission check: " + 7284 grantUri.uri.toSafeString()); 7285 return -1; 7286 } 7287 7288 int targetUid = lastTargetUid; 7289 if (targetUid < 0 && targetPkg != null) { 7290 try { 7291 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7292 if (targetUid < 0) { 7293 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7294 "Can't grant URI permission no uid for: " + targetPkg); 7295 return -1; 7296 } 7297 } catch (RemoteException ex) { 7298 return -1; 7299 } 7300 } 7301 7302 if (targetUid >= 0) { 7303 // First... does the target actually need this permission? 7304 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7305 // No need to grant the target this permission. 7306 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7307 "Target " + targetPkg + " already has full permission to " + grantUri); 7308 return -1; 7309 } 7310 } else { 7311 // First... there is no target package, so can anyone access it? 7312 boolean allowed = pi.exported; 7313 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7314 if (pi.readPermission != null) { 7315 allowed = false; 7316 } 7317 } 7318 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7319 if (pi.writePermission != null) { 7320 allowed = false; 7321 } 7322 } 7323 if (allowed) { 7324 return -1; 7325 } 7326 } 7327 7328 /* There is a special cross user grant if: 7329 * - The target is on another user. 7330 * - Apps on the current user can access the uri without any uid permissions. 7331 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7332 * grant uri permissions. 7333 */ 7334 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7335 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7336 modeFlags, false /*without considering the uid permissions*/); 7337 7338 // Second... is the provider allowing granting of URI permissions? 7339 if (!specialCrossUserGrant) { 7340 if (!pi.grantUriPermissions) { 7341 throw new SecurityException("Provider " + pi.packageName 7342 + "/" + pi.name 7343 + " does not allow granting of Uri permissions (uri " 7344 + grantUri + ")"); 7345 } 7346 if (pi.uriPermissionPatterns != null) { 7347 final int N = pi.uriPermissionPatterns.length; 7348 boolean allowed = false; 7349 for (int i=0; i<N; i++) { 7350 if (pi.uriPermissionPatterns[i] != null 7351 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7352 allowed = true; 7353 break; 7354 } 7355 } 7356 if (!allowed) { 7357 throw new SecurityException("Provider " + pi.packageName 7358 + "/" + pi.name 7359 + " does not allow granting of permission to path of Uri " 7360 + grantUri); 7361 } 7362 } 7363 } 7364 7365 // Third... does the caller itself have permission to access 7366 // this uri? 7367 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7368 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7369 // Require they hold a strong enough Uri permission 7370 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7371 throw new SecurityException("Uid " + callingUid 7372 + " does not have permission to uri " + grantUri); 7373 } 7374 } 7375 } 7376 return targetUid; 7377 } 7378 7379 /** 7380 * @param uri This uri must NOT contain an embedded userId. 7381 * @param userId The userId in which the uri is to be resolved. 7382 */ 7383 @Override 7384 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7385 final int modeFlags, int userId) { 7386 enforceNotIsolatedCaller("checkGrantUriPermission"); 7387 synchronized(this) { 7388 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7389 new GrantUri(userId, uri, false), modeFlags, -1); 7390 } 7391 } 7392 7393 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7394 final int modeFlags, UriPermissionOwner owner) { 7395 if (!Intent.isAccessUriMode(modeFlags)) { 7396 return; 7397 } 7398 7399 // So here we are: the caller has the assumed permission 7400 // to the uri, and the target doesn't. Let's now give this to 7401 // the target. 7402 7403 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7404 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7405 7406 final String authority = grantUri.uri.getAuthority(); 7407 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7408 if (pi == null) { 7409 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7410 return; 7411 } 7412 7413 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7414 grantUri.prefix = true; 7415 } 7416 final UriPermission perm = findOrCreateUriPermissionLocked( 7417 pi.packageName, targetPkg, targetUid, grantUri); 7418 perm.grantModes(modeFlags, owner); 7419 } 7420 7421 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7422 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7423 if (targetPkg == null) { 7424 throw new NullPointerException("targetPkg"); 7425 } 7426 int targetUid; 7427 final IPackageManager pm = AppGlobals.getPackageManager(); 7428 try { 7429 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7430 } catch (RemoteException ex) { 7431 return; 7432 } 7433 7434 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7435 targetUid); 7436 if (targetUid < 0) { 7437 return; 7438 } 7439 7440 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7441 owner); 7442 } 7443 7444 static class NeededUriGrants extends ArrayList<GrantUri> { 7445 final String targetPkg; 7446 final int targetUid; 7447 final int flags; 7448 7449 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7450 this.targetPkg = targetPkg; 7451 this.targetUid = targetUid; 7452 this.flags = flags; 7453 } 7454 } 7455 7456 /** 7457 * Like checkGrantUriPermissionLocked, but takes an Intent. 7458 */ 7459 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7460 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7461 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7462 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7463 + " clip=" + (intent != null ? intent.getClipData() : null) 7464 + " from " + intent + "; flags=0x" 7465 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7466 7467 if (targetPkg == null) { 7468 throw new NullPointerException("targetPkg"); 7469 } 7470 7471 if (intent == null) { 7472 return null; 7473 } 7474 Uri data = intent.getData(); 7475 ClipData clip = intent.getClipData(); 7476 if (data == null && clip == null) { 7477 return null; 7478 } 7479 // Default userId for uris in the intent (if they don't specify it themselves) 7480 int contentUserHint = intent.getContentUserHint(); 7481 if (contentUserHint == UserHandle.USER_CURRENT) { 7482 contentUserHint = UserHandle.getUserId(callingUid); 7483 } 7484 final IPackageManager pm = AppGlobals.getPackageManager(); 7485 int targetUid; 7486 if (needed != null) { 7487 targetUid = needed.targetUid; 7488 } else { 7489 try { 7490 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7491 } catch (RemoteException ex) { 7492 return null; 7493 } 7494 if (targetUid < 0) { 7495 if (DEBUG_URI_PERMISSION) { 7496 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7497 + " on user " + targetUserId); 7498 } 7499 return null; 7500 } 7501 } 7502 if (data != null) { 7503 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7504 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7505 targetUid); 7506 if (targetUid > 0) { 7507 if (needed == null) { 7508 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7509 } 7510 needed.add(grantUri); 7511 } 7512 } 7513 if (clip != null) { 7514 for (int i=0; i<clip.getItemCount(); i++) { 7515 Uri uri = clip.getItemAt(i).getUri(); 7516 if (uri != null) { 7517 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7518 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7519 targetUid); 7520 if (targetUid > 0) { 7521 if (needed == null) { 7522 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7523 } 7524 needed.add(grantUri); 7525 } 7526 } else { 7527 Intent clipIntent = clip.getItemAt(i).getIntent(); 7528 if (clipIntent != null) { 7529 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7530 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7531 if (newNeeded != null) { 7532 needed = newNeeded; 7533 } 7534 } 7535 } 7536 } 7537 } 7538 7539 return needed; 7540 } 7541 7542 /** 7543 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7544 */ 7545 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7546 UriPermissionOwner owner) { 7547 if (needed != null) { 7548 for (int i=0; i<needed.size(); i++) { 7549 GrantUri grantUri = needed.get(i); 7550 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7551 grantUri, needed.flags, owner); 7552 } 7553 } 7554 } 7555 7556 void grantUriPermissionFromIntentLocked(int callingUid, 7557 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7558 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7559 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7560 if (needed == null) { 7561 return; 7562 } 7563 7564 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7565 } 7566 7567 /** 7568 * @param uri This uri must NOT contain an embedded userId. 7569 * @param userId The userId in which the uri is to be resolved. 7570 */ 7571 @Override 7572 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7573 final int modeFlags, int userId) { 7574 enforceNotIsolatedCaller("grantUriPermission"); 7575 GrantUri grantUri = new GrantUri(userId, uri, false); 7576 synchronized(this) { 7577 final ProcessRecord r = getRecordForAppLocked(caller); 7578 if (r == null) { 7579 throw new SecurityException("Unable to find app for caller " 7580 + caller 7581 + " when granting permission to uri " + grantUri); 7582 } 7583 if (targetPkg == null) { 7584 throw new IllegalArgumentException("null target"); 7585 } 7586 if (grantUri == null) { 7587 throw new IllegalArgumentException("null uri"); 7588 } 7589 7590 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7591 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7592 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7593 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7594 7595 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7596 UserHandle.getUserId(r.uid)); 7597 } 7598 } 7599 7600 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7601 if (perm.modeFlags == 0) { 7602 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7603 perm.targetUid); 7604 if (perms != null) { 7605 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7606 "Removing " + perm.targetUid + " permission to " + perm.uri); 7607 7608 perms.remove(perm.uri); 7609 if (perms.isEmpty()) { 7610 mGrantedUriPermissions.remove(perm.targetUid); 7611 } 7612 } 7613 } 7614 } 7615 7616 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7617 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7618 7619 final IPackageManager pm = AppGlobals.getPackageManager(); 7620 final String authority = grantUri.uri.getAuthority(); 7621 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7622 if (pi == null) { 7623 Slog.w(TAG, "No content provider found for permission revoke: " 7624 + grantUri.toSafeString()); 7625 return; 7626 } 7627 7628 // Does the caller have this permission on the URI? 7629 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7630 // If they don't have direct access to the URI, then revoke any 7631 // ownerless URI permissions that have been granted to them. 7632 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7633 if (perms != null) { 7634 boolean persistChanged = false; 7635 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7636 final UriPermission perm = it.next(); 7637 if (perm.uri.sourceUserId == grantUri.sourceUserId 7638 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7639 if (DEBUG_URI_PERMISSION) 7640 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7641 " permission to " + perm.uri); 7642 persistChanged |= perm.revokeModes( 7643 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7644 if (perm.modeFlags == 0) { 7645 it.remove(); 7646 } 7647 } 7648 } 7649 if (perms.isEmpty()) { 7650 mGrantedUriPermissions.remove(callingUid); 7651 } 7652 if (persistChanged) { 7653 schedulePersistUriGrants(); 7654 } 7655 } 7656 return; 7657 } 7658 7659 boolean persistChanged = false; 7660 7661 // Go through all of the permissions and remove any that match. 7662 int N = mGrantedUriPermissions.size(); 7663 for (int i = 0; i < N; i++) { 7664 final int targetUid = mGrantedUriPermissions.keyAt(i); 7665 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7666 7667 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7668 final UriPermission perm = it.next(); 7669 if (perm.uri.sourceUserId == grantUri.sourceUserId 7670 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7671 if (DEBUG_URI_PERMISSION) 7672 Slog.v(TAG, 7673 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7674 persistChanged |= perm.revokeModes( 7675 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7676 if (perm.modeFlags == 0) { 7677 it.remove(); 7678 } 7679 } 7680 } 7681 7682 if (perms.isEmpty()) { 7683 mGrantedUriPermissions.remove(targetUid); 7684 N--; 7685 i--; 7686 } 7687 } 7688 7689 if (persistChanged) { 7690 schedulePersistUriGrants(); 7691 } 7692 } 7693 7694 /** 7695 * @param uri This uri must NOT contain an embedded userId. 7696 * @param userId The userId in which the uri is to be resolved. 7697 */ 7698 @Override 7699 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7700 int userId) { 7701 enforceNotIsolatedCaller("revokeUriPermission"); 7702 synchronized(this) { 7703 final ProcessRecord r = getRecordForAppLocked(caller); 7704 if (r == null) { 7705 throw new SecurityException("Unable to find app for caller " 7706 + caller 7707 + " when revoking permission to uri " + uri); 7708 } 7709 if (uri == null) { 7710 Slog.w(TAG, "revokeUriPermission: null uri"); 7711 return; 7712 } 7713 7714 if (!Intent.isAccessUriMode(modeFlags)) { 7715 return; 7716 } 7717 7718 final IPackageManager pm = AppGlobals.getPackageManager(); 7719 final String authority = uri.getAuthority(); 7720 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7721 if (pi == null) { 7722 Slog.w(TAG, "No content provider found for permission revoke: " 7723 + uri.toSafeString()); 7724 return; 7725 } 7726 7727 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7728 } 7729 } 7730 7731 /** 7732 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7733 * given package. 7734 * 7735 * @param packageName Package name to match, or {@code null} to apply to all 7736 * packages. 7737 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7738 * to all users. 7739 * @param persistable If persistable grants should be removed. 7740 */ 7741 private void removeUriPermissionsForPackageLocked( 7742 String packageName, int userHandle, boolean persistable) { 7743 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7744 throw new IllegalArgumentException("Must narrow by either package or user"); 7745 } 7746 7747 boolean persistChanged = false; 7748 7749 int N = mGrantedUriPermissions.size(); 7750 for (int i = 0; i < N; i++) { 7751 final int targetUid = mGrantedUriPermissions.keyAt(i); 7752 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7753 7754 // Only inspect grants matching user 7755 if (userHandle == UserHandle.USER_ALL 7756 || userHandle == UserHandle.getUserId(targetUid)) { 7757 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7758 final UriPermission perm = it.next(); 7759 7760 // Only inspect grants matching package 7761 if (packageName == null || perm.sourcePkg.equals(packageName) 7762 || perm.targetPkg.equals(packageName)) { 7763 persistChanged |= perm.revokeModes(persistable 7764 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7765 7766 // Only remove when no modes remain; any persisted grants 7767 // will keep this alive. 7768 if (perm.modeFlags == 0) { 7769 it.remove(); 7770 } 7771 } 7772 } 7773 7774 if (perms.isEmpty()) { 7775 mGrantedUriPermissions.remove(targetUid); 7776 N--; 7777 i--; 7778 } 7779 } 7780 } 7781 7782 if (persistChanged) { 7783 schedulePersistUriGrants(); 7784 } 7785 } 7786 7787 @Override 7788 public IBinder newUriPermissionOwner(String name) { 7789 enforceNotIsolatedCaller("newUriPermissionOwner"); 7790 synchronized(this) { 7791 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7792 return owner.getExternalTokenLocked(); 7793 } 7794 } 7795 7796 /** 7797 * @param uri This uri must NOT contain an embedded userId. 7798 * @param sourceUserId The userId in which the uri is to be resolved. 7799 * @param targetUserId The userId of the app that receives the grant. 7800 */ 7801 @Override 7802 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7803 final int modeFlags, int sourceUserId, int targetUserId) { 7804 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7805 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7806 synchronized(this) { 7807 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7808 if (owner == null) { 7809 throw new IllegalArgumentException("Unknown owner: " + token); 7810 } 7811 if (fromUid != Binder.getCallingUid()) { 7812 if (Binder.getCallingUid() != Process.myUid()) { 7813 // Only system code can grant URI permissions on behalf 7814 // of other users. 7815 throw new SecurityException("nice try"); 7816 } 7817 } 7818 if (targetPkg == null) { 7819 throw new IllegalArgumentException("null target"); 7820 } 7821 if (uri == null) { 7822 throw new IllegalArgumentException("null uri"); 7823 } 7824 7825 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7826 modeFlags, owner, targetUserId); 7827 } 7828 } 7829 7830 /** 7831 * @param uri This uri must NOT contain an embedded userId. 7832 * @param userId The userId in which the uri is to be resolved. 7833 */ 7834 @Override 7835 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7836 synchronized(this) { 7837 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7838 if (owner == null) { 7839 throw new IllegalArgumentException("Unknown owner: " + token); 7840 } 7841 7842 if (uri == null) { 7843 owner.removeUriPermissionsLocked(mode); 7844 } else { 7845 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7846 } 7847 } 7848 } 7849 7850 private void schedulePersistUriGrants() { 7851 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7852 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7853 10 * DateUtils.SECOND_IN_MILLIS); 7854 } 7855 } 7856 7857 private void writeGrantedUriPermissions() { 7858 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7859 7860 // Snapshot permissions so we can persist without lock 7861 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7862 synchronized (this) { 7863 final int size = mGrantedUriPermissions.size(); 7864 for (int i = 0; i < size; i++) { 7865 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7866 for (UriPermission perm : perms.values()) { 7867 if (perm.persistedModeFlags != 0) { 7868 persist.add(perm.snapshot()); 7869 } 7870 } 7871 } 7872 } 7873 7874 FileOutputStream fos = null; 7875 try { 7876 fos = mGrantFile.startWrite(); 7877 7878 XmlSerializer out = new FastXmlSerializer(); 7879 out.setOutput(fos, "utf-8"); 7880 out.startDocument(null, true); 7881 out.startTag(null, TAG_URI_GRANTS); 7882 for (UriPermission.Snapshot perm : persist) { 7883 out.startTag(null, TAG_URI_GRANT); 7884 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7885 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7886 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7887 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7888 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7889 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7890 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7891 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7892 out.endTag(null, TAG_URI_GRANT); 7893 } 7894 out.endTag(null, TAG_URI_GRANTS); 7895 out.endDocument(); 7896 7897 mGrantFile.finishWrite(fos); 7898 } catch (IOException e) { 7899 if (fos != null) { 7900 mGrantFile.failWrite(fos); 7901 } 7902 } 7903 } 7904 7905 private void readGrantedUriPermissionsLocked() { 7906 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7907 7908 final long now = System.currentTimeMillis(); 7909 7910 FileInputStream fis = null; 7911 try { 7912 fis = mGrantFile.openRead(); 7913 final XmlPullParser in = Xml.newPullParser(); 7914 in.setInput(fis, null); 7915 7916 int type; 7917 while ((type = in.next()) != END_DOCUMENT) { 7918 final String tag = in.getName(); 7919 if (type == START_TAG) { 7920 if (TAG_URI_GRANT.equals(tag)) { 7921 final int sourceUserId; 7922 final int targetUserId; 7923 final int userHandle = readIntAttribute(in, 7924 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7925 if (userHandle != UserHandle.USER_NULL) { 7926 // For backwards compatibility. 7927 sourceUserId = userHandle; 7928 targetUserId = userHandle; 7929 } else { 7930 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7931 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7932 } 7933 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7934 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7935 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7936 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7937 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7938 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7939 7940 // Sanity check that provider still belongs to source package 7941 final ProviderInfo pi = getProviderInfoLocked( 7942 uri.getAuthority(), sourceUserId); 7943 if (pi != null && sourcePkg.equals(pi.packageName)) { 7944 int targetUid = -1; 7945 try { 7946 targetUid = AppGlobals.getPackageManager() 7947 .getPackageUid(targetPkg, targetUserId); 7948 } catch (RemoteException e) { 7949 } 7950 if (targetUid != -1) { 7951 final UriPermission perm = findOrCreateUriPermissionLocked( 7952 sourcePkg, targetPkg, targetUid, 7953 new GrantUri(sourceUserId, uri, prefix)); 7954 perm.initPersistedModes(modeFlags, createdTime); 7955 } 7956 } else { 7957 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7958 + " but instead found " + pi); 7959 } 7960 } 7961 } 7962 } 7963 } catch (FileNotFoundException e) { 7964 // Missing grants is okay 7965 } catch (IOException e) { 7966 Slog.wtf(TAG, "Failed reading Uri grants", e); 7967 } catch (XmlPullParserException e) { 7968 Slog.wtf(TAG, "Failed reading Uri grants", e); 7969 } finally { 7970 IoUtils.closeQuietly(fis); 7971 } 7972 } 7973 7974 /** 7975 * @param uri This uri must NOT contain an embedded userId. 7976 * @param userId The userId in which the uri is to be resolved. 7977 */ 7978 @Override 7979 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7980 enforceNotIsolatedCaller("takePersistableUriPermission"); 7981 7982 Preconditions.checkFlagsArgument(modeFlags, 7983 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7984 7985 synchronized (this) { 7986 final int callingUid = Binder.getCallingUid(); 7987 boolean persistChanged = false; 7988 GrantUri grantUri = new GrantUri(userId, uri, false); 7989 7990 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7991 new GrantUri(userId, uri, false)); 7992 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7993 new GrantUri(userId, uri, true)); 7994 7995 final boolean exactValid = (exactPerm != null) 7996 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7997 final boolean prefixValid = (prefixPerm != null) 7998 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7999 8000 if (!(exactValid || prefixValid)) { 8001 throw new SecurityException("No persistable permission grants found for UID " 8002 + callingUid + " and Uri " + grantUri.toSafeString()); 8003 } 8004 8005 if (exactValid) { 8006 persistChanged |= exactPerm.takePersistableModes(modeFlags); 8007 } 8008 if (prefixValid) { 8009 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 8010 } 8011 8012 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 8013 8014 if (persistChanged) { 8015 schedulePersistUriGrants(); 8016 } 8017 } 8018 } 8019 8020 /** 8021 * @param uri This uri must NOT contain an embedded userId. 8022 * @param userId The userId in which the uri is to be resolved. 8023 */ 8024 @Override 8025 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 8026 enforceNotIsolatedCaller("releasePersistableUriPermission"); 8027 8028 Preconditions.checkFlagsArgument(modeFlags, 8029 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 8030 8031 synchronized (this) { 8032 final int callingUid = Binder.getCallingUid(); 8033 boolean persistChanged = false; 8034 8035 UriPermission exactPerm = findUriPermissionLocked(callingUid, 8036 new GrantUri(userId, uri, false)); 8037 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 8038 new GrantUri(userId, uri, true)); 8039 if (exactPerm == null && prefixPerm == null) { 8040 throw new SecurityException("No permission grants found for UID " + callingUid 8041 + " and Uri " + uri.toSafeString()); 8042 } 8043 8044 if (exactPerm != null) { 8045 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 8046 removeUriPermissionIfNeededLocked(exactPerm); 8047 } 8048 if (prefixPerm != null) { 8049 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 8050 removeUriPermissionIfNeededLocked(prefixPerm); 8051 } 8052 8053 if (persistChanged) { 8054 schedulePersistUriGrants(); 8055 } 8056 } 8057 } 8058 8059 /** 8060 * Prune any older {@link UriPermission} for the given UID until outstanding 8061 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 8062 * 8063 * @return if any mutations occured that require persisting. 8064 */ 8065 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 8066 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8067 if (perms == null) return false; 8068 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 8069 8070 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 8071 for (UriPermission perm : perms.values()) { 8072 if (perm.persistedModeFlags != 0) { 8073 persisted.add(perm); 8074 } 8075 } 8076 8077 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8078 if (trimCount <= 0) return false; 8079 8080 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8081 for (int i = 0; i < trimCount; i++) { 8082 final UriPermission perm = persisted.get(i); 8083 8084 if (DEBUG_URI_PERMISSION) { 8085 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8086 } 8087 8088 perm.releasePersistableModes(~0); 8089 removeUriPermissionIfNeededLocked(perm); 8090 } 8091 8092 return true; 8093 } 8094 8095 @Override 8096 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8097 String packageName, boolean incoming) { 8098 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8099 Preconditions.checkNotNull(packageName, "packageName"); 8100 8101 final int callingUid = Binder.getCallingUid(); 8102 final IPackageManager pm = AppGlobals.getPackageManager(); 8103 try { 8104 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8105 if (packageUid != callingUid) { 8106 throw new SecurityException( 8107 "Package " + packageName + " does not belong to calling UID " + callingUid); 8108 } 8109 } catch (RemoteException e) { 8110 throw new SecurityException("Failed to verify package name ownership"); 8111 } 8112 8113 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8114 synchronized (this) { 8115 if (incoming) { 8116 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8117 callingUid); 8118 if (perms == null) { 8119 Slog.w(TAG, "No permission grants found for " + packageName); 8120 } else { 8121 for (UriPermission perm : perms.values()) { 8122 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8123 result.add(perm.buildPersistedPublicApiObject()); 8124 } 8125 } 8126 } 8127 } else { 8128 final int size = mGrantedUriPermissions.size(); 8129 for (int i = 0; i < size; i++) { 8130 final ArrayMap<GrantUri, UriPermission> perms = 8131 mGrantedUriPermissions.valueAt(i); 8132 for (UriPermission perm : perms.values()) { 8133 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8134 result.add(perm.buildPersistedPublicApiObject()); 8135 } 8136 } 8137 } 8138 } 8139 } 8140 return new ParceledListSlice<android.content.UriPermission>(result); 8141 } 8142 8143 @Override 8144 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8145 synchronized (this) { 8146 ProcessRecord app = 8147 who != null ? getRecordForAppLocked(who) : null; 8148 if (app == null) return; 8149 8150 Message msg = Message.obtain(); 8151 msg.what = WAIT_FOR_DEBUGGER_MSG; 8152 msg.obj = app; 8153 msg.arg1 = waiting ? 1 : 0; 8154 mHandler.sendMessage(msg); 8155 } 8156 } 8157 8158 @Override 8159 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8160 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8161 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8162 outInfo.availMem = Process.getFreeMemory(); 8163 outInfo.totalMem = Process.getTotalMemory(); 8164 outInfo.threshold = homeAppMem; 8165 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8166 outInfo.hiddenAppThreshold = cachedAppMem; 8167 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8168 ProcessList.SERVICE_ADJ); 8169 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8170 ProcessList.VISIBLE_APP_ADJ); 8171 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8172 ProcessList.FOREGROUND_APP_ADJ); 8173 } 8174 8175 // ========================================================= 8176 // TASK MANAGEMENT 8177 // ========================================================= 8178 8179 @Override 8180 public List<IAppTask> getAppTasks(String callingPackage) { 8181 int callingUid = Binder.getCallingUid(); 8182 long ident = Binder.clearCallingIdentity(); 8183 8184 synchronized(this) { 8185 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8186 try { 8187 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8188 8189 final int N = mRecentTasks.size(); 8190 for (int i = 0; i < N; i++) { 8191 TaskRecord tr = mRecentTasks.get(i); 8192 // Skip tasks that do not match the caller. We don't need to verify 8193 // callingPackage, because we are also limiting to callingUid and know 8194 // that will limit to the correct security sandbox. 8195 if (tr.effectiveUid != callingUid) { 8196 continue; 8197 } 8198 Intent intent = tr.getBaseIntent(); 8199 if (intent == null || 8200 !callingPackage.equals(intent.getComponent().getPackageName())) { 8201 continue; 8202 } 8203 ActivityManager.RecentTaskInfo taskInfo = 8204 createRecentTaskInfoFromTaskRecord(tr); 8205 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8206 list.add(taskImpl); 8207 } 8208 } finally { 8209 Binder.restoreCallingIdentity(ident); 8210 } 8211 return list; 8212 } 8213 } 8214 8215 @Override 8216 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8217 final int callingUid = Binder.getCallingUid(); 8218 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8219 8220 synchronized(this) { 8221 if (localLOGV) Slog.v( 8222 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8223 8224 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8225 callingUid); 8226 8227 // TODO: Improve with MRU list from all ActivityStacks. 8228 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8229 } 8230 8231 return list; 8232 } 8233 8234 TaskRecord getMostRecentTask() { 8235 return mRecentTasks.get(0); 8236 } 8237 8238 /** 8239 * Creates a new RecentTaskInfo from a TaskRecord. 8240 */ 8241 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8242 // Update the task description to reflect any changes in the task stack 8243 tr.updateTaskDescription(); 8244 8245 // Compose the recent task info 8246 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8247 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8248 rti.persistentId = tr.taskId; 8249 rti.baseIntent = new Intent(tr.getBaseIntent()); 8250 rti.origActivity = tr.origActivity; 8251 rti.description = tr.lastDescription; 8252 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8253 rti.userId = tr.userId; 8254 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8255 rti.firstActiveTime = tr.firstActiveTime; 8256 rti.lastActiveTime = tr.lastActiveTime; 8257 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8258 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8259 return rti; 8260 } 8261 8262 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8263 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8264 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8265 if (!allowed) { 8266 if (checkPermission(android.Manifest.permission.GET_TASKS, 8267 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8268 // Temporary compatibility: some existing apps on the system image may 8269 // still be requesting the old permission and not switched to the new 8270 // one; if so, we'll still allow them full access. This means we need 8271 // to see if they are holding the old permission and are a system app. 8272 try { 8273 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8274 allowed = true; 8275 Slog.w(TAG, caller + ": caller " + callingUid 8276 + " is using old GET_TASKS but privileged; allowing"); 8277 } 8278 } catch (RemoteException e) { 8279 } 8280 } 8281 } 8282 if (!allowed) { 8283 Slog.w(TAG, caller + ": caller " + callingUid 8284 + " does not hold GET_TASKS; limiting output"); 8285 } 8286 return allowed; 8287 } 8288 8289 @Override 8290 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8291 final int callingUid = Binder.getCallingUid(); 8292 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8293 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8294 8295 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8296 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8297 synchronized (this) { 8298 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8299 callingUid); 8300 final boolean detailed = checkCallingPermission( 8301 android.Manifest.permission.GET_DETAILED_TASKS) 8302 == PackageManager.PERMISSION_GRANTED; 8303 8304 final int N = mRecentTasks.size(); 8305 ArrayList<ActivityManager.RecentTaskInfo> res 8306 = new ArrayList<ActivityManager.RecentTaskInfo>( 8307 maxNum < N ? maxNum : N); 8308 8309 final Set<Integer> includedUsers; 8310 if (includeProfiles) { 8311 includedUsers = getProfileIdsLocked(userId); 8312 } else { 8313 includedUsers = new HashSet<Integer>(); 8314 } 8315 includedUsers.add(Integer.valueOf(userId)); 8316 8317 for (int i=0; i<N && maxNum > 0; i++) { 8318 TaskRecord tr = mRecentTasks.get(i); 8319 // Only add calling user or related users recent tasks 8320 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8321 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8322 continue; 8323 } 8324 8325 // Return the entry if desired by the caller. We always return 8326 // the first entry, because callers always expect this to be the 8327 // foreground app. We may filter others if the caller has 8328 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8329 // we should exclude the entry. 8330 8331 if (i == 0 8332 || withExcluded 8333 || (tr.intent == null) 8334 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8335 == 0)) { 8336 if (!allowed) { 8337 // If the caller doesn't have the GET_TASKS permission, then only 8338 // allow them to see a small subset of tasks -- their own and home. 8339 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8340 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8341 continue; 8342 } 8343 } 8344 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8345 if (tr.stack != null && tr.stack.isHomeStack()) { 8346 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8347 continue; 8348 } 8349 } 8350 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8351 // Don't include auto remove tasks that are finished or finishing. 8352 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8353 + tr); 8354 continue; 8355 } 8356 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8357 && !tr.isAvailable) { 8358 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8359 continue; 8360 } 8361 8362 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8363 if (!detailed) { 8364 rti.baseIntent.replaceExtras((Bundle)null); 8365 } 8366 8367 res.add(rti); 8368 maxNum--; 8369 } 8370 } 8371 return res; 8372 } 8373 } 8374 8375 private TaskRecord recentTaskForIdLocked(int id) { 8376 final int N = mRecentTasks.size(); 8377 for (int i=0; i<N; i++) { 8378 TaskRecord tr = mRecentTasks.get(i); 8379 if (tr.taskId == id) { 8380 return tr; 8381 } 8382 } 8383 return null; 8384 } 8385 8386 @Override 8387 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8388 synchronized (this) { 8389 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8390 "getTaskThumbnail()"); 8391 TaskRecord tr = recentTaskForIdLocked(id); 8392 if (tr != null) { 8393 return tr.getTaskThumbnailLocked(); 8394 } 8395 } 8396 return null; 8397 } 8398 8399 @Override 8400 public int addAppTask(IBinder activityToken, Intent intent, 8401 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8402 final int callingUid = Binder.getCallingUid(); 8403 final long callingIdent = Binder.clearCallingIdentity(); 8404 8405 try { 8406 synchronized (this) { 8407 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8408 if (r == null) { 8409 throw new IllegalArgumentException("Activity does not exist; token=" 8410 + activityToken); 8411 } 8412 ComponentName comp = intent.getComponent(); 8413 if (comp == null) { 8414 throw new IllegalArgumentException("Intent " + intent 8415 + " must specify explicit component"); 8416 } 8417 if (thumbnail.getWidth() != mThumbnailWidth 8418 || thumbnail.getHeight() != mThumbnailHeight) { 8419 throw new IllegalArgumentException("Bad thumbnail size: got " 8420 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8421 + mThumbnailWidth + "x" + mThumbnailHeight); 8422 } 8423 if (intent.getSelector() != null) { 8424 intent.setSelector(null); 8425 } 8426 if (intent.getSourceBounds() != null) { 8427 intent.setSourceBounds(null); 8428 } 8429 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8430 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8431 // The caller has added this as an auto-remove task... that makes no 8432 // sense, so turn off auto-remove. 8433 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8434 } 8435 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8436 // Must be a new task. 8437 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8438 } 8439 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8440 mLastAddedTaskActivity = null; 8441 } 8442 ActivityInfo ainfo = mLastAddedTaskActivity; 8443 if (ainfo == null) { 8444 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8445 comp, 0, UserHandle.getUserId(callingUid)); 8446 if (ainfo.applicationInfo.uid != callingUid) { 8447 throw new SecurityException( 8448 "Can't add task for another application: target uid=" 8449 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8450 } 8451 } 8452 8453 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8454 intent, description); 8455 8456 int trimIdx = trimRecentsForTask(task, false); 8457 if (trimIdx >= 0) { 8458 // If this would have caused a trim, then we'll abort because that 8459 // means it would be added at the end of the list but then just removed. 8460 return -1; 8461 } 8462 8463 final int N = mRecentTasks.size(); 8464 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8465 final TaskRecord tr = mRecentTasks.remove(N - 1); 8466 tr.removedFromRecents(mTaskPersister); 8467 } 8468 8469 task.inRecents = true; 8470 mRecentTasks.add(task); 8471 r.task.stack.addTask(task, false, false); 8472 8473 task.setLastThumbnail(thumbnail); 8474 task.freeLastThumbnail(); 8475 8476 return task.taskId; 8477 } 8478 } finally { 8479 Binder.restoreCallingIdentity(callingIdent); 8480 } 8481 } 8482 8483 @Override 8484 public Point getAppTaskThumbnailSize() { 8485 synchronized (this) { 8486 return new Point(mThumbnailWidth, mThumbnailHeight); 8487 } 8488 } 8489 8490 @Override 8491 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8492 synchronized (this) { 8493 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8494 if (r != null) { 8495 r.setTaskDescription(td); 8496 r.task.updateTaskDescription(); 8497 } 8498 } 8499 } 8500 8501 @Override 8502 public Bitmap getTaskDescriptionIcon(String filename) { 8503 if (!FileUtils.isValidExtFilename(filename) 8504 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8505 throw new IllegalArgumentException("Bad filename: " + filename); 8506 } 8507 return mTaskPersister.getTaskDescriptionIcon(filename); 8508 } 8509 8510 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8511 mRecentTasks.remove(tr); 8512 tr.removedFromRecents(mTaskPersister); 8513 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8514 Intent baseIntent = new Intent( 8515 tr.intent != null ? tr.intent : tr.affinityIntent); 8516 ComponentName component = baseIntent.getComponent(); 8517 if (component == null) { 8518 Slog.w(TAG, "Now component for base intent of task: " + tr); 8519 return; 8520 } 8521 8522 // Find any running services associated with this app. 8523 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8524 8525 if (killProcesses) { 8526 // Find any running processes associated with this app. 8527 final String pkg = component.getPackageName(); 8528 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8529 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8530 for (int i=0; i<pmap.size(); i++) { 8531 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8532 for (int j=0; j<uids.size(); j++) { 8533 ProcessRecord proc = uids.valueAt(j); 8534 if (proc.userId != tr.userId) { 8535 continue; 8536 } 8537 if (!proc.pkgList.containsKey(pkg)) { 8538 continue; 8539 } 8540 procs.add(proc); 8541 } 8542 } 8543 8544 // Kill the running processes. 8545 for (int i=0; i<procs.size(); i++) { 8546 ProcessRecord pr = procs.get(i); 8547 if (pr == mHomeProcess) { 8548 // Don't kill the home process along with tasks from the same package. 8549 continue; 8550 } 8551 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8552 pr.kill("remove task", true); 8553 } else { 8554 pr.waitingToKill = "remove task"; 8555 } 8556 } 8557 } 8558 } 8559 8560 /** 8561 * Removes the task with the specified task id. 8562 * 8563 * @param taskId Identifier of the task to be removed. 8564 * @param flags Additional operational flags. May be 0 or 8565 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8566 * @return Returns true if the given task was found and removed. 8567 */ 8568 private boolean removeTaskByIdLocked(int taskId, int flags) { 8569 TaskRecord tr = recentTaskForIdLocked(taskId); 8570 if (tr != null) { 8571 tr.removeTaskActivitiesLocked(); 8572 cleanUpRemovedTaskLocked(tr, flags); 8573 if (tr.isPersistable) { 8574 notifyTaskPersisterLocked(null, true); 8575 } 8576 return true; 8577 } 8578 return false; 8579 } 8580 8581 @Override 8582 public boolean removeTask(int taskId, int flags) { 8583 synchronized (this) { 8584 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8585 "removeTask()"); 8586 long ident = Binder.clearCallingIdentity(); 8587 try { 8588 return removeTaskByIdLocked(taskId, flags); 8589 } finally { 8590 Binder.restoreCallingIdentity(ident); 8591 } 8592 } 8593 } 8594 8595 /** 8596 * TODO: Add mController hook 8597 */ 8598 @Override 8599 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8600 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8601 "moveTaskToFront()"); 8602 8603 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8604 synchronized(this) { 8605 moveTaskToFrontLocked(taskId, flags, options); 8606 } 8607 } 8608 8609 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8610 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8611 Binder.getCallingUid(), -1, -1, "Task to front")) { 8612 ActivityOptions.abort(options); 8613 return; 8614 } 8615 final long origId = Binder.clearCallingIdentity(); 8616 try { 8617 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8618 if (task == null) { 8619 return; 8620 } 8621 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8622 mStackSupervisor.showLockTaskToast(); 8623 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8624 return; 8625 } 8626 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8627 if (prev != null && prev.isRecentsActivity()) { 8628 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8629 } 8630 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8631 } finally { 8632 Binder.restoreCallingIdentity(origId); 8633 } 8634 ActivityOptions.abort(options); 8635 } 8636 8637 @Override 8638 public void moveTaskToBack(int taskId) { 8639 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8640 "moveTaskToBack()"); 8641 8642 synchronized(this) { 8643 TaskRecord tr = recentTaskForIdLocked(taskId); 8644 if (tr != null) { 8645 if (tr == mStackSupervisor.mLockTaskModeTask) { 8646 mStackSupervisor.showLockTaskToast(); 8647 return; 8648 } 8649 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8650 ActivityStack stack = tr.stack; 8651 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8652 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8653 Binder.getCallingUid(), -1, -1, "Task to back")) { 8654 return; 8655 } 8656 } 8657 final long origId = Binder.clearCallingIdentity(); 8658 try { 8659 stack.moveTaskToBackLocked(taskId, null); 8660 } finally { 8661 Binder.restoreCallingIdentity(origId); 8662 } 8663 } 8664 } 8665 } 8666 8667 /** 8668 * Moves an activity, and all of the other activities within the same task, to the bottom 8669 * of the history stack. The activity's order within the task is unchanged. 8670 * 8671 * @param token A reference to the activity we wish to move 8672 * @param nonRoot If false then this only works if the activity is the root 8673 * of a task; if true it will work for any activity in a task. 8674 * @return Returns true if the move completed, false if not. 8675 */ 8676 @Override 8677 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8678 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8679 synchronized(this) { 8680 final long origId = Binder.clearCallingIdentity(); 8681 try { 8682 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8683 if (taskId >= 0) { 8684 if ((mStackSupervisor.mLockTaskModeTask != null) 8685 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8686 mStackSupervisor.showLockTaskToast(); 8687 return false; 8688 } 8689 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8690 } 8691 } finally { 8692 Binder.restoreCallingIdentity(origId); 8693 } 8694 } 8695 return false; 8696 } 8697 8698 @Override 8699 public void moveTaskBackwards(int task) { 8700 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8701 "moveTaskBackwards()"); 8702 8703 synchronized(this) { 8704 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8705 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8706 return; 8707 } 8708 final long origId = Binder.clearCallingIdentity(); 8709 moveTaskBackwardsLocked(task); 8710 Binder.restoreCallingIdentity(origId); 8711 } 8712 } 8713 8714 private final void moveTaskBackwardsLocked(int task) { 8715 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8716 } 8717 8718 @Override 8719 public IBinder getHomeActivityToken() throws RemoteException { 8720 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8721 "getHomeActivityToken()"); 8722 synchronized (this) { 8723 return mStackSupervisor.getHomeActivityToken(); 8724 } 8725 } 8726 8727 @Override 8728 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8729 IActivityContainerCallback callback) throws RemoteException { 8730 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8731 "createActivityContainer()"); 8732 synchronized (this) { 8733 if (parentActivityToken == null) { 8734 throw new IllegalArgumentException("parent token must not be null"); 8735 } 8736 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8737 if (r == null) { 8738 return null; 8739 } 8740 if (callback == null) { 8741 throw new IllegalArgumentException("callback must not be null"); 8742 } 8743 return mStackSupervisor.createActivityContainer(r, callback); 8744 } 8745 } 8746 8747 @Override 8748 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8749 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8750 "deleteActivityContainer()"); 8751 synchronized (this) { 8752 mStackSupervisor.deleteActivityContainer(container); 8753 } 8754 } 8755 8756 @Override 8757 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8758 throws RemoteException { 8759 synchronized (this) { 8760 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8761 if (stack != null) { 8762 return stack.mActivityContainer; 8763 } 8764 return null; 8765 } 8766 } 8767 8768 @Override 8769 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8770 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8771 "moveTaskToStack()"); 8772 if (stackId == HOME_STACK_ID) { 8773 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8774 new RuntimeException("here").fillInStackTrace()); 8775 } 8776 synchronized (this) { 8777 long ident = Binder.clearCallingIdentity(); 8778 try { 8779 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8780 + stackId + " toTop=" + toTop); 8781 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8782 } finally { 8783 Binder.restoreCallingIdentity(ident); 8784 } 8785 } 8786 } 8787 8788 @Override 8789 public void resizeStack(int stackBoxId, Rect bounds) { 8790 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8791 "resizeStackBox()"); 8792 long ident = Binder.clearCallingIdentity(); 8793 try { 8794 mWindowManager.resizeStack(stackBoxId, bounds); 8795 } finally { 8796 Binder.restoreCallingIdentity(ident); 8797 } 8798 } 8799 8800 @Override 8801 public List<StackInfo> getAllStackInfos() { 8802 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8803 "getAllStackInfos()"); 8804 long ident = Binder.clearCallingIdentity(); 8805 try { 8806 synchronized (this) { 8807 return mStackSupervisor.getAllStackInfosLocked(); 8808 } 8809 } finally { 8810 Binder.restoreCallingIdentity(ident); 8811 } 8812 } 8813 8814 @Override 8815 public StackInfo getStackInfo(int stackId) { 8816 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8817 "getStackInfo()"); 8818 long ident = Binder.clearCallingIdentity(); 8819 try { 8820 synchronized (this) { 8821 return mStackSupervisor.getStackInfoLocked(stackId); 8822 } 8823 } finally { 8824 Binder.restoreCallingIdentity(ident); 8825 } 8826 } 8827 8828 @Override 8829 public boolean isInHomeStack(int taskId) { 8830 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8831 "getStackInfo()"); 8832 long ident = Binder.clearCallingIdentity(); 8833 try { 8834 synchronized (this) { 8835 TaskRecord tr = recentTaskForIdLocked(taskId); 8836 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8837 } 8838 } finally { 8839 Binder.restoreCallingIdentity(ident); 8840 } 8841 } 8842 8843 @Override 8844 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8845 synchronized(this) { 8846 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8847 } 8848 } 8849 8850 private boolean isLockTaskAuthorized(String pkg) { 8851 final DevicePolicyManager dpm = (DevicePolicyManager) 8852 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8853 try { 8854 int uid = mContext.getPackageManager().getPackageUid(pkg, 8855 Binder.getCallingUserHandle().getIdentifier()); 8856 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8857 } catch (NameNotFoundException e) { 8858 return false; 8859 } 8860 } 8861 8862 void startLockTaskMode(TaskRecord task) { 8863 final String pkg; 8864 synchronized (this) { 8865 pkg = task.intent.getComponent().getPackageName(); 8866 } 8867 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8868 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8869 final TaskRecord taskRecord = task; 8870 mHandler.post(new Runnable() { 8871 @Override 8872 public void run() { 8873 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8874 } 8875 }); 8876 return; 8877 } 8878 long ident = Binder.clearCallingIdentity(); 8879 try { 8880 synchronized (this) { 8881 // Since we lost lock on task, make sure it is still there. 8882 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8883 if (task != null) { 8884 if (!isSystemInitiated 8885 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8886 throw new IllegalArgumentException("Invalid task, not in foreground"); 8887 } 8888 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8889 } 8890 } 8891 } finally { 8892 Binder.restoreCallingIdentity(ident); 8893 } 8894 } 8895 8896 @Override 8897 public void startLockTaskMode(int taskId) { 8898 final TaskRecord task; 8899 long ident = Binder.clearCallingIdentity(); 8900 try { 8901 synchronized (this) { 8902 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8903 } 8904 } finally { 8905 Binder.restoreCallingIdentity(ident); 8906 } 8907 if (task != null) { 8908 startLockTaskMode(task); 8909 } 8910 } 8911 8912 @Override 8913 public void startLockTaskMode(IBinder token) { 8914 final TaskRecord task; 8915 long ident = Binder.clearCallingIdentity(); 8916 try { 8917 synchronized (this) { 8918 final ActivityRecord r = ActivityRecord.forToken(token); 8919 if (r == null) { 8920 return; 8921 } 8922 task = r.task; 8923 } 8924 } finally { 8925 Binder.restoreCallingIdentity(ident); 8926 } 8927 if (task != null) { 8928 startLockTaskMode(task); 8929 } 8930 } 8931 8932 @Override 8933 public void startLockTaskModeOnCurrent() throws RemoteException { 8934 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8935 "startLockTaskModeOnCurrent"); 8936 ActivityRecord r = null; 8937 synchronized (this) { 8938 r = mStackSupervisor.topRunningActivityLocked(); 8939 } 8940 startLockTaskMode(r.task); 8941 } 8942 8943 @Override 8944 public void stopLockTaskMode() { 8945 // Verify that the user matches the package of the intent for the TaskRecord 8946 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8947 // and stopLockTaskMode. 8948 final int callingUid = Binder.getCallingUid(); 8949 if (callingUid != Process.SYSTEM_UID) { 8950 try { 8951 String pkg = 8952 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8953 int uid = mContext.getPackageManager().getPackageUid(pkg, 8954 Binder.getCallingUserHandle().getIdentifier()); 8955 if (uid != callingUid) { 8956 throw new SecurityException("Invalid uid, expected " + uid); 8957 } 8958 } catch (NameNotFoundException e) { 8959 Log.d(TAG, "stopLockTaskMode " + e); 8960 return; 8961 } 8962 } 8963 long ident = Binder.clearCallingIdentity(); 8964 try { 8965 Log.d(TAG, "stopLockTaskMode"); 8966 // Stop lock task 8967 synchronized (this) { 8968 mStackSupervisor.setLockTaskModeLocked(null, false); 8969 } 8970 } finally { 8971 Binder.restoreCallingIdentity(ident); 8972 } 8973 } 8974 8975 @Override 8976 public void stopLockTaskModeOnCurrent() throws RemoteException { 8977 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8978 "stopLockTaskModeOnCurrent"); 8979 long ident = Binder.clearCallingIdentity(); 8980 try { 8981 stopLockTaskMode(); 8982 } finally { 8983 Binder.restoreCallingIdentity(ident); 8984 } 8985 } 8986 8987 @Override 8988 public boolean isInLockTaskMode() { 8989 synchronized (this) { 8990 return mStackSupervisor.isInLockTaskMode(); 8991 } 8992 } 8993 8994 // ========================================================= 8995 // CONTENT PROVIDERS 8996 // ========================================================= 8997 8998 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8999 List<ProviderInfo> providers = null; 9000 try { 9001 providers = AppGlobals.getPackageManager(). 9002 queryContentProviders(app.processName, app.uid, 9003 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 9004 } catch (RemoteException ex) { 9005 } 9006 if (DEBUG_MU) 9007 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 9008 int userId = app.userId; 9009 if (providers != null) { 9010 int N = providers.size(); 9011 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 9012 for (int i=0; i<N; i++) { 9013 ProviderInfo cpi = 9014 (ProviderInfo)providers.get(i); 9015 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9016 cpi.name, cpi.flags); 9017 if (singleton && UserHandle.getUserId(app.uid) != 0) { 9018 // This is a singleton provider, but a user besides the 9019 // default user is asking to initialize a process it runs 9020 // in... well, no, it doesn't actually run in this process, 9021 // it runs in the process of the default user. Get rid of it. 9022 providers.remove(i); 9023 N--; 9024 i--; 9025 continue; 9026 } 9027 9028 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9029 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 9030 if (cpr == null) { 9031 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 9032 mProviderMap.putProviderByClass(comp, cpr); 9033 } 9034 if (DEBUG_MU) 9035 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 9036 app.pubProviders.put(cpi.name, cpr); 9037 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9038 // Don't add this if it is a platform component that is marked 9039 // to run in multiple processes, because this is actually 9040 // part of the framework so doesn't make sense to track as a 9041 // separate apk in the process. 9042 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9043 mProcessStats); 9044 } 9045 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9046 } 9047 } 9048 return providers; 9049 } 9050 9051 /** 9052 * Check if {@link ProcessRecord} has a possible chance at accessing the 9053 * given {@link ProviderInfo}. Final permission checking is always done 9054 * in {@link ContentProvider}. 9055 */ 9056 private final String checkContentProviderPermissionLocked( 9057 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9058 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9059 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9060 boolean checkedGrants = false; 9061 if (checkUser) { 9062 // Looking for cross-user grants before enforcing the typical cross-users permissions 9063 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9064 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9065 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9066 return null; 9067 } 9068 checkedGrants = true; 9069 } 9070 userId = handleIncomingUser(callingPid, callingUid, userId, 9071 false, ALLOW_NON_FULL, 9072 "checkContentProviderPermissionLocked " + cpi.authority, null); 9073 if (userId != tmpTargetUserId) { 9074 // When we actually went to determine the final targer user ID, this ended 9075 // up different than our initial check for the authority. This is because 9076 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9077 // SELF. So we need to re-check the grants again. 9078 checkedGrants = false; 9079 } 9080 } 9081 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9082 cpi.applicationInfo.uid, cpi.exported) 9083 == PackageManager.PERMISSION_GRANTED) { 9084 return null; 9085 } 9086 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9087 cpi.applicationInfo.uid, cpi.exported) 9088 == PackageManager.PERMISSION_GRANTED) { 9089 return null; 9090 } 9091 9092 PathPermission[] pps = cpi.pathPermissions; 9093 if (pps != null) { 9094 int i = pps.length; 9095 while (i > 0) { 9096 i--; 9097 PathPermission pp = pps[i]; 9098 String pprperm = pp.getReadPermission(); 9099 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9100 cpi.applicationInfo.uid, cpi.exported) 9101 == PackageManager.PERMISSION_GRANTED) { 9102 return null; 9103 } 9104 String ppwperm = pp.getWritePermission(); 9105 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9106 cpi.applicationInfo.uid, cpi.exported) 9107 == PackageManager.PERMISSION_GRANTED) { 9108 return null; 9109 } 9110 } 9111 } 9112 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9113 return null; 9114 } 9115 9116 String msg; 9117 if (!cpi.exported) { 9118 msg = "Permission Denial: opening provider " + cpi.name 9119 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9120 + ", uid=" + callingUid + ") that is not exported from uid " 9121 + cpi.applicationInfo.uid; 9122 } else { 9123 msg = "Permission Denial: opening provider " + cpi.name 9124 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9125 + ", uid=" + callingUid + ") requires " 9126 + cpi.readPermission + " or " + cpi.writePermission; 9127 } 9128 Slog.w(TAG, msg); 9129 return msg; 9130 } 9131 9132 /** 9133 * Returns if the ContentProvider has granted a uri to callingUid 9134 */ 9135 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9136 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9137 if (perms != null) { 9138 for (int i=perms.size()-1; i>=0; i--) { 9139 GrantUri grantUri = perms.keyAt(i); 9140 if (grantUri.sourceUserId == userId || !checkUser) { 9141 if (matchesProvider(grantUri.uri, cpi)) { 9142 return true; 9143 } 9144 } 9145 } 9146 } 9147 return false; 9148 } 9149 9150 /** 9151 * Returns true if the uri authority is one of the authorities specified in the provider. 9152 */ 9153 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9154 String uriAuth = uri.getAuthority(); 9155 String cpiAuth = cpi.authority; 9156 if (cpiAuth.indexOf(';') == -1) { 9157 return cpiAuth.equals(uriAuth); 9158 } 9159 String[] cpiAuths = cpiAuth.split(";"); 9160 int length = cpiAuths.length; 9161 for (int i = 0; i < length; i++) { 9162 if (cpiAuths[i].equals(uriAuth)) return true; 9163 } 9164 return false; 9165 } 9166 9167 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9168 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9169 if (r != null) { 9170 for (int i=0; i<r.conProviders.size(); i++) { 9171 ContentProviderConnection conn = r.conProviders.get(i); 9172 if (conn.provider == cpr) { 9173 if (DEBUG_PROVIDER) Slog.v(TAG, 9174 "Adding provider requested by " 9175 + r.processName + " from process " 9176 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9177 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9178 if (stable) { 9179 conn.stableCount++; 9180 conn.numStableIncs++; 9181 } else { 9182 conn.unstableCount++; 9183 conn.numUnstableIncs++; 9184 } 9185 return conn; 9186 } 9187 } 9188 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9189 if (stable) { 9190 conn.stableCount = 1; 9191 conn.numStableIncs = 1; 9192 } else { 9193 conn.unstableCount = 1; 9194 conn.numUnstableIncs = 1; 9195 } 9196 cpr.connections.add(conn); 9197 r.conProviders.add(conn); 9198 return conn; 9199 } 9200 cpr.addExternalProcessHandleLocked(externalProcessToken); 9201 return null; 9202 } 9203 9204 boolean decProviderCountLocked(ContentProviderConnection conn, 9205 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9206 if (conn != null) { 9207 cpr = conn.provider; 9208 if (DEBUG_PROVIDER) Slog.v(TAG, 9209 "Removing provider requested by " 9210 + conn.client.processName + " from process " 9211 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9212 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9213 if (stable) { 9214 conn.stableCount--; 9215 } else { 9216 conn.unstableCount--; 9217 } 9218 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9219 cpr.connections.remove(conn); 9220 conn.client.conProviders.remove(conn); 9221 return true; 9222 } 9223 return false; 9224 } 9225 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9226 return false; 9227 } 9228 9229 private void checkTime(long startTime, String where) { 9230 long now = SystemClock.elapsedRealtime(); 9231 if ((now-startTime) > 1000) { 9232 // If we are taking more than a second, log about it. 9233 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9234 } 9235 } 9236 9237 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9238 String name, IBinder token, boolean stable, int userId) { 9239 ContentProviderRecord cpr; 9240 ContentProviderConnection conn = null; 9241 ProviderInfo cpi = null; 9242 9243 synchronized(this) { 9244 long startTime = SystemClock.elapsedRealtime(); 9245 9246 ProcessRecord r = null; 9247 if (caller != null) { 9248 r = getRecordForAppLocked(caller); 9249 if (r == null) { 9250 throw new SecurityException( 9251 "Unable to find app for caller " + caller 9252 + " (pid=" + Binder.getCallingPid() 9253 + ") when getting content provider " + name); 9254 } 9255 } 9256 9257 boolean checkCrossUser = true; 9258 9259 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9260 9261 // First check if this content provider has been published... 9262 cpr = mProviderMap.getProviderByName(name, userId); 9263 // If that didn't work, check if it exists for user 0 and then 9264 // verify that it's a singleton provider before using it. 9265 if (cpr == null && userId != UserHandle.USER_OWNER) { 9266 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9267 if (cpr != null) { 9268 cpi = cpr.info; 9269 if (isSingleton(cpi.processName, cpi.applicationInfo, 9270 cpi.name, cpi.flags) 9271 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9272 userId = UserHandle.USER_OWNER; 9273 checkCrossUser = false; 9274 } else { 9275 cpr = null; 9276 cpi = null; 9277 } 9278 } 9279 } 9280 9281 boolean providerRunning = cpr != null; 9282 if (providerRunning) { 9283 cpi = cpr.info; 9284 String msg; 9285 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9286 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9287 != null) { 9288 throw new SecurityException(msg); 9289 } 9290 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9291 9292 if (r != null && cpr.canRunHere(r)) { 9293 // This provider has been published or is in the process 9294 // of being published... but it is also allowed to run 9295 // in the caller's process, so don't make a connection 9296 // and just let the caller instantiate its own instance. 9297 ContentProviderHolder holder = cpr.newHolder(null); 9298 // don't give caller the provider object, it needs 9299 // to make its own. 9300 holder.provider = null; 9301 return holder; 9302 } 9303 9304 final long origId = Binder.clearCallingIdentity(); 9305 9306 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9307 9308 // In this case the provider instance already exists, so we can 9309 // return it right away. 9310 conn = incProviderCountLocked(r, cpr, token, stable); 9311 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9312 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9313 // If this is a perceptible app accessing the provider, 9314 // make sure to count it as being accessed and thus 9315 // back up on the LRU list. This is good because 9316 // content providers are often expensive to start. 9317 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9318 updateLruProcessLocked(cpr.proc, false, null); 9319 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9320 } 9321 } 9322 9323 if (cpr.proc != null) { 9324 if (false) { 9325 if (cpr.name.flattenToShortString().equals( 9326 "com.android.providers.calendar/.CalendarProvider2")) { 9327 Slog.v(TAG, "****************** KILLING " 9328 + cpr.name.flattenToShortString()); 9329 Process.killProcess(cpr.proc.pid); 9330 } 9331 } 9332 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9333 boolean success = updateOomAdjLocked(cpr.proc); 9334 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9335 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9336 // NOTE: there is still a race here where a signal could be 9337 // pending on the process even though we managed to update its 9338 // adj level. Not sure what to do about this, but at least 9339 // the race is now smaller. 9340 if (!success) { 9341 // Uh oh... it looks like the provider's process 9342 // has been killed on us. We need to wait for a new 9343 // process to be started, and make sure its death 9344 // doesn't kill our process. 9345 Slog.i(TAG, 9346 "Existing provider " + cpr.name.flattenToShortString() 9347 + " is crashing; detaching " + r); 9348 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9349 checkTime(startTime, "getContentProviderImpl: before appDied"); 9350 appDiedLocked(cpr.proc); 9351 checkTime(startTime, "getContentProviderImpl: after appDied"); 9352 if (!lastRef) { 9353 // This wasn't the last ref our process had on 9354 // the provider... we have now been killed, bail. 9355 return null; 9356 } 9357 providerRunning = false; 9358 conn = null; 9359 } 9360 } 9361 9362 Binder.restoreCallingIdentity(origId); 9363 } 9364 9365 boolean singleton; 9366 if (!providerRunning) { 9367 try { 9368 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9369 cpi = AppGlobals.getPackageManager(). 9370 resolveContentProvider(name, 9371 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9372 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9373 } catch (RemoteException ex) { 9374 } 9375 if (cpi == null) { 9376 return null; 9377 } 9378 // If the provider is a singleton AND 9379 // (it's a call within the same user || the provider is a 9380 // privileged app) 9381 // Then allow connecting to the singleton provider 9382 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9383 cpi.name, cpi.flags) 9384 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9385 if (singleton) { 9386 userId = UserHandle.USER_OWNER; 9387 } 9388 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9389 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9390 9391 String msg; 9392 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9393 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9394 != null) { 9395 throw new SecurityException(msg); 9396 } 9397 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9398 9399 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9400 && !cpi.processName.equals("system")) { 9401 // If this content provider does not run in the system 9402 // process, and the system is not yet ready to run other 9403 // processes, then fail fast instead of hanging. 9404 throw new IllegalArgumentException( 9405 "Attempt to launch content provider before system ready"); 9406 } 9407 9408 // Make sure that the user who owns this provider is running. If not, 9409 // we don't want to allow it to run. 9410 if (!isUserRunningLocked(userId, false)) { 9411 Slog.w(TAG, "Unable to launch app " 9412 + cpi.applicationInfo.packageName + "/" 9413 + cpi.applicationInfo.uid + " for provider " 9414 + name + ": user " + userId + " is stopped"); 9415 return null; 9416 } 9417 9418 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9419 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9420 cpr = mProviderMap.getProviderByClass(comp, userId); 9421 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9422 final boolean firstClass = cpr == null; 9423 if (firstClass) { 9424 final long ident = Binder.clearCallingIdentity(); 9425 try { 9426 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9427 ApplicationInfo ai = 9428 AppGlobals.getPackageManager(). 9429 getApplicationInfo( 9430 cpi.applicationInfo.packageName, 9431 STOCK_PM_FLAGS, userId); 9432 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9433 if (ai == null) { 9434 Slog.w(TAG, "No package info for content provider " 9435 + cpi.name); 9436 return null; 9437 } 9438 ai = getAppInfoForUser(ai, userId); 9439 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9440 } catch (RemoteException ex) { 9441 // pm is in same process, this will never happen. 9442 } finally { 9443 Binder.restoreCallingIdentity(ident); 9444 } 9445 } 9446 9447 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9448 9449 if (r != null && cpr.canRunHere(r)) { 9450 // If this is a multiprocess provider, then just return its 9451 // info and allow the caller to instantiate it. Only do 9452 // this if the provider is the same user as the caller's 9453 // process, or can run as root (so can be in any process). 9454 return cpr.newHolder(null); 9455 } 9456 9457 if (DEBUG_PROVIDER) { 9458 RuntimeException e = new RuntimeException("here"); 9459 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9460 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9461 } 9462 9463 // This is single process, and our app is now connecting to it. 9464 // See if we are already in the process of launching this 9465 // provider. 9466 final int N = mLaunchingProviders.size(); 9467 int i; 9468 for (i=0; i<N; i++) { 9469 if (mLaunchingProviders.get(i) == cpr) { 9470 break; 9471 } 9472 } 9473 9474 // If the provider is not already being launched, then get it 9475 // started. 9476 if (i >= N) { 9477 final long origId = Binder.clearCallingIdentity(); 9478 9479 try { 9480 // Content provider is now in use, its package can't be stopped. 9481 try { 9482 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9483 AppGlobals.getPackageManager().setPackageStoppedState( 9484 cpr.appInfo.packageName, false, userId); 9485 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9486 } catch (RemoteException e) { 9487 } catch (IllegalArgumentException e) { 9488 Slog.w(TAG, "Failed trying to unstop package " 9489 + cpr.appInfo.packageName + ": " + e); 9490 } 9491 9492 // Use existing process if already started 9493 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9494 ProcessRecord proc = getProcessRecordLocked( 9495 cpi.processName, cpr.appInfo.uid, false); 9496 if (proc != null && proc.thread != null) { 9497 if (DEBUG_PROVIDER) { 9498 Slog.d(TAG, "Installing in existing process " + proc); 9499 } 9500 if (!proc.pubProviders.containsKey(cpi.name)) { 9501 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9502 proc.pubProviders.put(cpi.name, cpr); 9503 try { 9504 proc.thread.scheduleInstallProvider(cpi); 9505 } catch (RemoteException e) { 9506 } 9507 } 9508 } else { 9509 checkTime(startTime, "getContentProviderImpl: before start process"); 9510 proc = startProcessLocked(cpi.processName, 9511 cpr.appInfo, false, 0, "content provider", 9512 new ComponentName(cpi.applicationInfo.packageName, 9513 cpi.name), false, false, false); 9514 checkTime(startTime, "getContentProviderImpl: after start process"); 9515 if (proc == null) { 9516 Slog.w(TAG, "Unable to launch app " 9517 + cpi.applicationInfo.packageName + "/" 9518 + cpi.applicationInfo.uid + " for provider " 9519 + name + ": process is bad"); 9520 return null; 9521 } 9522 } 9523 cpr.launchingApp = proc; 9524 mLaunchingProviders.add(cpr); 9525 } finally { 9526 Binder.restoreCallingIdentity(origId); 9527 } 9528 } 9529 9530 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9531 9532 // Make sure the provider is published (the same provider class 9533 // may be published under multiple names). 9534 if (firstClass) { 9535 mProviderMap.putProviderByClass(comp, cpr); 9536 } 9537 9538 mProviderMap.putProviderByName(name, cpr); 9539 conn = incProviderCountLocked(r, cpr, token, stable); 9540 if (conn != null) { 9541 conn.waiting = true; 9542 } 9543 } 9544 checkTime(startTime, "getContentProviderImpl: done!"); 9545 } 9546 9547 // Wait for the provider to be published... 9548 synchronized (cpr) { 9549 while (cpr.provider == null) { 9550 if (cpr.launchingApp == null) { 9551 Slog.w(TAG, "Unable to launch app " 9552 + cpi.applicationInfo.packageName + "/" 9553 + cpi.applicationInfo.uid + " for provider " 9554 + name + ": launching app became null"); 9555 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9556 UserHandle.getUserId(cpi.applicationInfo.uid), 9557 cpi.applicationInfo.packageName, 9558 cpi.applicationInfo.uid, name); 9559 return null; 9560 } 9561 try { 9562 if (DEBUG_MU) { 9563 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9564 + cpr.launchingApp); 9565 } 9566 if (conn != null) { 9567 conn.waiting = true; 9568 } 9569 cpr.wait(); 9570 } catch (InterruptedException ex) { 9571 } finally { 9572 if (conn != null) { 9573 conn.waiting = false; 9574 } 9575 } 9576 } 9577 } 9578 return cpr != null ? cpr.newHolder(conn) : null; 9579 } 9580 9581 @Override 9582 public final ContentProviderHolder getContentProvider( 9583 IApplicationThread caller, String name, int userId, boolean stable) { 9584 enforceNotIsolatedCaller("getContentProvider"); 9585 if (caller == null) { 9586 String msg = "null IApplicationThread when getting content provider " 9587 + name; 9588 Slog.w(TAG, msg); 9589 throw new SecurityException(msg); 9590 } 9591 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9592 // with cross-user grant. 9593 return getContentProviderImpl(caller, name, null, stable, userId); 9594 } 9595 9596 public ContentProviderHolder getContentProviderExternal( 9597 String name, int userId, IBinder token) { 9598 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9599 "Do not have permission in call getContentProviderExternal()"); 9600 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9601 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9602 return getContentProviderExternalUnchecked(name, token, userId); 9603 } 9604 9605 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9606 IBinder token, int userId) { 9607 return getContentProviderImpl(null, name, token, true, userId); 9608 } 9609 9610 /** 9611 * Drop a content provider from a ProcessRecord's bookkeeping 9612 */ 9613 public void removeContentProvider(IBinder connection, boolean stable) { 9614 enforceNotIsolatedCaller("removeContentProvider"); 9615 long ident = Binder.clearCallingIdentity(); 9616 try { 9617 synchronized (this) { 9618 ContentProviderConnection conn; 9619 try { 9620 conn = (ContentProviderConnection)connection; 9621 } catch (ClassCastException e) { 9622 String msg ="removeContentProvider: " + connection 9623 + " not a ContentProviderConnection"; 9624 Slog.w(TAG, msg); 9625 throw new IllegalArgumentException(msg); 9626 } 9627 if (conn == null) { 9628 throw new NullPointerException("connection is null"); 9629 } 9630 if (decProviderCountLocked(conn, null, null, stable)) { 9631 updateOomAdjLocked(); 9632 } 9633 } 9634 } finally { 9635 Binder.restoreCallingIdentity(ident); 9636 } 9637 } 9638 9639 public void removeContentProviderExternal(String name, IBinder token) { 9640 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9641 "Do not have permission in call removeContentProviderExternal()"); 9642 int userId = UserHandle.getCallingUserId(); 9643 long ident = Binder.clearCallingIdentity(); 9644 try { 9645 removeContentProviderExternalUnchecked(name, token, userId); 9646 } finally { 9647 Binder.restoreCallingIdentity(ident); 9648 } 9649 } 9650 9651 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9652 synchronized (this) { 9653 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9654 if(cpr == null) { 9655 //remove from mProvidersByClass 9656 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9657 return; 9658 } 9659 9660 //update content provider record entry info 9661 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9662 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9663 if (localCpr.hasExternalProcessHandles()) { 9664 if (localCpr.removeExternalProcessHandleLocked(token)) { 9665 updateOomAdjLocked(); 9666 } else { 9667 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9668 + " with no external reference for token: " 9669 + token + "."); 9670 } 9671 } else { 9672 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9673 + " with no external references."); 9674 } 9675 } 9676 } 9677 9678 public final void publishContentProviders(IApplicationThread caller, 9679 List<ContentProviderHolder> providers) { 9680 if (providers == null) { 9681 return; 9682 } 9683 9684 enforceNotIsolatedCaller("publishContentProviders"); 9685 synchronized (this) { 9686 final ProcessRecord r = getRecordForAppLocked(caller); 9687 if (DEBUG_MU) 9688 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9689 if (r == null) { 9690 throw new SecurityException( 9691 "Unable to find app for caller " + caller 9692 + " (pid=" + Binder.getCallingPid() 9693 + ") when publishing content providers"); 9694 } 9695 9696 final long origId = Binder.clearCallingIdentity(); 9697 9698 final int N = providers.size(); 9699 for (int i=0; i<N; i++) { 9700 ContentProviderHolder src = providers.get(i); 9701 if (src == null || src.info == null || src.provider == null) { 9702 continue; 9703 } 9704 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9705 if (DEBUG_MU) 9706 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9707 if (dst != null) { 9708 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9709 mProviderMap.putProviderByClass(comp, dst); 9710 String names[] = dst.info.authority.split(";"); 9711 for (int j = 0; j < names.length; j++) { 9712 mProviderMap.putProviderByName(names[j], dst); 9713 } 9714 9715 int NL = mLaunchingProviders.size(); 9716 int j; 9717 for (j=0; j<NL; j++) { 9718 if (mLaunchingProviders.get(j) == dst) { 9719 mLaunchingProviders.remove(j); 9720 j--; 9721 NL--; 9722 } 9723 } 9724 synchronized (dst) { 9725 dst.provider = src.provider; 9726 dst.proc = r; 9727 dst.notifyAll(); 9728 } 9729 updateOomAdjLocked(r); 9730 } 9731 } 9732 9733 Binder.restoreCallingIdentity(origId); 9734 } 9735 } 9736 9737 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9738 ContentProviderConnection conn; 9739 try { 9740 conn = (ContentProviderConnection)connection; 9741 } catch (ClassCastException e) { 9742 String msg ="refContentProvider: " + connection 9743 + " not a ContentProviderConnection"; 9744 Slog.w(TAG, msg); 9745 throw new IllegalArgumentException(msg); 9746 } 9747 if (conn == null) { 9748 throw new NullPointerException("connection is null"); 9749 } 9750 9751 synchronized (this) { 9752 if (stable > 0) { 9753 conn.numStableIncs += stable; 9754 } 9755 stable = conn.stableCount + stable; 9756 if (stable < 0) { 9757 throw new IllegalStateException("stableCount < 0: " + stable); 9758 } 9759 9760 if (unstable > 0) { 9761 conn.numUnstableIncs += unstable; 9762 } 9763 unstable = conn.unstableCount + unstable; 9764 if (unstable < 0) { 9765 throw new IllegalStateException("unstableCount < 0: " + unstable); 9766 } 9767 9768 if ((stable+unstable) <= 0) { 9769 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9770 + stable + " unstable=" + unstable); 9771 } 9772 conn.stableCount = stable; 9773 conn.unstableCount = unstable; 9774 return !conn.dead; 9775 } 9776 } 9777 9778 public void unstableProviderDied(IBinder connection) { 9779 ContentProviderConnection conn; 9780 try { 9781 conn = (ContentProviderConnection)connection; 9782 } catch (ClassCastException e) { 9783 String msg ="refContentProvider: " + connection 9784 + " not a ContentProviderConnection"; 9785 Slog.w(TAG, msg); 9786 throw new IllegalArgumentException(msg); 9787 } 9788 if (conn == null) { 9789 throw new NullPointerException("connection is null"); 9790 } 9791 9792 // Safely retrieve the content provider associated with the connection. 9793 IContentProvider provider; 9794 synchronized (this) { 9795 provider = conn.provider.provider; 9796 } 9797 9798 if (provider == null) { 9799 // Um, yeah, we're way ahead of you. 9800 return; 9801 } 9802 9803 // Make sure the caller is being honest with us. 9804 if (provider.asBinder().pingBinder()) { 9805 // Er, no, still looks good to us. 9806 synchronized (this) { 9807 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9808 + " says " + conn + " died, but we don't agree"); 9809 return; 9810 } 9811 } 9812 9813 // Well look at that! It's dead! 9814 synchronized (this) { 9815 if (conn.provider.provider != provider) { 9816 // But something changed... good enough. 9817 return; 9818 } 9819 9820 ProcessRecord proc = conn.provider.proc; 9821 if (proc == null || proc.thread == null) { 9822 // Seems like the process is already cleaned up. 9823 return; 9824 } 9825 9826 // As far as we're concerned, this is just like receiving a 9827 // death notification... just a bit prematurely. 9828 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9829 + ") early provider death"); 9830 final long ident = Binder.clearCallingIdentity(); 9831 try { 9832 appDiedLocked(proc); 9833 } finally { 9834 Binder.restoreCallingIdentity(ident); 9835 } 9836 } 9837 } 9838 9839 @Override 9840 public void appNotRespondingViaProvider(IBinder connection) { 9841 enforceCallingPermission( 9842 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9843 9844 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9845 if (conn == null) { 9846 Slog.w(TAG, "ContentProviderConnection is null"); 9847 return; 9848 } 9849 9850 final ProcessRecord host = conn.provider.proc; 9851 if (host == null) { 9852 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9853 return; 9854 } 9855 9856 final long token = Binder.clearCallingIdentity(); 9857 try { 9858 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9859 } finally { 9860 Binder.restoreCallingIdentity(token); 9861 } 9862 } 9863 9864 public final void installSystemProviders() { 9865 List<ProviderInfo> providers; 9866 synchronized (this) { 9867 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9868 providers = generateApplicationProvidersLocked(app); 9869 if (providers != null) { 9870 for (int i=providers.size()-1; i>=0; i--) { 9871 ProviderInfo pi = (ProviderInfo)providers.get(i); 9872 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9873 Slog.w(TAG, "Not installing system proc provider " + pi.name 9874 + ": not system .apk"); 9875 providers.remove(i); 9876 } 9877 } 9878 } 9879 } 9880 if (providers != null) { 9881 mSystemThread.installSystemProviders(providers); 9882 } 9883 9884 mCoreSettingsObserver = new CoreSettingsObserver(this); 9885 9886 //mUsageStatsService.monitorPackages(); 9887 } 9888 9889 /** 9890 * Allows apps to retrieve the MIME type of a URI. 9891 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9892 * users, then it does not need permission to access the ContentProvider. 9893 * Either, it needs cross-user uri grants. 9894 * 9895 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9896 * 9897 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9898 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9899 */ 9900 public String getProviderMimeType(Uri uri, int userId) { 9901 enforceNotIsolatedCaller("getProviderMimeType"); 9902 final String name = uri.getAuthority(); 9903 int callingUid = Binder.getCallingUid(); 9904 int callingPid = Binder.getCallingPid(); 9905 long ident = 0; 9906 boolean clearedIdentity = false; 9907 userId = unsafeConvertIncomingUser(userId); 9908 if (canClearIdentity(callingPid, callingUid, userId)) { 9909 clearedIdentity = true; 9910 ident = Binder.clearCallingIdentity(); 9911 } 9912 ContentProviderHolder holder = null; 9913 try { 9914 holder = getContentProviderExternalUnchecked(name, null, userId); 9915 if (holder != null) { 9916 return holder.provider.getType(uri); 9917 } 9918 } catch (RemoteException e) { 9919 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9920 return null; 9921 } finally { 9922 // We need to clear the identity to call removeContentProviderExternalUnchecked 9923 if (!clearedIdentity) { 9924 ident = Binder.clearCallingIdentity(); 9925 } 9926 try { 9927 if (holder != null) { 9928 removeContentProviderExternalUnchecked(name, null, userId); 9929 } 9930 } finally { 9931 Binder.restoreCallingIdentity(ident); 9932 } 9933 } 9934 9935 return null; 9936 } 9937 9938 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9939 if (UserHandle.getUserId(callingUid) == userId) { 9940 return true; 9941 } 9942 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9943 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9944 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9945 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9946 return true; 9947 } 9948 return false; 9949 } 9950 9951 // ========================================================= 9952 // GLOBAL MANAGEMENT 9953 // ========================================================= 9954 9955 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9956 boolean isolated, int isolatedUid) { 9957 String proc = customProcess != null ? customProcess : info.processName; 9958 BatteryStatsImpl.Uid.Proc ps = null; 9959 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9960 int uid = info.uid; 9961 if (isolated) { 9962 if (isolatedUid == 0) { 9963 int userId = UserHandle.getUserId(uid); 9964 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9965 while (true) { 9966 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9967 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9968 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9969 } 9970 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9971 mNextIsolatedProcessUid++; 9972 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9973 // No process for this uid, use it. 9974 break; 9975 } 9976 stepsLeft--; 9977 if (stepsLeft <= 0) { 9978 return null; 9979 } 9980 } 9981 } else { 9982 // Special case for startIsolatedProcess (internal only), where 9983 // the uid of the isolated process is specified by the caller. 9984 uid = isolatedUid; 9985 } 9986 } 9987 return new ProcessRecord(stats, info, proc, uid); 9988 } 9989 9990 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9991 String abiOverride) { 9992 ProcessRecord app; 9993 if (!isolated) { 9994 app = getProcessRecordLocked(info.processName, info.uid, true); 9995 } else { 9996 app = null; 9997 } 9998 9999 if (app == null) { 10000 app = newProcessRecordLocked(info, null, isolated, 0); 10001 mProcessNames.put(info.processName, app.uid, app); 10002 if (isolated) { 10003 mIsolatedProcesses.put(app.uid, app); 10004 } 10005 updateLruProcessLocked(app, false, null); 10006 updateOomAdjLocked(); 10007 } 10008 10009 // This package really, really can not be stopped. 10010 try { 10011 AppGlobals.getPackageManager().setPackageStoppedState( 10012 info.packageName, false, UserHandle.getUserId(app.uid)); 10013 } catch (RemoteException e) { 10014 } catch (IllegalArgumentException e) { 10015 Slog.w(TAG, "Failed trying to unstop package " 10016 + info.packageName + ": " + e); 10017 } 10018 10019 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 10020 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 10021 app.persistent = true; 10022 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 10023 } 10024 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 10025 mPersistentStartingProcesses.add(app); 10026 startProcessLocked(app, "added application", app.processName, abiOverride, 10027 null /* entryPoint */, null /* entryPointArgs */); 10028 } 10029 10030 return app; 10031 } 10032 10033 public void unhandledBack() { 10034 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 10035 "unhandledBack()"); 10036 10037 synchronized(this) { 10038 final long origId = Binder.clearCallingIdentity(); 10039 try { 10040 getFocusedStack().unhandledBackLocked(); 10041 } finally { 10042 Binder.restoreCallingIdentity(origId); 10043 } 10044 } 10045 } 10046 10047 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10048 enforceNotIsolatedCaller("openContentUri"); 10049 final int userId = UserHandle.getCallingUserId(); 10050 String name = uri.getAuthority(); 10051 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10052 ParcelFileDescriptor pfd = null; 10053 if (cph != null) { 10054 // We record the binder invoker's uid in thread-local storage before 10055 // going to the content provider to open the file. Later, in the code 10056 // that handles all permissions checks, we look for this uid and use 10057 // that rather than the Activity Manager's own uid. The effect is that 10058 // we do the check against the caller's permissions even though it looks 10059 // to the content provider like the Activity Manager itself is making 10060 // the request. 10061 sCallerIdentity.set(new Identity( 10062 Binder.getCallingPid(), Binder.getCallingUid())); 10063 try { 10064 pfd = cph.provider.openFile(null, uri, "r", null); 10065 } catch (FileNotFoundException e) { 10066 // do nothing; pfd will be returned null 10067 } finally { 10068 // Ensure that whatever happens, we clean up the identity state 10069 sCallerIdentity.remove(); 10070 // Ensure we're done with the provider. 10071 removeContentProviderExternalUnchecked(name, null, userId); 10072 } 10073 } else { 10074 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10075 } 10076 return pfd; 10077 } 10078 10079 // Actually is sleeping or shutting down or whatever else in the future 10080 // is an inactive state. 10081 public boolean isSleepingOrShuttingDown() { 10082 return isSleeping() || mShuttingDown; 10083 } 10084 10085 public boolean isSleeping() { 10086 return mSleeping; 10087 } 10088 10089 void goingToSleep() { 10090 synchronized(this) { 10091 mWentToSleep = true; 10092 goToSleepIfNeededLocked(); 10093 } 10094 } 10095 10096 void finishRunningVoiceLocked() { 10097 if (mRunningVoice) { 10098 mRunningVoice = false; 10099 goToSleepIfNeededLocked(); 10100 } 10101 } 10102 10103 void goToSleepIfNeededLocked() { 10104 if (mWentToSleep && !mRunningVoice) { 10105 if (!mSleeping) { 10106 mSleeping = true; 10107 mStackSupervisor.goingToSleepLocked(); 10108 10109 // Initialize the wake times of all processes. 10110 checkExcessivePowerUsageLocked(false); 10111 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10112 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10113 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10114 } 10115 } 10116 } 10117 10118 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10119 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10120 // Never persist the home stack. 10121 return; 10122 } 10123 mTaskPersister.wakeup(task, flush); 10124 } 10125 10126 @Override 10127 public void notifyCleartextNetwork(int uid, byte[] firstPacket) { 10128 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); 10129 } 10130 10131 @Override 10132 public boolean shutdown(int timeout) { 10133 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10134 != PackageManager.PERMISSION_GRANTED) { 10135 throw new SecurityException("Requires permission " 10136 + android.Manifest.permission.SHUTDOWN); 10137 } 10138 10139 boolean timedout = false; 10140 10141 synchronized(this) { 10142 mShuttingDown = true; 10143 updateEventDispatchingLocked(); 10144 timedout = mStackSupervisor.shutdownLocked(timeout); 10145 } 10146 10147 mAppOpsService.shutdown(); 10148 if (mUsageStatsService != null) { 10149 mUsageStatsService.prepareShutdown(); 10150 } 10151 mBatteryStatsService.shutdown(); 10152 synchronized (this) { 10153 mProcessStats.shutdownLocked(); 10154 } 10155 notifyTaskPersisterLocked(null, true); 10156 10157 return timedout; 10158 } 10159 10160 public final void activitySlept(IBinder token) { 10161 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10162 10163 final long origId = Binder.clearCallingIdentity(); 10164 10165 synchronized (this) { 10166 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10167 if (r != null) { 10168 mStackSupervisor.activitySleptLocked(r); 10169 } 10170 } 10171 10172 Binder.restoreCallingIdentity(origId); 10173 } 10174 10175 void logLockScreen(String msg) { 10176 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10177 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10178 mWentToSleep + " mSleeping=" + mSleeping); 10179 } 10180 10181 private void comeOutOfSleepIfNeededLocked() { 10182 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10183 if (mSleeping) { 10184 mSleeping = false; 10185 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10186 } 10187 } 10188 } 10189 10190 void wakingUp() { 10191 synchronized(this) { 10192 mWentToSleep = false; 10193 comeOutOfSleepIfNeededLocked(); 10194 } 10195 } 10196 10197 void startRunningVoiceLocked() { 10198 if (!mRunningVoice) { 10199 mRunningVoice = true; 10200 comeOutOfSleepIfNeededLocked(); 10201 } 10202 } 10203 10204 private void updateEventDispatchingLocked() { 10205 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10206 } 10207 10208 public void setLockScreenShown(boolean shown) { 10209 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10210 != PackageManager.PERMISSION_GRANTED) { 10211 throw new SecurityException("Requires permission " 10212 + android.Manifest.permission.DEVICE_POWER); 10213 } 10214 10215 synchronized(this) { 10216 long ident = Binder.clearCallingIdentity(); 10217 try { 10218 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10219 mLockScreenShown = shown; 10220 comeOutOfSleepIfNeededLocked(); 10221 } finally { 10222 Binder.restoreCallingIdentity(ident); 10223 } 10224 } 10225 } 10226 10227 @Override 10228 public void stopAppSwitches() { 10229 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10230 != PackageManager.PERMISSION_GRANTED) { 10231 throw new SecurityException("Requires permission " 10232 + android.Manifest.permission.STOP_APP_SWITCHES); 10233 } 10234 10235 synchronized(this) { 10236 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10237 + APP_SWITCH_DELAY_TIME; 10238 mDidAppSwitch = false; 10239 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10240 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10241 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10242 } 10243 } 10244 10245 public void resumeAppSwitches() { 10246 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10247 != PackageManager.PERMISSION_GRANTED) { 10248 throw new SecurityException("Requires permission " 10249 + android.Manifest.permission.STOP_APP_SWITCHES); 10250 } 10251 10252 synchronized(this) { 10253 // Note that we don't execute any pending app switches... we will 10254 // let those wait until either the timeout, or the next start 10255 // activity request. 10256 mAppSwitchesAllowedTime = 0; 10257 } 10258 } 10259 10260 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10261 int callingPid, int callingUid, String name) { 10262 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10263 return true; 10264 } 10265 10266 int perm = checkComponentPermission( 10267 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10268 sourceUid, -1, true); 10269 if (perm == PackageManager.PERMISSION_GRANTED) { 10270 return true; 10271 } 10272 10273 // If the actual IPC caller is different from the logical source, then 10274 // also see if they are allowed to control app switches. 10275 if (callingUid != -1 && callingUid != sourceUid) { 10276 perm = checkComponentPermission( 10277 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10278 callingUid, -1, true); 10279 if (perm == PackageManager.PERMISSION_GRANTED) { 10280 return true; 10281 } 10282 } 10283 10284 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10285 return false; 10286 } 10287 10288 public void setDebugApp(String packageName, boolean waitForDebugger, 10289 boolean persistent) { 10290 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10291 "setDebugApp()"); 10292 10293 long ident = Binder.clearCallingIdentity(); 10294 try { 10295 // Note that this is not really thread safe if there are multiple 10296 // callers into it at the same time, but that's not a situation we 10297 // care about. 10298 if (persistent) { 10299 final ContentResolver resolver = mContext.getContentResolver(); 10300 Settings.Global.putString( 10301 resolver, Settings.Global.DEBUG_APP, 10302 packageName); 10303 Settings.Global.putInt( 10304 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10305 waitForDebugger ? 1 : 0); 10306 } 10307 10308 synchronized (this) { 10309 if (!persistent) { 10310 mOrigDebugApp = mDebugApp; 10311 mOrigWaitForDebugger = mWaitForDebugger; 10312 } 10313 mDebugApp = packageName; 10314 mWaitForDebugger = waitForDebugger; 10315 mDebugTransient = !persistent; 10316 if (packageName != null) { 10317 forceStopPackageLocked(packageName, -1, false, false, true, true, 10318 false, UserHandle.USER_ALL, "set debug app"); 10319 } 10320 } 10321 } finally { 10322 Binder.restoreCallingIdentity(ident); 10323 } 10324 } 10325 10326 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10327 synchronized (this) { 10328 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10329 if (!isDebuggable) { 10330 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10331 throw new SecurityException("Process not debuggable: " + app.packageName); 10332 } 10333 } 10334 10335 mOpenGlTraceApp = processName; 10336 } 10337 } 10338 10339 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10340 synchronized (this) { 10341 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10342 if (!isDebuggable) { 10343 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10344 throw new SecurityException("Process not debuggable: " + app.packageName); 10345 } 10346 } 10347 mProfileApp = processName; 10348 mProfileFile = profilerInfo.profileFile; 10349 if (mProfileFd != null) { 10350 try { 10351 mProfileFd.close(); 10352 } catch (IOException e) { 10353 } 10354 mProfileFd = null; 10355 } 10356 mProfileFd = profilerInfo.profileFd; 10357 mSamplingInterval = profilerInfo.samplingInterval; 10358 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10359 mProfileType = 0; 10360 } 10361 } 10362 10363 @Override 10364 public void setAlwaysFinish(boolean enabled) { 10365 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10366 "setAlwaysFinish()"); 10367 10368 Settings.Global.putInt( 10369 mContext.getContentResolver(), 10370 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10371 10372 synchronized (this) { 10373 mAlwaysFinishActivities = enabled; 10374 } 10375 } 10376 10377 @Override 10378 public void setActivityController(IActivityController controller) { 10379 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10380 "setActivityController()"); 10381 synchronized (this) { 10382 mController = controller; 10383 Watchdog.getInstance().setActivityController(controller); 10384 } 10385 } 10386 10387 @Override 10388 public void setUserIsMonkey(boolean userIsMonkey) { 10389 synchronized (this) { 10390 synchronized (mPidsSelfLocked) { 10391 final int callingPid = Binder.getCallingPid(); 10392 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10393 if (precessRecord == null) { 10394 throw new SecurityException("Unknown process: " + callingPid); 10395 } 10396 if (precessRecord.instrumentationUiAutomationConnection == null) { 10397 throw new SecurityException("Only an instrumentation process " 10398 + "with a UiAutomation can call setUserIsMonkey"); 10399 } 10400 } 10401 mUserIsMonkey = userIsMonkey; 10402 } 10403 } 10404 10405 @Override 10406 public boolean isUserAMonkey() { 10407 synchronized (this) { 10408 // If there is a controller also implies the user is a monkey. 10409 return (mUserIsMonkey || mController != null); 10410 } 10411 } 10412 10413 public void requestBugReport() { 10414 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10415 SystemProperties.set("ctl.start", "bugreport"); 10416 } 10417 10418 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10419 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10420 } 10421 10422 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10423 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10424 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10425 } 10426 return KEY_DISPATCHING_TIMEOUT; 10427 } 10428 10429 @Override 10430 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10431 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10432 != PackageManager.PERMISSION_GRANTED) { 10433 throw new SecurityException("Requires permission " 10434 + android.Manifest.permission.FILTER_EVENTS); 10435 } 10436 ProcessRecord proc; 10437 long timeout; 10438 synchronized (this) { 10439 synchronized (mPidsSelfLocked) { 10440 proc = mPidsSelfLocked.get(pid); 10441 } 10442 timeout = getInputDispatchingTimeoutLocked(proc); 10443 } 10444 10445 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10446 return -1; 10447 } 10448 10449 return timeout; 10450 } 10451 10452 /** 10453 * Handle input dispatching timeouts. 10454 * Returns whether input dispatching should be aborted or not. 10455 */ 10456 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10457 final ActivityRecord activity, final ActivityRecord parent, 10458 final boolean aboveSystem, String reason) { 10459 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10460 != PackageManager.PERMISSION_GRANTED) { 10461 throw new SecurityException("Requires permission " 10462 + android.Manifest.permission.FILTER_EVENTS); 10463 } 10464 10465 final String annotation; 10466 if (reason == null) { 10467 annotation = "Input dispatching timed out"; 10468 } else { 10469 annotation = "Input dispatching timed out (" + reason + ")"; 10470 } 10471 10472 if (proc != null) { 10473 synchronized (this) { 10474 if (proc.debugging) { 10475 return false; 10476 } 10477 10478 if (mDidDexOpt) { 10479 // Give more time since we were dexopting. 10480 mDidDexOpt = false; 10481 return false; 10482 } 10483 10484 if (proc.instrumentationClass != null) { 10485 Bundle info = new Bundle(); 10486 info.putString("shortMsg", "keyDispatchingTimedOut"); 10487 info.putString("longMsg", annotation); 10488 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10489 return true; 10490 } 10491 } 10492 mHandler.post(new Runnable() { 10493 @Override 10494 public void run() { 10495 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10496 } 10497 }); 10498 } 10499 10500 return true; 10501 } 10502 10503 public Bundle getAssistContextExtras(int requestType) { 10504 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10505 UserHandle.getCallingUserId()); 10506 if (pae == null) { 10507 return null; 10508 } 10509 synchronized (pae) { 10510 while (!pae.haveResult) { 10511 try { 10512 pae.wait(); 10513 } catch (InterruptedException e) { 10514 } 10515 } 10516 if (pae.result != null) { 10517 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10518 } 10519 } 10520 synchronized (this) { 10521 mPendingAssistExtras.remove(pae); 10522 mHandler.removeCallbacks(pae); 10523 } 10524 return pae.extras; 10525 } 10526 10527 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10528 int userHandle) { 10529 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10530 "getAssistContextExtras()"); 10531 PendingAssistExtras pae; 10532 Bundle extras = new Bundle(); 10533 synchronized (this) { 10534 ActivityRecord activity = getFocusedStack().mResumedActivity; 10535 if (activity == null) { 10536 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10537 return null; 10538 } 10539 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10540 if (activity.app == null || activity.app.thread == null) { 10541 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10542 return null; 10543 } 10544 if (activity.app.pid == Binder.getCallingPid()) { 10545 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10546 return null; 10547 } 10548 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10549 try { 10550 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10551 requestType); 10552 mPendingAssistExtras.add(pae); 10553 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10554 } catch (RemoteException e) { 10555 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10556 return null; 10557 } 10558 return pae; 10559 } 10560 } 10561 10562 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10563 PendingAssistExtras pae = (PendingAssistExtras)token; 10564 synchronized (pae) { 10565 pae.result = extras; 10566 pae.haveResult = true; 10567 pae.notifyAll(); 10568 if (pae.intent == null) { 10569 // Caller is just waiting for the result. 10570 return; 10571 } 10572 } 10573 10574 // We are now ready to launch the assist activity. 10575 synchronized (this) { 10576 boolean exists = mPendingAssistExtras.remove(pae); 10577 mHandler.removeCallbacks(pae); 10578 if (!exists) { 10579 // Timed out. 10580 return; 10581 } 10582 } 10583 pae.intent.replaceExtras(extras); 10584 if (pae.hint != null) { 10585 pae.intent.putExtra(pae.hint, true); 10586 } 10587 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10588 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10589 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10590 closeSystemDialogs("assist"); 10591 try { 10592 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10593 } catch (ActivityNotFoundException e) { 10594 Slog.w(TAG, "No activity to handle assist action.", e); 10595 } 10596 } 10597 10598 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10599 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10600 } 10601 10602 public void registerProcessObserver(IProcessObserver observer) { 10603 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10604 "registerProcessObserver()"); 10605 synchronized (this) { 10606 mProcessObservers.register(observer); 10607 } 10608 } 10609 10610 @Override 10611 public void unregisterProcessObserver(IProcessObserver observer) { 10612 synchronized (this) { 10613 mProcessObservers.unregister(observer); 10614 } 10615 } 10616 10617 @Override 10618 public boolean convertFromTranslucent(IBinder token) { 10619 final long origId = Binder.clearCallingIdentity(); 10620 try { 10621 synchronized (this) { 10622 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10623 if (r == null) { 10624 return false; 10625 } 10626 final boolean translucentChanged = r.changeWindowTranslucency(true); 10627 if (translucentChanged) { 10628 r.task.stack.releaseBackgroundResources(); 10629 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10630 } 10631 mWindowManager.setAppFullscreen(token, true); 10632 return translucentChanged; 10633 } 10634 } finally { 10635 Binder.restoreCallingIdentity(origId); 10636 } 10637 } 10638 10639 @Override 10640 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10641 final long origId = Binder.clearCallingIdentity(); 10642 try { 10643 synchronized (this) { 10644 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10645 if (r == null) { 10646 return false; 10647 } 10648 int index = r.task.mActivities.lastIndexOf(r); 10649 if (index > 0) { 10650 ActivityRecord under = r.task.mActivities.get(index - 1); 10651 under.returningOptions = options; 10652 } 10653 final boolean translucentChanged = r.changeWindowTranslucency(false); 10654 if (translucentChanged) { 10655 r.task.stack.convertToTranslucent(r); 10656 } 10657 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10658 mWindowManager.setAppFullscreen(token, false); 10659 return translucentChanged; 10660 } 10661 } finally { 10662 Binder.restoreCallingIdentity(origId); 10663 } 10664 } 10665 10666 @Override 10667 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10668 final long origId = Binder.clearCallingIdentity(); 10669 try { 10670 synchronized (this) { 10671 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10672 if (r != null) { 10673 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10674 } 10675 } 10676 return false; 10677 } finally { 10678 Binder.restoreCallingIdentity(origId); 10679 } 10680 } 10681 10682 @Override 10683 public boolean isBackgroundVisibleBehind(IBinder token) { 10684 final long origId = Binder.clearCallingIdentity(); 10685 try { 10686 synchronized (this) { 10687 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10688 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10689 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10690 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10691 return visible; 10692 } 10693 } finally { 10694 Binder.restoreCallingIdentity(origId); 10695 } 10696 } 10697 10698 @Override 10699 public ActivityOptions getActivityOptions(IBinder token) { 10700 final long origId = Binder.clearCallingIdentity(); 10701 try { 10702 synchronized (this) { 10703 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10704 if (r != null) { 10705 final ActivityOptions activityOptions = r.pendingOptions; 10706 r.pendingOptions = null; 10707 return activityOptions; 10708 } 10709 return null; 10710 } 10711 } finally { 10712 Binder.restoreCallingIdentity(origId); 10713 } 10714 } 10715 10716 @Override 10717 public void setImmersive(IBinder token, boolean immersive) { 10718 synchronized(this) { 10719 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10720 if (r == null) { 10721 throw new IllegalArgumentException(); 10722 } 10723 r.immersive = immersive; 10724 10725 // update associated state if we're frontmost 10726 if (r == mFocusedActivity) { 10727 if (DEBUG_IMMERSIVE) { 10728 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10729 } 10730 applyUpdateLockStateLocked(r); 10731 } 10732 } 10733 } 10734 10735 @Override 10736 public boolean isImmersive(IBinder token) { 10737 synchronized (this) { 10738 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10739 if (r == null) { 10740 throw new IllegalArgumentException(); 10741 } 10742 return r.immersive; 10743 } 10744 } 10745 10746 public boolean isTopActivityImmersive() { 10747 enforceNotIsolatedCaller("startActivity"); 10748 synchronized (this) { 10749 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10750 return (r != null) ? r.immersive : false; 10751 } 10752 } 10753 10754 @Override 10755 public boolean isTopOfTask(IBinder token) { 10756 synchronized (this) { 10757 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10758 if (r == null) { 10759 throw new IllegalArgumentException(); 10760 } 10761 return r.task.getTopActivity() == r; 10762 } 10763 } 10764 10765 public final void enterSafeMode() { 10766 synchronized(this) { 10767 // It only makes sense to do this before the system is ready 10768 // and started launching other packages. 10769 if (!mSystemReady) { 10770 try { 10771 AppGlobals.getPackageManager().enterSafeMode(); 10772 } catch (RemoteException e) { 10773 } 10774 } 10775 10776 mSafeMode = true; 10777 } 10778 } 10779 10780 public final void showSafeModeOverlay() { 10781 View v = LayoutInflater.from(mContext).inflate( 10782 com.android.internal.R.layout.safe_mode, null); 10783 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10784 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10785 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10786 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10787 lp.gravity = Gravity.BOTTOM | Gravity.START; 10788 lp.format = v.getBackground().getOpacity(); 10789 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10790 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10791 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10792 ((WindowManager)mContext.getSystemService( 10793 Context.WINDOW_SERVICE)).addView(v, lp); 10794 } 10795 10796 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10797 if (!(sender instanceof PendingIntentRecord)) { 10798 return; 10799 } 10800 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10801 synchronized (stats) { 10802 if (mBatteryStatsService.isOnBattery()) { 10803 mBatteryStatsService.enforceCallingPermission(); 10804 PendingIntentRecord rec = (PendingIntentRecord)sender; 10805 int MY_UID = Binder.getCallingUid(); 10806 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10807 BatteryStatsImpl.Uid.Pkg pkg = 10808 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10809 sourcePkg != null ? sourcePkg : rec.key.packageName); 10810 pkg.incWakeupsLocked(); 10811 } 10812 } 10813 } 10814 10815 public boolean killPids(int[] pids, String pReason, boolean secure) { 10816 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10817 throw new SecurityException("killPids only available to the system"); 10818 } 10819 String reason = (pReason == null) ? "Unknown" : pReason; 10820 // XXX Note: don't acquire main activity lock here, because the window 10821 // manager calls in with its locks held. 10822 10823 boolean killed = false; 10824 synchronized (mPidsSelfLocked) { 10825 int[] types = new int[pids.length]; 10826 int worstType = 0; 10827 for (int i=0; i<pids.length; i++) { 10828 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10829 if (proc != null) { 10830 int type = proc.setAdj; 10831 types[i] = type; 10832 if (type > worstType) { 10833 worstType = type; 10834 } 10835 } 10836 } 10837 10838 // If the worst oom_adj is somewhere in the cached proc LRU range, 10839 // then constrain it so we will kill all cached procs. 10840 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10841 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10842 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10843 } 10844 10845 // If this is not a secure call, don't let it kill processes that 10846 // are important. 10847 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10848 worstType = ProcessList.SERVICE_ADJ; 10849 } 10850 10851 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10852 for (int i=0; i<pids.length; i++) { 10853 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10854 if (proc == null) { 10855 continue; 10856 } 10857 int adj = proc.setAdj; 10858 if (adj >= worstType && !proc.killedByAm) { 10859 proc.kill(reason, true); 10860 killed = true; 10861 } 10862 } 10863 } 10864 return killed; 10865 } 10866 10867 @Override 10868 public void killUid(int uid, String reason) { 10869 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10870 throw new SecurityException("killUid only available to the system"); 10871 } 10872 synchronized (this) { 10873 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10874 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10875 reason != null ? reason : "kill uid"); 10876 } 10877 } 10878 10879 @Override 10880 public boolean killProcessesBelowForeground(String reason) { 10881 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10882 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10883 } 10884 10885 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10886 } 10887 10888 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10889 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10890 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10891 } 10892 10893 boolean killed = false; 10894 synchronized (mPidsSelfLocked) { 10895 final int size = mPidsSelfLocked.size(); 10896 for (int i = 0; i < size; i++) { 10897 final int pid = mPidsSelfLocked.keyAt(i); 10898 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10899 if (proc == null) continue; 10900 10901 final int adj = proc.setAdj; 10902 if (adj > belowAdj && !proc.killedByAm) { 10903 proc.kill(reason, true); 10904 killed = true; 10905 } 10906 } 10907 } 10908 return killed; 10909 } 10910 10911 @Override 10912 public void hang(final IBinder who, boolean allowRestart) { 10913 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10914 != PackageManager.PERMISSION_GRANTED) { 10915 throw new SecurityException("Requires permission " 10916 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10917 } 10918 10919 final IBinder.DeathRecipient death = new DeathRecipient() { 10920 @Override 10921 public void binderDied() { 10922 synchronized (this) { 10923 notifyAll(); 10924 } 10925 } 10926 }; 10927 10928 try { 10929 who.linkToDeath(death, 0); 10930 } catch (RemoteException e) { 10931 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10932 return; 10933 } 10934 10935 synchronized (this) { 10936 Watchdog.getInstance().setAllowRestart(allowRestart); 10937 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10938 synchronized (death) { 10939 while (who.isBinderAlive()) { 10940 try { 10941 death.wait(); 10942 } catch (InterruptedException e) { 10943 } 10944 } 10945 } 10946 Watchdog.getInstance().setAllowRestart(true); 10947 } 10948 } 10949 10950 @Override 10951 public void restart() { 10952 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10953 != PackageManager.PERMISSION_GRANTED) { 10954 throw new SecurityException("Requires permission " 10955 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10956 } 10957 10958 Log.i(TAG, "Sending shutdown broadcast..."); 10959 10960 BroadcastReceiver br = new BroadcastReceiver() { 10961 @Override public void onReceive(Context context, Intent intent) { 10962 // Now the broadcast is done, finish up the low-level shutdown. 10963 Log.i(TAG, "Shutting down activity manager..."); 10964 shutdown(10000); 10965 Log.i(TAG, "Shutdown complete, restarting!"); 10966 Process.killProcess(Process.myPid()); 10967 System.exit(10); 10968 } 10969 }; 10970 10971 // First send the high-level shut down broadcast. 10972 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10973 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10974 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10975 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10976 mContext.sendOrderedBroadcastAsUser(intent, 10977 UserHandle.ALL, null, br, mHandler, 0, null, null); 10978 */ 10979 br.onReceive(mContext, intent); 10980 } 10981 10982 private long getLowRamTimeSinceIdle(long now) { 10983 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10984 } 10985 10986 @Override 10987 public void performIdleMaintenance() { 10988 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10989 != PackageManager.PERMISSION_GRANTED) { 10990 throw new SecurityException("Requires permission " 10991 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10992 } 10993 10994 synchronized (this) { 10995 final long now = SystemClock.uptimeMillis(); 10996 final long timeSinceLastIdle = now - mLastIdleTime; 10997 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10998 mLastIdleTime = now; 10999 mLowRamTimeSinceLastIdle = 0; 11000 if (mLowRamStartTime != 0) { 11001 mLowRamStartTime = now; 11002 } 11003 11004 StringBuilder sb = new StringBuilder(128); 11005 sb.append("Idle maintenance over "); 11006 TimeUtils.formatDuration(timeSinceLastIdle, sb); 11007 sb.append(" low RAM for "); 11008 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 11009 Slog.i(TAG, sb.toString()); 11010 11011 // If at least 1/3 of our time since the last idle period has been spent 11012 // with RAM low, then we want to kill processes. 11013 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 11014 11015 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11016 ProcessRecord proc = mLruProcesses.get(i); 11017 if (proc.notCachedSinceIdle) { 11018 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 11019 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 11020 if (doKilling && proc.initialIdlePss != 0 11021 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 11022 proc.kill("idle maint (pss " + proc.lastPss 11023 + " from " + proc.initialIdlePss + ")", true); 11024 } 11025 } 11026 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 11027 proc.notCachedSinceIdle = true; 11028 proc.initialIdlePss = 0; 11029 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 11030 isSleeping(), now); 11031 } 11032 } 11033 11034 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 11035 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 11036 } 11037 } 11038 11039 private void retrieveSettings() { 11040 final ContentResolver resolver = mContext.getContentResolver(); 11041 String debugApp = Settings.Global.getString( 11042 resolver, Settings.Global.DEBUG_APP); 11043 boolean waitForDebugger = Settings.Global.getInt( 11044 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11045 boolean alwaysFinishActivities = Settings.Global.getInt( 11046 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11047 boolean forceRtl = Settings.Global.getInt( 11048 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11049 // Transfer any global setting for forcing RTL layout, into a System Property 11050 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11051 11052 Configuration configuration = new Configuration(); 11053 Settings.System.getConfiguration(resolver, configuration); 11054 if (forceRtl) { 11055 // This will take care of setting the correct layout direction flags 11056 configuration.setLayoutDirection(configuration.locale); 11057 } 11058 11059 synchronized (this) { 11060 mDebugApp = mOrigDebugApp = debugApp; 11061 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11062 mAlwaysFinishActivities = alwaysFinishActivities; 11063 // This happens before any activities are started, so we can 11064 // change mConfiguration in-place. 11065 updateConfigurationLocked(configuration, null, false, true); 11066 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11067 } 11068 } 11069 11070 /** Loads resources after the current configuration has been set. */ 11071 private void loadResourcesOnSystemReady() { 11072 final Resources res = mContext.getResources(); 11073 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11074 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11075 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11076 } 11077 11078 public boolean testIsSystemReady() { 11079 // no need to synchronize(this) just to read & return the value 11080 return mSystemReady; 11081 } 11082 11083 private static File getCalledPreBootReceiversFile() { 11084 File dataDir = Environment.getDataDirectory(); 11085 File systemDir = new File(dataDir, "system"); 11086 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11087 return fname; 11088 } 11089 11090 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11091 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11092 File file = getCalledPreBootReceiversFile(); 11093 FileInputStream fis = null; 11094 try { 11095 fis = new FileInputStream(file); 11096 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11097 int fvers = dis.readInt(); 11098 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11099 String vers = dis.readUTF(); 11100 String codename = dis.readUTF(); 11101 String build = dis.readUTF(); 11102 if (android.os.Build.VERSION.RELEASE.equals(vers) 11103 && android.os.Build.VERSION.CODENAME.equals(codename) 11104 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11105 int num = dis.readInt(); 11106 while (num > 0) { 11107 num--; 11108 String pkg = dis.readUTF(); 11109 String cls = dis.readUTF(); 11110 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11111 } 11112 } 11113 } 11114 } catch (FileNotFoundException e) { 11115 } catch (IOException e) { 11116 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11117 } finally { 11118 if (fis != null) { 11119 try { 11120 fis.close(); 11121 } catch (IOException e) { 11122 } 11123 } 11124 } 11125 return lastDoneReceivers; 11126 } 11127 11128 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11129 File file = getCalledPreBootReceiversFile(); 11130 FileOutputStream fos = null; 11131 DataOutputStream dos = null; 11132 try { 11133 fos = new FileOutputStream(file); 11134 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11135 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11136 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11137 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11138 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11139 dos.writeInt(list.size()); 11140 for (int i=0; i<list.size(); i++) { 11141 dos.writeUTF(list.get(i).getPackageName()); 11142 dos.writeUTF(list.get(i).getClassName()); 11143 } 11144 } catch (IOException e) { 11145 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11146 file.delete(); 11147 } finally { 11148 FileUtils.sync(fos); 11149 if (dos != null) { 11150 try { 11151 dos.close(); 11152 } catch (IOException e) { 11153 // TODO Auto-generated catch block 11154 e.printStackTrace(); 11155 } 11156 } 11157 } 11158 } 11159 11160 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11161 ArrayList<ComponentName> doneReceivers, int userId) { 11162 boolean waitingUpdate = false; 11163 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11164 List<ResolveInfo> ris = null; 11165 try { 11166 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11167 intent, null, 0, userId); 11168 } catch (RemoteException e) { 11169 } 11170 if (ris != null) { 11171 for (int i=ris.size()-1; i>=0; i--) { 11172 if ((ris.get(i).activityInfo.applicationInfo.flags 11173 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11174 ris.remove(i); 11175 } 11176 } 11177 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11178 11179 // For User 0, load the version number. When delivering to a new user, deliver 11180 // to all receivers. 11181 if (userId == UserHandle.USER_OWNER) { 11182 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11183 for (int i=0; i<ris.size(); i++) { 11184 ActivityInfo ai = ris.get(i).activityInfo; 11185 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11186 if (lastDoneReceivers.contains(comp)) { 11187 // We already did the pre boot receiver for this app with the current 11188 // platform version, so don't do it again... 11189 ris.remove(i); 11190 i--; 11191 // ...however, do keep it as one that has been done, so we don't 11192 // forget about it when rewriting the file of last done receivers. 11193 doneReceivers.add(comp); 11194 } 11195 } 11196 } 11197 11198 // If primary user, send broadcast to all available users, else just to userId 11199 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11200 : new int[] { userId }; 11201 for (int i = 0; i < ris.size(); i++) { 11202 ActivityInfo ai = ris.get(i).activityInfo; 11203 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11204 doneReceivers.add(comp); 11205 intent.setComponent(comp); 11206 for (int j=0; j<users.length; j++) { 11207 IIntentReceiver finisher = null; 11208 // On last receiver and user, set up a completion callback 11209 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11210 finisher = new IIntentReceiver.Stub() { 11211 public void performReceive(Intent intent, int resultCode, 11212 String data, Bundle extras, boolean ordered, 11213 boolean sticky, int sendingUser) { 11214 // The raw IIntentReceiver interface is called 11215 // with the AM lock held, so redispatch to 11216 // execute our code without the lock. 11217 mHandler.post(onFinishCallback); 11218 } 11219 }; 11220 } 11221 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11222 + " for user " + users[j]); 11223 broadcastIntentLocked(null, null, intent, null, finisher, 11224 0, null, null, null, AppOpsManager.OP_NONE, 11225 true, false, MY_PID, Process.SYSTEM_UID, 11226 users[j]); 11227 if (finisher != null) { 11228 waitingUpdate = true; 11229 } 11230 } 11231 } 11232 } 11233 11234 return waitingUpdate; 11235 } 11236 11237 public void systemReady(final Runnable goingCallback) { 11238 synchronized(this) { 11239 if (mSystemReady) { 11240 // If we're done calling all the receivers, run the next "boot phase" passed in 11241 // by the SystemServer 11242 if (goingCallback != null) { 11243 goingCallback.run(); 11244 } 11245 return; 11246 } 11247 11248 // Make sure we have the current profile info, since it is needed for 11249 // security checks. 11250 updateCurrentProfileIdsLocked(); 11251 11252 if (mRecentTasks == null) { 11253 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11254 if (!mRecentTasks.isEmpty()) { 11255 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11256 } 11257 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11258 mTaskPersister.startPersisting(); 11259 } 11260 11261 // Check to see if there are any update receivers to run. 11262 if (!mDidUpdate) { 11263 if (mWaitingUpdate) { 11264 return; 11265 } 11266 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11267 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11268 public void run() { 11269 synchronized (ActivityManagerService.this) { 11270 mDidUpdate = true; 11271 } 11272 writeLastDonePreBootReceivers(doneReceivers); 11273 showBootMessage(mContext.getText( 11274 R.string.android_upgrading_complete), 11275 false); 11276 systemReady(goingCallback); 11277 } 11278 }, doneReceivers, UserHandle.USER_OWNER); 11279 11280 if (mWaitingUpdate) { 11281 return; 11282 } 11283 mDidUpdate = true; 11284 } 11285 11286 mAppOpsService.systemReady(); 11287 mSystemReady = true; 11288 } 11289 11290 ArrayList<ProcessRecord> procsToKill = null; 11291 synchronized(mPidsSelfLocked) { 11292 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11293 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11294 if (!isAllowedWhileBooting(proc.info)){ 11295 if (procsToKill == null) { 11296 procsToKill = new ArrayList<ProcessRecord>(); 11297 } 11298 procsToKill.add(proc); 11299 } 11300 } 11301 } 11302 11303 synchronized(this) { 11304 if (procsToKill != null) { 11305 for (int i=procsToKill.size()-1; i>=0; i--) { 11306 ProcessRecord proc = procsToKill.get(i); 11307 Slog.i(TAG, "Removing system update proc: " + proc); 11308 removeProcessLocked(proc, true, false, "system update done"); 11309 } 11310 } 11311 11312 // Now that we have cleaned up any update processes, we 11313 // are ready to start launching real processes and know that 11314 // we won't trample on them any more. 11315 mProcessesReady = true; 11316 } 11317 11318 Slog.i(TAG, "System now ready"); 11319 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11320 SystemClock.uptimeMillis()); 11321 11322 synchronized(this) { 11323 // Make sure we have no pre-ready processes sitting around. 11324 11325 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11326 ResolveInfo ri = mContext.getPackageManager() 11327 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11328 STOCK_PM_FLAGS); 11329 CharSequence errorMsg = null; 11330 if (ri != null) { 11331 ActivityInfo ai = ri.activityInfo; 11332 ApplicationInfo app = ai.applicationInfo; 11333 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11334 mTopAction = Intent.ACTION_FACTORY_TEST; 11335 mTopData = null; 11336 mTopComponent = new ComponentName(app.packageName, 11337 ai.name); 11338 } else { 11339 errorMsg = mContext.getResources().getText( 11340 com.android.internal.R.string.factorytest_not_system); 11341 } 11342 } else { 11343 errorMsg = mContext.getResources().getText( 11344 com.android.internal.R.string.factorytest_no_action); 11345 } 11346 if (errorMsg != null) { 11347 mTopAction = null; 11348 mTopData = null; 11349 mTopComponent = null; 11350 Message msg = Message.obtain(); 11351 msg.what = SHOW_FACTORY_ERROR_MSG; 11352 msg.getData().putCharSequence("msg", errorMsg); 11353 mHandler.sendMessage(msg); 11354 } 11355 } 11356 } 11357 11358 retrieveSettings(); 11359 loadResourcesOnSystemReady(); 11360 11361 synchronized (this) { 11362 readGrantedUriPermissionsLocked(); 11363 } 11364 11365 if (goingCallback != null) goingCallback.run(); 11366 11367 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11368 Integer.toString(mCurrentUserId), mCurrentUserId); 11369 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11370 Integer.toString(mCurrentUserId), mCurrentUserId); 11371 mSystemServiceManager.startUser(mCurrentUserId); 11372 11373 synchronized (this) { 11374 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11375 try { 11376 List apps = AppGlobals.getPackageManager(). 11377 getPersistentApplications(STOCK_PM_FLAGS); 11378 if (apps != null) { 11379 int N = apps.size(); 11380 int i; 11381 for (i=0; i<N; i++) { 11382 ApplicationInfo info 11383 = (ApplicationInfo)apps.get(i); 11384 if (info != null && 11385 !info.packageName.equals("android")) { 11386 addAppLocked(info, false, null /* ABI override */); 11387 } 11388 } 11389 } 11390 } catch (RemoteException ex) { 11391 // pm is in same process, this will never happen. 11392 } 11393 } 11394 11395 // Start up initial activity. 11396 mBooting = true; 11397 startHomeActivityLocked(mCurrentUserId); 11398 11399 try { 11400 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11401 Message msg = Message.obtain(); 11402 msg.what = SHOW_UID_ERROR_MSG; 11403 mHandler.sendMessage(msg); 11404 } 11405 } catch (RemoteException e) { 11406 } 11407 11408 long ident = Binder.clearCallingIdentity(); 11409 try { 11410 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11411 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11412 | Intent.FLAG_RECEIVER_FOREGROUND); 11413 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11414 broadcastIntentLocked(null, null, intent, 11415 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11416 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11417 intent = new Intent(Intent.ACTION_USER_STARTING); 11418 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11419 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11420 broadcastIntentLocked(null, null, intent, 11421 null, new IIntentReceiver.Stub() { 11422 @Override 11423 public void performReceive(Intent intent, int resultCode, String data, 11424 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11425 throws RemoteException { 11426 } 11427 }, 0, null, null, 11428 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11429 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11430 } catch (Throwable t) { 11431 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11432 } finally { 11433 Binder.restoreCallingIdentity(ident); 11434 } 11435 mStackSupervisor.resumeTopActivitiesLocked(); 11436 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11437 } 11438 } 11439 11440 private boolean makeAppCrashingLocked(ProcessRecord app, 11441 String shortMsg, String longMsg, String stackTrace) { 11442 app.crashing = true; 11443 app.crashingReport = generateProcessError(app, 11444 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11445 startAppProblemLocked(app); 11446 app.stopFreezingAllLocked(); 11447 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11448 } 11449 11450 private void makeAppNotRespondingLocked(ProcessRecord app, 11451 String activity, String shortMsg, String longMsg) { 11452 app.notResponding = true; 11453 app.notRespondingReport = generateProcessError(app, 11454 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11455 activity, shortMsg, longMsg, null); 11456 startAppProblemLocked(app); 11457 app.stopFreezingAllLocked(); 11458 } 11459 11460 /** 11461 * Generate a process error record, suitable for attachment to a ProcessRecord. 11462 * 11463 * @param app The ProcessRecord in which the error occurred. 11464 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11465 * ActivityManager.AppErrorStateInfo 11466 * @param activity The activity associated with the crash, if known. 11467 * @param shortMsg Short message describing the crash. 11468 * @param longMsg Long message describing the crash. 11469 * @param stackTrace Full crash stack trace, may be null. 11470 * 11471 * @return Returns a fully-formed AppErrorStateInfo record. 11472 */ 11473 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11474 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11475 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11476 11477 report.condition = condition; 11478 report.processName = app.processName; 11479 report.pid = app.pid; 11480 report.uid = app.info.uid; 11481 report.tag = activity; 11482 report.shortMsg = shortMsg; 11483 report.longMsg = longMsg; 11484 report.stackTrace = stackTrace; 11485 11486 return report; 11487 } 11488 11489 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11490 synchronized (this) { 11491 app.crashing = false; 11492 app.crashingReport = null; 11493 app.notResponding = false; 11494 app.notRespondingReport = null; 11495 if (app.anrDialog == fromDialog) { 11496 app.anrDialog = null; 11497 } 11498 if (app.waitDialog == fromDialog) { 11499 app.waitDialog = null; 11500 } 11501 if (app.pid > 0 && app.pid != MY_PID) { 11502 handleAppCrashLocked(app, null, null, null); 11503 app.kill("user request after error", true); 11504 } 11505 } 11506 } 11507 11508 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11509 String stackTrace) { 11510 long now = SystemClock.uptimeMillis(); 11511 11512 Long crashTime; 11513 if (!app.isolated) { 11514 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11515 } else { 11516 crashTime = null; 11517 } 11518 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11519 // This process loses! 11520 Slog.w(TAG, "Process " + app.info.processName 11521 + " has crashed too many times: killing!"); 11522 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11523 app.userId, app.info.processName, app.uid); 11524 mStackSupervisor.handleAppCrashLocked(app); 11525 if (!app.persistent) { 11526 // We don't want to start this process again until the user 11527 // explicitly does so... but for persistent process, we really 11528 // need to keep it running. If a persistent process is actually 11529 // repeatedly crashing, then badness for everyone. 11530 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11531 app.info.processName); 11532 if (!app.isolated) { 11533 // XXX We don't have a way to mark isolated processes 11534 // as bad, since they don't have a peristent identity. 11535 mBadProcesses.put(app.info.processName, app.uid, 11536 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11537 mProcessCrashTimes.remove(app.info.processName, app.uid); 11538 } 11539 app.bad = true; 11540 app.removed = true; 11541 // Don't let services in this process be restarted and potentially 11542 // annoy the user repeatedly. Unless it is persistent, since those 11543 // processes run critical code. 11544 removeProcessLocked(app, false, false, "crash"); 11545 mStackSupervisor.resumeTopActivitiesLocked(); 11546 return false; 11547 } 11548 mStackSupervisor.resumeTopActivitiesLocked(); 11549 } else { 11550 mStackSupervisor.finishTopRunningActivityLocked(app); 11551 } 11552 11553 // Bump up the crash count of any services currently running in the proc. 11554 for (int i=app.services.size()-1; i>=0; i--) { 11555 // Any services running in the application need to be placed 11556 // back in the pending list. 11557 ServiceRecord sr = app.services.valueAt(i); 11558 sr.crashCount++; 11559 } 11560 11561 // If the crashing process is what we consider to be the "home process" and it has been 11562 // replaced by a third-party app, clear the package preferred activities from packages 11563 // with a home activity running in the process to prevent a repeatedly crashing app 11564 // from blocking the user to manually clear the list. 11565 final ArrayList<ActivityRecord> activities = app.activities; 11566 if (app == mHomeProcess && activities.size() > 0 11567 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11568 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11569 final ActivityRecord r = activities.get(activityNdx); 11570 if (r.isHomeActivity()) { 11571 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11572 try { 11573 ActivityThread.getPackageManager() 11574 .clearPackagePreferredActivities(r.packageName); 11575 } catch (RemoteException c) { 11576 // pm is in same process, this will never happen. 11577 } 11578 } 11579 } 11580 } 11581 11582 if (!app.isolated) { 11583 // XXX Can't keep track of crash times for isolated processes, 11584 // because they don't have a perisistent identity. 11585 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11586 } 11587 11588 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11589 return true; 11590 } 11591 11592 void startAppProblemLocked(ProcessRecord app) { 11593 // If this app is not running under the current user, then we 11594 // can't give it a report button because that would require 11595 // launching the report UI under a different user. 11596 app.errorReportReceiver = null; 11597 11598 for (int userId : mCurrentProfileIds) { 11599 if (app.userId == userId) { 11600 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11601 mContext, app.info.packageName, app.info.flags); 11602 } 11603 } 11604 skipCurrentReceiverLocked(app); 11605 } 11606 11607 void skipCurrentReceiverLocked(ProcessRecord app) { 11608 for (BroadcastQueue queue : mBroadcastQueues) { 11609 queue.skipCurrentReceiverLocked(app); 11610 } 11611 } 11612 11613 /** 11614 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11615 * The application process will exit immediately after this call returns. 11616 * @param app object of the crashing app, null for the system server 11617 * @param crashInfo describing the exception 11618 */ 11619 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11620 ProcessRecord r = findAppProcess(app, "Crash"); 11621 final String processName = app == null ? "system_server" 11622 : (r == null ? "unknown" : r.processName); 11623 11624 handleApplicationCrashInner("crash", r, processName, crashInfo); 11625 } 11626 11627 /* Native crash reporting uses this inner version because it needs to be somewhat 11628 * decoupled from the AM-managed cleanup lifecycle 11629 */ 11630 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11631 ApplicationErrorReport.CrashInfo crashInfo) { 11632 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11633 UserHandle.getUserId(Binder.getCallingUid()), processName, 11634 r == null ? -1 : r.info.flags, 11635 crashInfo.exceptionClassName, 11636 crashInfo.exceptionMessage, 11637 crashInfo.throwFileName, 11638 crashInfo.throwLineNumber); 11639 11640 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11641 11642 crashApplication(r, crashInfo); 11643 } 11644 11645 public void handleApplicationStrictModeViolation( 11646 IBinder app, 11647 int violationMask, 11648 StrictMode.ViolationInfo info) { 11649 ProcessRecord r = findAppProcess(app, "StrictMode"); 11650 if (r == null) { 11651 return; 11652 } 11653 11654 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11655 Integer stackFingerprint = info.hashCode(); 11656 boolean logIt = true; 11657 synchronized (mAlreadyLoggedViolatedStacks) { 11658 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11659 logIt = false; 11660 // TODO: sub-sample into EventLog for these, with 11661 // the info.durationMillis? Then we'd get 11662 // the relative pain numbers, without logging all 11663 // the stack traces repeatedly. We'd want to do 11664 // likewise in the client code, which also does 11665 // dup suppression, before the Binder call. 11666 } else { 11667 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11668 mAlreadyLoggedViolatedStacks.clear(); 11669 } 11670 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11671 } 11672 } 11673 if (logIt) { 11674 logStrictModeViolationToDropBox(r, info); 11675 } 11676 } 11677 11678 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11679 AppErrorResult result = new AppErrorResult(); 11680 synchronized (this) { 11681 final long origId = Binder.clearCallingIdentity(); 11682 11683 Message msg = Message.obtain(); 11684 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11685 HashMap<String, Object> data = new HashMap<String, Object>(); 11686 data.put("result", result); 11687 data.put("app", r); 11688 data.put("violationMask", violationMask); 11689 data.put("info", info); 11690 msg.obj = data; 11691 mHandler.sendMessage(msg); 11692 11693 Binder.restoreCallingIdentity(origId); 11694 } 11695 int res = result.get(); 11696 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11697 } 11698 } 11699 11700 // Depending on the policy in effect, there could be a bunch of 11701 // these in quick succession so we try to batch these together to 11702 // minimize disk writes, number of dropbox entries, and maximize 11703 // compression, by having more fewer, larger records. 11704 private void logStrictModeViolationToDropBox( 11705 ProcessRecord process, 11706 StrictMode.ViolationInfo info) { 11707 if (info == null) { 11708 return; 11709 } 11710 final boolean isSystemApp = process == null || 11711 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11712 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11713 final String processName = process == null ? "unknown" : process.processName; 11714 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11715 final DropBoxManager dbox = (DropBoxManager) 11716 mContext.getSystemService(Context.DROPBOX_SERVICE); 11717 11718 // Exit early if the dropbox isn't configured to accept this report type. 11719 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11720 11721 boolean bufferWasEmpty; 11722 boolean needsFlush; 11723 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11724 synchronized (sb) { 11725 bufferWasEmpty = sb.length() == 0; 11726 appendDropBoxProcessHeaders(process, processName, sb); 11727 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11728 sb.append("System-App: ").append(isSystemApp).append("\n"); 11729 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11730 if (info.violationNumThisLoop != 0) { 11731 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11732 } 11733 if (info.numAnimationsRunning != 0) { 11734 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11735 } 11736 if (info.broadcastIntentAction != null) { 11737 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11738 } 11739 if (info.durationMillis != -1) { 11740 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11741 } 11742 if (info.numInstances != -1) { 11743 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11744 } 11745 if (info.tags != null) { 11746 for (String tag : info.tags) { 11747 sb.append("Span-Tag: ").append(tag).append("\n"); 11748 } 11749 } 11750 sb.append("\n"); 11751 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11752 sb.append(info.crashInfo.stackTrace); 11753 sb.append("\n"); 11754 } 11755 if (info.message != null) { 11756 sb.append(info.message); 11757 sb.append("\n"); 11758 } 11759 11760 // Only buffer up to ~64k. Various logging bits truncate 11761 // things at 128k. 11762 needsFlush = (sb.length() > 64 * 1024); 11763 } 11764 11765 // Flush immediately if the buffer's grown too large, or this 11766 // is a non-system app. Non-system apps are isolated with a 11767 // different tag & policy and not batched. 11768 // 11769 // Batching is useful during internal testing with 11770 // StrictMode settings turned up high. Without batching, 11771 // thousands of separate files could be created on boot. 11772 if (!isSystemApp || needsFlush) { 11773 new Thread("Error dump: " + dropboxTag) { 11774 @Override 11775 public void run() { 11776 String report; 11777 synchronized (sb) { 11778 report = sb.toString(); 11779 sb.delete(0, sb.length()); 11780 sb.trimToSize(); 11781 } 11782 if (report.length() != 0) { 11783 dbox.addText(dropboxTag, report); 11784 } 11785 } 11786 }.start(); 11787 return; 11788 } 11789 11790 // System app batching: 11791 if (!bufferWasEmpty) { 11792 // An existing dropbox-writing thread is outstanding, so 11793 // we don't need to start it up. The existing thread will 11794 // catch the buffer appends we just did. 11795 return; 11796 } 11797 11798 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11799 // (After this point, we shouldn't access AMS internal data structures.) 11800 new Thread("Error dump: " + dropboxTag) { 11801 @Override 11802 public void run() { 11803 // 5 second sleep to let stacks arrive and be batched together 11804 try { 11805 Thread.sleep(5000); // 5 seconds 11806 } catch (InterruptedException e) {} 11807 11808 String errorReport; 11809 synchronized (mStrictModeBuffer) { 11810 errorReport = mStrictModeBuffer.toString(); 11811 if (errorReport.length() == 0) { 11812 return; 11813 } 11814 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11815 mStrictModeBuffer.trimToSize(); 11816 } 11817 dbox.addText(dropboxTag, errorReport); 11818 } 11819 }.start(); 11820 } 11821 11822 /** 11823 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11824 * @param app object of the crashing app, null for the system server 11825 * @param tag reported by the caller 11826 * @param system whether this wtf is coming from the system 11827 * @param crashInfo describing the context of the error 11828 * @return true if the process should exit immediately (WTF is fatal) 11829 */ 11830 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11831 final ApplicationErrorReport.CrashInfo crashInfo) { 11832 final int callingUid = Binder.getCallingUid(); 11833 final int callingPid = Binder.getCallingPid(); 11834 11835 if (system) { 11836 // If this is coming from the system, we could very well have low-level 11837 // system locks held, so we want to do this all asynchronously. And we 11838 // never want this to become fatal, so there is that too. 11839 mHandler.post(new Runnable() { 11840 @Override public void run() { 11841 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11842 } 11843 }); 11844 return false; 11845 } 11846 11847 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11848 crashInfo); 11849 11850 if (r != null && r.pid != Process.myPid() && 11851 Settings.Global.getInt(mContext.getContentResolver(), 11852 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11853 crashApplication(r, crashInfo); 11854 return true; 11855 } else { 11856 return false; 11857 } 11858 } 11859 11860 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11861 final ApplicationErrorReport.CrashInfo crashInfo) { 11862 final ProcessRecord r = findAppProcess(app, "WTF"); 11863 final String processName = app == null ? "system_server" 11864 : (r == null ? "unknown" : r.processName); 11865 11866 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11867 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11868 11869 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11870 11871 return r; 11872 } 11873 11874 /** 11875 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11876 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11877 */ 11878 private ProcessRecord findAppProcess(IBinder app, String reason) { 11879 if (app == null) { 11880 return null; 11881 } 11882 11883 synchronized (this) { 11884 final int NP = mProcessNames.getMap().size(); 11885 for (int ip=0; ip<NP; ip++) { 11886 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11887 final int NA = apps.size(); 11888 for (int ia=0; ia<NA; ia++) { 11889 ProcessRecord p = apps.valueAt(ia); 11890 if (p.thread != null && p.thread.asBinder() == app) { 11891 return p; 11892 } 11893 } 11894 } 11895 11896 Slog.w(TAG, "Can't find mystery application for " + reason 11897 + " from pid=" + Binder.getCallingPid() 11898 + " uid=" + Binder.getCallingUid() + ": " + app); 11899 return null; 11900 } 11901 } 11902 11903 /** 11904 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11905 * to append various headers to the dropbox log text. 11906 */ 11907 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11908 StringBuilder sb) { 11909 // Watchdog thread ends up invoking this function (with 11910 // a null ProcessRecord) to add the stack file to dropbox. 11911 // Do not acquire a lock on this (am) in such cases, as it 11912 // could cause a potential deadlock, if and when watchdog 11913 // is invoked due to unavailability of lock on am and it 11914 // would prevent watchdog from killing system_server. 11915 if (process == null) { 11916 sb.append("Process: ").append(processName).append("\n"); 11917 return; 11918 } 11919 // Note: ProcessRecord 'process' is guarded by the service 11920 // instance. (notably process.pkgList, which could otherwise change 11921 // concurrently during execution of this method) 11922 synchronized (this) { 11923 sb.append("Process: ").append(processName).append("\n"); 11924 int flags = process.info.flags; 11925 IPackageManager pm = AppGlobals.getPackageManager(); 11926 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11927 for (int ip=0; ip<process.pkgList.size(); ip++) { 11928 String pkg = process.pkgList.keyAt(ip); 11929 sb.append("Package: ").append(pkg); 11930 try { 11931 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11932 if (pi != null) { 11933 sb.append(" v").append(pi.versionCode); 11934 if (pi.versionName != null) { 11935 sb.append(" (").append(pi.versionName).append(")"); 11936 } 11937 } 11938 } catch (RemoteException e) { 11939 Slog.e(TAG, "Error getting package info: " + pkg, e); 11940 } 11941 sb.append("\n"); 11942 } 11943 } 11944 } 11945 11946 private static String processClass(ProcessRecord process) { 11947 if (process == null || process.pid == MY_PID) { 11948 return "system_server"; 11949 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11950 return "system_app"; 11951 } else { 11952 return "data_app"; 11953 } 11954 } 11955 11956 /** 11957 * Write a description of an error (crash, WTF, ANR) to the drop box. 11958 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11959 * @param process which caused the error, null means the system server 11960 * @param activity which triggered the error, null if unknown 11961 * @param parent activity related to the error, null if unknown 11962 * @param subject line related to the error, null if absent 11963 * @param report in long form describing the error, null if absent 11964 * @param logFile to include in the report, null if none 11965 * @param crashInfo giving an application stack trace, null if absent 11966 */ 11967 public void addErrorToDropBox(String eventType, 11968 ProcessRecord process, String processName, ActivityRecord activity, 11969 ActivityRecord parent, String subject, 11970 final String report, final File logFile, 11971 final ApplicationErrorReport.CrashInfo crashInfo) { 11972 // NOTE -- this must never acquire the ActivityManagerService lock, 11973 // otherwise the watchdog may be prevented from resetting the system. 11974 11975 final String dropboxTag = processClass(process) + "_" + eventType; 11976 final DropBoxManager dbox = (DropBoxManager) 11977 mContext.getSystemService(Context.DROPBOX_SERVICE); 11978 11979 // Exit early if the dropbox isn't configured to accept this report type. 11980 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11981 11982 final StringBuilder sb = new StringBuilder(1024); 11983 appendDropBoxProcessHeaders(process, processName, sb); 11984 if (activity != null) { 11985 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11986 } 11987 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11988 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11989 } 11990 if (parent != null && parent != activity) { 11991 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11992 } 11993 if (subject != null) { 11994 sb.append("Subject: ").append(subject).append("\n"); 11995 } 11996 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11997 if (Debug.isDebuggerConnected()) { 11998 sb.append("Debugger: Connected\n"); 11999 } 12000 sb.append("\n"); 12001 12002 // Do the rest in a worker thread to avoid blocking the caller on I/O 12003 // (After this point, we shouldn't access AMS internal data structures.) 12004 Thread worker = new Thread("Error dump: " + dropboxTag) { 12005 @Override 12006 public void run() { 12007 if (report != null) { 12008 sb.append(report); 12009 } 12010 if (logFile != null) { 12011 try { 12012 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 12013 "\n\n[[TRUNCATED]]")); 12014 } catch (IOException e) { 12015 Slog.e(TAG, "Error reading " + logFile, e); 12016 } 12017 } 12018 if (crashInfo != null && crashInfo.stackTrace != null) { 12019 sb.append(crashInfo.stackTrace); 12020 } 12021 12022 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 12023 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 12024 if (lines > 0) { 12025 sb.append("\n"); 12026 12027 // Merge several logcat streams, and take the last N lines 12028 InputStreamReader input = null; 12029 try { 12030 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 12031 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 12032 "-b", "crash", 12033 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 12034 12035 try { logcat.getOutputStream().close(); } catch (IOException e) {} 12036 try { logcat.getErrorStream().close(); } catch (IOException e) {} 12037 input = new InputStreamReader(logcat.getInputStream()); 12038 12039 int num; 12040 char[] buf = new char[8192]; 12041 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 12042 } catch (IOException e) { 12043 Slog.e(TAG, "Error running logcat", e); 12044 } finally { 12045 if (input != null) try { input.close(); } catch (IOException e) {} 12046 } 12047 } 12048 12049 dbox.addText(dropboxTag, sb.toString()); 12050 } 12051 }; 12052 12053 if (process == null) { 12054 // If process is null, we are being called from some internal code 12055 // and may be about to die -- run this synchronously. 12056 worker.run(); 12057 } else { 12058 worker.start(); 12059 } 12060 } 12061 12062 /** 12063 * Bring up the "unexpected error" dialog box for a crashing app. 12064 * Deal with edge cases (intercepts from instrumented applications, 12065 * ActivityController, error intent receivers, that sort of thing). 12066 * @param r the application crashing 12067 * @param crashInfo describing the failure 12068 */ 12069 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12070 long timeMillis = System.currentTimeMillis(); 12071 String shortMsg = crashInfo.exceptionClassName; 12072 String longMsg = crashInfo.exceptionMessage; 12073 String stackTrace = crashInfo.stackTrace; 12074 if (shortMsg != null && longMsg != null) { 12075 longMsg = shortMsg + ": " + longMsg; 12076 } else if (shortMsg != null) { 12077 longMsg = shortMsg; 12078 } 12079 12080 AppErrorResult result = new AppErrorResult(); 12081 synchronized (this) { 12082 if (mController != null) { 12083 try { 12084 String name = r != null ? r.processName : null; 12085 int pid = r != null ? r.pid : Binder.getCallingPid(); 12086 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12087 if (!mController.appCrashed(name, pid, 12088 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12089 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12090 && "Native crash".equals(crashInfo.exceptionClassName)) { 12091 Slog.w(TAG, "Skip killing native crashed app " + name 12092 + "(" + pid + ") during testing"); 12093 } else { 12094 Slog.w(TAG, "Force-killing crashed app " + name 12095 + " at watcher's request"); 12096 if (r != null) { 12097 r.kill("crash", true); 12098 } else { 12099 // Huh. 12100 Process.killProcess(pid); 12101 Process.killProcessGroup(uid, pid); 12102 } 12103 } 12104 return; 12105 } 12106 } catch (RemoteException e) { 12107 mController = null; 12108 Watchdog.getInstance().setActivityController(null); 12109 } 12110 } 12111 12112 final long origId = Binder.clearCallingIdentity(); 12113 12114 // If this process is running instrumentation, finish it. 12115 if (r != null && r.instrumentationClass != null) { 12116 Slog.w(TAG, "Error in app " + r.processName 12117 + " running instrumentation " + r.instrumentationClass + ":"); 12118 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12119 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12120 Bundle info = new Bundle(); 12121 info.putString("shortMsg", shortMsg); 12122 info.putString("longMsg", longMsg); 12123 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12124 Binder.restoreCallingIdentity(origId); 12125 return; 12126 } 12127 12128 // If we can't identify the process or it's already exceeded its crash quota, 12129 // quit right away without showing a crash dialog. 12130 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12131 Binder.restoreCallingIdentity(origId); 12132 return; 12133 } 12134 12135 Message msg = Message.obtain(); 12136 msg.what = SHOW_ERROR_MSG; 12137 HashMap data = new HashMap(); 12138 data.put("result", result); 12139 data.put("app", r); 12140 msg.obj = data; 12141 mHandler.sendMessage(msg); 12142 12143 Binder.restoreCallingIdentity(origId); 12144 } 12145 12146 int res = result.get(); 12147 12148 Intent appErrorIntent = null; 12149 synchronized (this) { 12150 if (r != null && !r.isolated) { 12151 // XXX Can't keep track of crash time for isolated processes, 12152 // since they don't have a persistent identity. 12153 mProcessCrashTimes.put(r.info.processName, r.uid, 12154 SystemClock.uptimeMillis()); 12155 } 12156 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12157 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12158 } 12159 } 12160 12161 if (appErrorIntent != null) { 12162 try { 12163 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12164 } catch (ActivityNotFoundException e) { 12165 Slog.w(TAG, "bug report receiver dissappeared", e); 12166 } 12167 } 12168 } 12169 12170 Intent createAppErrorIntentLocked(ProcessRecord r, 12171 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12172 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12173 if (report == null) { 12174 return null; 12175 } 12176 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12177 result.setComponent(r.errorReportReceiver); 12178 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12179 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12180 return result; 12181 } 12182 12183 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12184 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12185 if (r.errorReportReceiver == null) { 12186 return null; 12187 } 12188 12189 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12190 return null; 12191 } 12192 12193 ApplicationErrorReport report = new ApplicationErrorReport(); 12194 report.packageName = r.info.packageName; 12195 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12196 report.processName = r.processName; 12197 report.time = timeMillis; 12198 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12199 12200 if (r.crashing || r.forceCrashReport) { 12201 report.type = ApplicationErrorReport.TYPE_CRASH; 12202 report.crashInfo = crashInfo; 12203 } else if (r.notResponding) { 12204 report.type = ApplicationErrorReport.TYPE_ANR; 12205 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12206 12207 report.anrInfo.activity = r.notRespondingReport.tag; 12208 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12209 report.anrInfo.info = r.notRespondingReport.longMsg; 12210 } 12211 12212 return report; 12213 } 12214 12215 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12216 enforceNotIsolatedCaller("getProcessesInErrorState"); 12217 // assume our apps are happy - lazy create the list 12218 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12219 12220 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12221 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12222 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12223 12224 synchronized (this) { 12225 12226 // iterate across all processes 12227 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12228 ProcessRecord app = mLruProcesses.get(i); 12229 if (!allUsers && app.userId != userId) { 12230 continue; 12231 } 12232 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12233 // This one's in trouble, so we'll generate a report for it 12234 // crashes are higher priority (in case there's a crash *and* an anr) 12235 ActivityManager.ProcessErrorStateInfo report = null; 12236 if (app.crashing) { 12237 report = app.crashingReport; 12238 } else if (app.notResponding) { 12239 report = app.notRespondingReport; 12240 } 12241 12242 if (report != null) { 12243 if (errList == null) { 12244 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12245 } 12246 errList.add(report); 12247 } else { 12248 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12249 " crashing = " + app.crashing + 12250 " notResponding = " + app.notResponding); 12251 } 12252 } 12253 } 12254 } 12255 12256 return errList; 12257 } 12258 12259 static int procStateToImportance(int procState, int memAdj, 12260 ActivityManager.RunningAppProcessInfo currApp) { 12261 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12262 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12263 currApp.lru = memAdj; 12264 } else { 12265 currApp.lru = 0; 12266 } 12267 return imp; 12268 } 12269 12270 private void fillInProcMemInfo(ProcessRecord app, 12271 ActivityManager.RunningAppProcessInfo outInfo) { 12272 outInfo.pid = app.pid; 12273 outInfo.uid = app.info.uid; 12274 if (mHeavyWeightProcess == app) { 12275 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12276 } 12277 if (app.persistent) { 12278 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12279 } 12280 if (app.activities.size() > 0) { 12281 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12282 } 12283 outInfo.lastTrimLevel = app.trimMemoryLevel; 12284 int adj = app.curAdj; 12285 int procState = app.curProcState; 12286 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12287 outInfo.importanceReasonCode = app.adjTypeCode; 12288 outInfo.processState = app.curProcState; 12289 } 12290 12291 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12292 enforceNotIsolatedCaller("getRunningAppProcesses"); 12293 // Lazy instantiation of list 12294 List<ActivityManager.RunningAppProcessInfo> runList = null; 12295 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12296 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12297 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12298 synchronized (this) { 12299 // Iterate across all processes 12300 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12301 ProcessRecord app = mLruProcesses.get(i); 12302 if (!allUsers && app.userId != userId) { 12303 continue; 12304 } 12305 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12306 // Generate process state info for running application 12307 ActivityManager.RunningAppProcessInfo currApp = 12308 new ActivityManager.RunningAppProcessInfo(app.processName, 12309 app.pid, app.getPackageList()); 12310 fillInProcMemInfo(app, currApp); 12311 if (app.adjSource instanceof ProcessRecord) { 12312 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12313 currApp.importanceReasonImportance = 12314 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12315 app.adjSourceProcState); 12316 } else if (app.adjSource instanceof ActivityRecord) { 12317 ActivityRecord r = (ActivityRecord)app.adjSource; 12318 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12319 } 12320 if (app.adjTarget instanceof ComponentName) { 12321 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12322 } 12323 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12324 // + " lru=" + currApp.lru); 12325 if (runList == null) { 12326 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12327 } 12328 runList.add(currApp); 12329 } 12330 } 12331 } 12332 return runList; 12333 } 12334 12335 public List<ApplicationInfo> getRunningExternalApplications() { 12336 enforceNotIsolatedCaller("getRunningExternalApplications"); 12337 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12338 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12339 if (runningApps != null && runningApps.size() > 0) { 12340 Set<String> extList = new HashSet<String>(); 12341 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12342 if (app.pkgList != null) { 12343 for (String pkg : app.pkgList) { 12344 extList.add(pkg); 12345 } 12346 } 12347 } 12348 IPackageManager pm = AppGlobals.getPackageManager(); 12349 for (String pkg : extList) { 12350 try { 12351 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12352 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12353 retList.add(info); 12354 } 12355 } catch (RemoteException e) { 12356 } 12357 } 12358 } 12359 return retList; 12360 } 12361 12362 @Override 12363 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12364 enforceNotIsolatedCaller("getMyMemoryState"); 12365 synchronized (this) { 12366 ProcessRecord proc; 12367 synchronized (mPidsSelfLocked) { 12368 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12369 } 12370 fillInProcMemInfo(proc, outInfo); 12371 } 12372 } 12373 12374 @Override 12375 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12376 if (checkCallingPermission(android.Manifest.permission.DUMP) 12377 != PackageManager.PERMISSION_GRANTED) { 12378 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12379 + Binder.getCallingPid() 12380 + ", uid=" + Binder.getCallingUid() 12381 + " without permission " 12382 + android.Manifest.permission.DUMP); 12383 return; 12384 } 12385 12386 boolean dumpAll = false; 12387 boolean dumpClient = false; 12388 String dumpPackage = null; 12389 12390 int opti = 0; 12391 while (opti < args.length) { 12392 String opt = args[opti]; 12393 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12394 break; 12395 } 12396 opti++; 12397 if ("-a".equals(opt)) { 12398 dumpAll = true; 12399 } else if ("-c".equals(opt)) { 12400 dumpClient = true; 12401 } else if ("-h".equals(opt)) { 12402 pw.println("Activity manager dump options:"); 12403 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12404 pw.println(" cmd may be one of:"); 12405 pw.println(" a[ctivities]: activity stack state"); 12406 pw.println(" r[recents]: recent activities state"); 12407 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12408 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12409 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12410 pw.println(" o[om]: out of memory management"); 12411 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12412 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12413 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12414 pw.println(" service [COMP_SPEC]: service client-side state"); 12415 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12416 pw.println(" all: dump all activities"); 12417 pw.println(" top: dump the top activity"); 12418 pw.println(" write: write all pending state to storage"); 12419 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12420 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12421 pw.println(" a partial substring in a component name, a"); 12422 pw.println(" hex object identifier."); 12423 pw.println(" -a: include all available server state."); 12424 pw.println(" -c: include client state."); 12425 return; 12426 } else { 12427 pw.println("Unknown argument: " + opt + "; use -h for help"); 12428 } 12429 } 12430 12431 long origId = Binder.clearCallingIdentity(); 12432 boolean more = false; 12433 // Is the caller requesting to dump a particular piece of data? 12434 if (opti < args.length) { 12435 String cmd = args[opti]; 12436 opti++; 12437 if ("activities".equals(cmd) || "a".equals(cmd)) { 12438 synchronized (this) { 12439 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12440 } 12441 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12442 synchronized (this) { 12443 dumpRecentsLocked(fd, pw, args, opti, true, null); 12444 } 12445 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12446 String[] newArgs; 12447 String name; 12448 if (opti >= args.length) { 12449 name = null; 12450 newArgs = EMPTY_STRING_ARRAY; 12451 } else { 12452 name = args[opti]; 12453 opti++; 12454 newArgs = new String[args.length - opti]; 12455 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12456 args.length - opti); 12457 } 12458 synchronized (this) { 12459 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12460 } 12461 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12462 String[] newArgs; 12463 String name; 12464 if (opti >= args.length) { 12465 name = null; 12466 newArgs = EMPTY_STRING_ARRAY; 12467 } else { 12468 name = args[opti]; 12469 opti++; 12470 newArgs = new String[args.length - opti]; 12471 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12472 args.length - opti); 12473 } 12474 synchronized (this) { 12475 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12476 } 12477 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12478 String[] newArgs; 12479 String name; 12480 if (opti >= args.length) { 12481 name = null; 12482 newArgs = EMPTY_STRING_ARRAY; 12483 } else { 12484 name = args[opti]; 12485 opti++; 12486 newArgs = new String[args.length - opti]; 12487 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12488 args.length - opti); 12489 } 12490 synchronized (this) { 12491 dumpProcessesLocked(fd, pw, args, opti, true, name); 12492 } 12493 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12494 synchronized (this) { 12495 dumpOomLocked(fd, pw, args, opti, true); 12496 } 12497 } else if ("provider".equals(cmd)) { 12498 String[] newArgs; 12499 String name; 12500 if (opti >= args.length) { 12501 name = null; 12502 newArgs = EMPTY_STRING_ARRAY; 12503 } else { 12504 name = args[opti]; 12505 opti++; 12506 newArgs = new String[args.length - opti]; 12507 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12508 } 12509 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12510 pw.println("No providers match: " + name); 12511 pw.println("Use -h for help."); 12512 } 12513 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12514 synchronized (this) { 12515 dumpProvidersLocked(fd, pw, args, opti, true, null); 12516 } 12517 } else if ("service".equals(cmd)) { 12518 String[] newArgs; 12519 String name; 12520 if (opti >= args.length) { 12521 name = null; 12522 newArgs = EMPTY_STRING_ARRAY; 12523 } else { 12524 name = args[opti]; 12525 opti++; 12526 newArgs = new String[args.length - opti]; 12527 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12528 args.length - opti); 12529 } 12530 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12531 pw.println("No services match: " + name); 12532 pw.println("Use -h for help."); 12533 } 12534 } else if ("package".equals(cmd)) { 12535 String[] newArgs; 12536 if (opti >= args.length) { 12537 pw.println("package: no package name specified"); 12538 pw.println("Use -h for help."); 12539 } else { 12540 dumpPackage = args[opti]; 12541 opti++; 12542 newArgs = new String[args.length - opti]; 12543 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12544 args.length - opti); 12545 args = newArgs; 12546 opti = 0; 12547 more = true; 12548 } 12549 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12550 synchronized (this) { 12551 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12552 } 12553 } else if ("write".equals(cmd)) { 12554 mTaskPersister.flush(); 12555 pw.println("All tasks persisted."); 12556 return; 12557 } else { 12558 // Dumping a single activity? 12559 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12560 pw.println("Bad activity command, or no activities match: " + cmd); 12561 pw.println("Use -h for help."); 12562 } 12563 } 12564 if (!more) { 12565 Binder.restoreCallingIdentity(origId); 12566 return; 12567 } 12568 } 12569 12570 // No piece of data specified, dump everything. 12571 synchronized (this) { 12572 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12573 pw.println(); 12574 if (dumpAll) { 12575 pw.println("-------------------------------------------------------------------------------"); 12576 } 12577 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12578 pw.println(); 12579 if (dumpAll) { 12580 pw.println("-------------------------------------------------------------------------------"); 12581 } 12582 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12583 pw.println(); 12584 if (dumpAll) { 12585 pw.println("-------------------------------------------------------------------------------"); 12586 } 12587 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12588 pw.println(); 12589 if (dumpAll) { 12590 pw.println("-------------------------------------------------------------------------------"); 12591 } 12592 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12593 pw.println(); 12594 if (dumpAll) { 12595 pw.println("-------------------------------------------------------------------------------"); 12596 } 12597 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12598 pw.println(); 12599 if (dumpAll) { 12600 pw.println("-------------------------------------------------------------------------------"); 12601 } 12602 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12603 } 12604 Binder.restoreCallingIdentity(origId); 12605 } 12606 12607 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12608 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12609 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12610 12611 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12612 dumpPackage); 12613 boolean needSep = printedAnything; 12614 12615 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12616 dumpPackage, needSep, " mFocusedActivity: "); 12617 if (printed) { 12618 printedAnything = true; 12619 needSep = false; 12620 } 12621 12622 if (dumpPackage == null) { 12623 if (needSep) { 12624 pw.println(); 12625 } 12626 needSep = true; 12627 printedAnything = true; 12628 mStackSupervisor.dump(pw, " "); 12629 } 12630 12631 if (!printedAnything) { 12632 pw.println(" (nothing)"); 12633 } 12634 } 12635 12636 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12637 int opti, boolean dumpAll, String dumpPackage) { 12638 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12639 12640 boolean printedAnything = false; 12641 12642 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12643 boolean printedHeader = false; 12644 12645 final int N = mRecentTasks.size(); 12646 for (int i=0; i<N; i++) { 12647 TaskRecord tr = mRecentTasks.get(i); 12648 if (dumpPackage != null) { 12649 if (tr.realActivity == null || 12650 !dumpPackage.equals(tr.realActivity)) { 12651 continue; 12652 } 12653 } 12654 if (!printedHeader) { 12655 pw.println(" Recent tasks:"); 12656 printedHeader = true; 12657 printedAnything = true; 12658 } 12659 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12660 pw.println(tr); 12661 if (dumpAll) { 12662 mRecentTasks.get(i).dump(pw, " "); 12663 } 12664 } 12665 } 12666 12667 if (!printedAnything) { 12668 pw.println(" (nothing)"); 12669 } 12670 } 12671 12672 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12673 int opti, boolean dumpAll, String dumpPackage) { 12674 boolean needSep = false; 12675 boolean printedAnything = false; 12676 int numPers = 0; 12677 12678 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12679 12680 if (dumpAll) { 12681 final int NP = mProcessNames.getMap().size(); 12682 for (int ip=0; ip<NP; ip++) { 12683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12684 final int NA = procs.size(); 12685 for (int ia=0; ia<NA; ia++) { 12686 ProcessRecord r = procs.valueAt(ia); 12687 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12688 continue; 12689 } 12690 if (!needSep) { 12691 pw.println(" All known processes:"); 12692 needSep = true; 12693 printedAnything = true; 12694 } 12695 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12696 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12697 pw.print(" "); pw.println(r); 12698 r.dump(pw, " "); 12699 if (r.persistent) { 12700 numPers++; 12701 } 12702 } 12703 } 12704 } 12705 12706 if (mIsolatedProcesses.size() > 0) { 12707 boolean printed = false; 12708 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12709 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12710 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12711 continue; 12712 } 12713 if (!printed) { 12714 if (needSep) { 12715 pw.println(); 12716 } 12717 pw.println(" Isolated process list (sorted by uid):"); 12718 printedAnything = true; 12719 printed = true; 12720 needSep = true; 12721 } 12722 pw.println(String.format("%sIsolated #%2d: %s", 12723 " ", i, r.toString())); 12724 } 12725 } 12726 12727 if (mLruProcesses.size() > 0) { 12728 if (needSep) { 12729 pw.println(); 12730 } 12731 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12732 pw.print(" total, non-act at "); 12733 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12734 pw.print(", non-svc at "); 12735 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12736 pw.println("):"); 12737 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12738 needSep = true; 12739 printedAnything = true; 12740 } 12741 12742 if (dumpAll || dumpPackage != null) { 12743 synchronized (mPidsSelfLocked) { 12744 boolean printed = false; 12745 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12746 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12747 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12748 continue; 12749 } 12750 if (!printed) { 12751 if (needSep) pw.println(); 12752 needSep = true; 12753 pw.println(" PID mappings:"); 12754 printed = true; 12755 printedAnything = true; 12756 } 12757 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12758 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12759 } 12760 } 12761 } 12762 12763 if (mForegroundProcesses.size() > 0) { 12764 synchronized (mPidsSelfLocked) { 12765 boolean printed = false; 12766 for (int i=0; i<mForegroundProcesses.size(); i++) { 12767 ProcessRecord r = mPidsSelfLocked.get( 12768 mForegroundProcesses.valueAt(i).pid); 12769 if (dumpPackage != null && (r == null 12770 || !r.pkgList.containsKey(dumpPackage))) { 12771 continue; 12772 } 12773 if (!printed) { 12774 if (needSep) pw.println(); 12775 needSep = true; 12776 pw.println(" Foreground Processes:"); 12777 printed = true; 12778 printedAnything = true; 12779 } 12780 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12781 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12782 } 12783 } 12784 } 12785 12786 if (mPersistentStartingProcesses.size() > 0) { 12787 if (needSep) pw.println(); 12788 needSep = true; 12789 printedAnything = true; 12790 pw.println(" Persisent processes that are starting:"); 12791 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12792 "Starting Norm", "Restarting PERS", dumpPackage); 12793 } 12794 12795 if (mRemovedProcesses.size() > 0) { 12796 if (needSep) pw.println(); 12797 needSep = true; 12798 printedAnything = true; 12799 pw.println(" Processes that are being removed:"); 12800 dumpProcessList(pw, this, mRemovedProcesses, " ", 12801 "Removed Norm", "Removed PERS", dumpPackage); 12802 } 12803 12804 if (mProcessesOnHold.size() > 0) { 12805 if (needSep) pw.println(); 12806 needSep = true; 12807 printedAnything = true; 12808 pw.println(" Processes that are on old until the system is ready:"); 12809 dumpProcessList(pw, this, mProcessesOnHold, " ", 12810 "OnHold Norm", "OnHold PERS", dumpPackage); 12811 } 12812 12813 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12814 12815 if (mProcessCrashTimes.getMap().size() > 0) { 12816 boolean printed = false; 12817 long now = SystemClock.uptimeMillis(); 12818 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12819 final int NP = pmap.size(); 12820 for (int ip=0; ip<NP; ip++) { 12821 String pname = pmap.keyAt(ip); 12822 SparseArray<Long> 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(" Time since processes crashed:"); 12835 printed = true; 12836 printedAnything = true; 12837 } 12838 pw.print(" Process "); pw.print(pname); 12839 pw.print(" uid "); pw.print(puid); 12840 pw.print(": last crashed "); 12841 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12842 pw.println(" ago"); 12843 } 12844 } 12845 } 12846 12847 if (mBadProcesses.getMap().size() > 0) { 12848 boolean printed = false; 12849 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12850 final int NP = pmap.size(); 12851 for (int ip=0; ip<NP; ip++) { 12852 String pname = pmap.keyAt(ip); 12853 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12854 final int N = uids.size(); 12855 for (int i=0; i<N; i++) { 12856 int puid = uids.keyAt(i); 12857 ProcessRecord r = mProcessNames.get(pname, puid); 12858 if (dumpPackage != null && (r == null 12859 || !r.pkgList.containsKey(dumpPackage))) { 12860 continue; 12861 } 12862 if (!printed) { 12863 if (needSep) pw.println(); 12864 needSep = true; 12865 pw.println(" Bad processes:"); 12866 printedAnything = true; 12867 } 12868 BadProcessInfo info = uids.valueAt(i); 12869 pw.print(" Bad process "); pw.print(pname); 12870 pw.print(" uid "); pw.print(puid); 12871 pw.print(": crashed at time "); pw.println(info.time); 12872 if (info.shortMsg != null) { 12873 pw.print(" Short msg: "); pw.println(info.shortMsg); 12874 } 12875 if (info.longMsg != null) { 12876 pw.print(" Long msg: "); pw.println(info.longMsg); 12877 } 12878 if (info.stack != null) { 12879 pw.println(" Stack:"); 12880 int lastPos = 0; 12881 for (int pos=0; pos<info.stack.length(); pos++) { 12882 if (info.stack.charAt(pos) == '\n') { 12883 pw.print(" "); 12884 pw.write(info.stack, lastPos, pos-lastPos); 12885 pw.println(); 12886 lastPos = pos+1; 12887 } 12888 } 12889 if (lastPos < info.stack.length()) { 12890 pw.print(" "); 12891 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12892 pw.println(); 12893 } 12894 } 12895 } 12896 } 12897 } 12898 12899 if (dumpPackage == null) { 12900 pw.println(); 12901 needSep = false; 12902 pw.println(" mStartedUsers:"); 12903 for (int i=0; i<mStartedUsers.size(); i++) { 12904 UserStartedState uss = mStartedUsers.valueAt(i); 12905 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12906 pw.print(": "); uss.dump("", pw); 12907 } 12908 pw.print(" mStartedUserArray: ["); 12909 for (int i=0; i<mStartedUserArray.length; i++) { 12910 if (i > 0) pw.print(", "); 12911 pw.print(mStartedUserArray[i]); 12912 } 12913 pw.println("]"); 12914 pw.print(" mUserLru: ["); 12915 for (int i=0; i<mUserLru.size(); i++) { 12916 if (i > 0) pw.print(", "); 12917 pw.print(mUserLru.get(i)); 12918 } 12919 pw.println("]"); 12920 if (dumpAll) { 12921 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12922 } 12923 synchronized (mUserProfileGroupIdsSelfLocked) { 12924 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12925 pw.println(" mUserProfileGroupIds:"); 12926 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12927 pw.print(" User #"); 12928 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12929 pw.print(" -> profile #"); 12930 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12931 } 12932 } 12933 } 12934 } 12935 if (mHomeProcess != null && (dumpPackage == null 12936 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12937 if (needSep) { 12938 pw.println(); 12939 needSep = false; 12940 } 12941 pw.println(" mHomeProcess: " + mHomeProcess); 12942 } 12943 if (mPreviousProcess != null && (dumpPackage == null 12944 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12945 if (needSep) { 12946 pw.println(); 12947 needSep = false; 12948 } 12949 pw.println(" mPreviousProcess: " + mPreviousProcess); 12950 } 12951 if (dumpAll) { 12952 StringBuilder sb = new StringBuilder(128); 12953 sb.append(" mPreviousProcessVisibleTime: "); 12954 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12955 pw.println(sb); 12956 } 12957 if (mHeavyWeightProcess != null && (dumpPackage == null 12958 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12959 if (needSep) { 12960 pw.println(); 12961 needSep = false; 12962 } 12963 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12964 } 12965 if (dumpPackage == null) { 12966 pw.println(" mConfiguration: " + mConfiguration); 12967 } 12968 if (dumpAll) { 12969 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12970 if (mCompatModePackages.getPackages().size() > 0) { 12971 boolean printed = false; 12972 for (Map.Entry<String, Integer> entry 12973 : mCompatModePackages.getPackages().entrySet()) { 12974 String pkg = entry.getKey(); 12975 int mode = entry.getValue(); 12976 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12977 continue; 12978 } 12979 if (!printed) { 12980 pw.println(" mScreenCompatPackages:"); 12981 printed = true; 12982 } 12983 pw.print(" "); pw.print(pkg); pw.print(": "); 12984 pw.print(mode); pw.println(); 12985 } 12986 } 12987 } 12988 if (dumpPackage == null) { 12989 if (mSleeping || mWentToSleep || mLockScreenShown) { 12990 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12991 + " mLockScreenShown " + mLockScreenShown); 12992 } 12993 if (mShuttingDown || mRunningVoice) { 12994 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12995 } 12996 } 12997 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12998 || mOrigWaitForDebugger) { 12999 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13000 || dumpPackage.equals(mOrigDebugApp)) { 13001 if (needSep) { 13002 pw.println(); 13003 needSep = false; 13004 } 13005 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13006 + " mDebugTransient=" + mDebugTransient 13007 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13008 } 13009 } 13010 if (mOpenGlTraceApp != null) { 13011 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13012 if (needSep) { 13013 pw.println(); 13014 needSep = false; 13015 } 13016 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13017 } 13018 } 13019 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13020 || mProfileFd != null) { 13021 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13022 if (needSep) { 13023 pw.println(); 13024 needSep = false; 13025 } 13026 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13027 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13028 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13029 + mAutoStopProfiler); 13030 pw.println(" mProfileType=" + mProfileType); 13031 } 13032 } 13033 if (dumpPackage == null) { 13034 if (mAlwaysFinishActivities || mController != null) { 13035 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13036 + " mController=" + mController); 13037 } 13038 if (dumpAll) { 13039 pw.println(" Total persistent processes: " + numPers); 13040 pw.println(" mProcessesReady=" + mProcessesReady 13041 + " mSystemReady=" + mSystemReady 13042 + " mBooted=" + mBooted 13043 + " mFactoryTest=" + mFactoryTest); 13044 pw.println(" mBooting=" + mBooting 13045 + " mCallFinishBooting=" + mCallFinishBooting 13046 + " mBootAnimationComplete=" + mBootAnimationComplete); 13047 pw.print(" mLastPowerCheckRealtime="); 13048 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13049 pw.println(""); 13050 pw.print(" mLastPowerCheckUptime="); 13051 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13052 pw.println(""); 13053 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13054 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13055 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13056 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13057 + " (" + mLruProcesses.size() + " total)" 13058 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13059 + " mNumServiceProcs=" + mNumServiceProcs 13060 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13061 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13062 + " mLastMemoryLevel" + mLastMemoryLevel 13063 + " mLastNumProcesses" + mLastNumProcesses); 13064 long now = SystemClock.uptimeMillis(); 13065 pw.print(" mLastIdleTime="); 13066 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13067 pw.print(" mLowRamSinceLastIdle="); 13068 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13069 pw.println(); 13070 } 13071 } 13072 13073 if (!printedAnything) { 13074 pw.println(" (nothing)"); 13075 } 13076 } 13077 13078 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13079 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13080 if (mProcessesToGc.size() > 0) { 13081 boolean printed = false; 13082 long now = SystemClock.uptimeMillis(); 13083 for (int i=0; i<mProcessesToGc.size(); i++) { 13084 ProcessRecord proc = mProcessesToGc.get(i); 13085 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13086 continue; 13087 } 13088 if (!printed) { 13089 if (needSep) pw.println(); 13090 needSep = true; 13091 pw.println(" Processes that are waiting to GC:"); 13092 printed = true; 13093 } 13094 pw.print(" Process "); pw.println(proc); 13095 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13096 pw.print(", last gced="); 13097 pw.print(now-proc.lastRequestedGc); 13098 pw.print(" ms ago, last lowMem="); 13099 pw.print(now-proc.lastLowMemory); 13100 pw.println(" ms ago"); 13101 13102 } 13103 } 13104 return needSep; 13105 } 13106 13107 void printOomLevel(PrintWriter pw, String name, int adj) { 13108 pw.print(" "); 13109 if (adj >= 0) { 13110 pw.print(' '); 13111 if (adj < 10) pw.print(' '); 13112 } else { 13113 if (adj > -10) pw.print(' '); 13114 } 13115 pw.print(adj); 13116 pw.print(": "); 13117 pw.print(name); 13118 pw.print(" ("); 13119 pw.print(mProcessList.getMemLevel(adj)/1024); 13120 pw.println(" kB)"); 13121 } 13122 13123 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13124 int opti, boolean dumpAll) { 13125 boolean needSep = false; 13126 13127 if (mLruProcesses.size() > 0) { 13128 if (needSep) pw.println(); 13129 needSep = true; 13130 pw.println(" OOM levels:"); 13131 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13132 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13133 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13134 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13135 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13136 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13137 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13138 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13139 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13140 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13141 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13142 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13143 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13144 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13145 13146 if (needSep) pw.println(); 13147 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13148 pw.print(" total, non-act at "); 13149 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13150 pw.print(", non-svc at "); 13151 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13152 pw.println("):"); 13153 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13154 needSep = true; 13155 } 13156 13157 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13158 13159 pw.println(); 13160 pw.println(" mHomeProcess: " + mHomeProcess); 13161 pw.println(" mPreviousProcess: " + mPreviousProcess); 13162 if (mHeavyWeightProcess != null) { 13163 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13164 } 13165 13166 return true; 13167 } 13168 13169 /** 13170 * There are three ways to call this: 13171 * - no provider specified: dump all the providers 13172 * - a flattened component name that matched an existing provider was specified as the 13173 * first arg: dump that one provider 13174 * - the first arg isn't the flattened component name of an existing provider: 13175 * dump all providers whose component contains the first arg as a substring 13176 */ 13177 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13178 int opti, boolean dumpAll) { 13179 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13180 } 13181 13182 static class ItemMatcher { 13183 ArrayList<ComponentName> components; 13184 ArrayList<String> strings; 13185 ArrayList<Integer> objects; 13186 boolean all; 13187 13188 ItemMatcher() { 13189 all = true; 13190 } 13191 13192 void build(String name) { 13193 ComponentName componentName = ComponentName.unflattenFromString(name); 13194 if (componentName != null) { 13195 if (components == null) { 13196 components = new ArrayList<ComponentName>(); 13197 } 13198 components.add(componentName); 13199 all = false; 13200 } else { 13201 int objectId = 0; 13202 // Not a '/' separated full component name; maybe an object ID? 13203 try { 13204 objectId = Integer.parseInt(name, 16); 13205 if (objects == null) { 13206 objects = new ArrayList<Integer>(); 13207 } 13208 objects.add(objectId); 13209 all = false; 13210 } catch (RuntimeException e) { 13211 // Not an integer; just do string match. 13212 if (strings == null) { 13213 strings = new ArrayList<String>(); 13214 } 13215 strings.add(name); 13216 all = false; 13217 } 13218 } 13219 } 13220 13221 int build(String[] args, int opti) { 13222 for (; opti<args.length; opti++) { 13223 String name = args[opti]; 13224 if ("--".equals(name)) { 13225 return opti+1; 13226 } 13227 build(name); 13228 } 13229 return opti; 13230 } 13231 13232 boolean match(Object object, ComponentName comp) { 13233 if (all) { 13234 return true; 13235 } 13236 if (components != null) { 13237 for (int i=0; i<components.size(); i++) { 13238 if (components.get(i).equals(comp)) { 13239 return true; 13240 } 13241 } 13242 } 13243 if (objects != null) { 13244 for (int i=0; i<objects.size(); i++) { 13245 if (System.identityHashCode(object) == objects.get(i)) { 13246 return true; 13247 } 13248 } 13249 } 13250 if (strings != null) { 13251 String flat = comp.flattenToString(); 13252 for (int i=0; i<strings.size(); i++) { 13253 if (flat.contains(strings.get(i))) { 13254 return true; 13255 } 13256 } 13257 } 13258 return false; 13259 } 13260 } 13261 13262 /** 13263 * There are three things that cmd can be: 13264 * - a flattened component name that matches an existing activity 13265 * - the cmd arg isn't the flattened component name of an existing activity: 13266 * dump all activity whose component contains the cmd as a substring 13267 * - A hex number of the ActivityRecord object instance. 13268 */ 13269 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13270 int opti, boolean dumpAll) { 13271 ArrayList<ActivityRecord> activities; 13272 13273 synchronized (this) { 13274 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13275 } 13276 13277 if (activities.size() <= 0) { 13278 return false; 13279 } 13280 13281 String[] newArgs = new String[args.length - opti]; 13282 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13283 13284 TaskRecord lastTask = null; 13285 boolean needSep = false; 13286 for (int i=activities.size()-1; i>=0; i--) { 13287 ActivityRecord r = activities.get(i); 13288 if (needSep) { 13289 pw.println(); 13290 } 13291 needSep = true; 13292 synchronized (this) { 13293 if (lastTask != r.task) { 13294 lastTask = r.task; 13295 pw.print("TASK "); pw.print(lastTask.affinity); 13296 pw.print(" id="); pw.println(lastTask.taskId); 13297 if (dumpAll) { 13298 lastTask.dump(pw, " "); 13299 } 13300 } 13301 } 13302 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13303 } 13304 return true; 13305 } 13306 13307 /** 13308 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13309 * there is a thread associated with the activity. 13310 */ 13311 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13312 final ActivityRecord r, String[] args, boolean dumpAll) { 13313 String innerPrefix = prefix + " "; 13314 synchronized (this) { 13315 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13316 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13317 pw.print(" pid="); 13318 if (r.app != null) pw.println(r.app.pid); 13319 else pw.println("(not running)"); 13320 if (dumpAll) { 13321 r.dump(pw, innerPrefix); 13322 } 13323 } 13324 if (r.app != null && r.app.thread != null) { 13325 // flush anything that is already in the PrintWriter since the thread is going 13326 // to write to the file descriptor directly 13327 pw.flush(); 13328 try { 13329 TransferPipe tp = new TransferPipe(); 13330 try { 13331 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13332 r.appToken, innerPrefix, args); 13333 tp.go(fd); 13334 } finally { 13335 tp.kill(); 13336 } 13337 } catch (IOException e) { 13338 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13339 } catch (RemoteException e) { 13340 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13341 } 13342 } 13343 } 13344 13345 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13346 int opti, boolean dumpAll, String dumpPackage) { 13347 boolean needSep = false; 13348 boolean onlyHistory = false; 13349 boolean printedAnything = false; 13350 13351 if ("history".equals(dumpPackage)) { 13352 if (opti < args.length && "-s".equals(args[opti])) { 13353 dumpAll = false; 13354 } 13355 onlyHistory = true; 13356 dumpPackage = null; 13357 } 13358 13359 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13360 if (!onlyHistory && dumpAll) { 13361 if (mRegisteredReceivers.size() > 0) { 13362 boolean printed = false; 13363 Iterator it = mRegisteredReceivers.values().iterator(); 13364 while (it.hasNext()) { 13365 ReceiverList r = (ReceiverList)it.next(); 13366 if (dumpPackage != null && (r.app == null || 13367 !dumpPackage.equals(r.app.info.packageName))) { 13368 continue; 13369 } 13370 if (!printed) { 13371 pw.println(" Registered Receivers:"); 13372 needSep = true; 13373 printed = true; 13374 printedAnything = true; 13375 } 13376 pw.print(" * "); pw.println(r); 13377 r.dump(pw, " "); 13378 } 13379 } 13380 13381 if (mReceiverResolver.dump(pw, needSep ? 13382 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13383 " ", dumpPackage, false)) { 13384 needSep = true; 13385 printedAnything = true; 13386 } 13387 } 13388 13389 for (BroadcastQueue q : mBroadcastQueues) { 13390 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13391 printedAnything |= needSep; 13392 } 13393 13394 needSep = true; 13395 13396 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13397 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13398 if (needSep) { 13399 pw.println(); 13400 } 13401 needSep = true; 13402 printedAnything = true; 13403 pw.print(" Sticky broadcasts for user "); 13404 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13405 StringBuilder sb = new StringBuilder(128); 13406 for (Map.Entry<String, ArrayList<Intent>> ent 13407 : mStickyBroadcasts.valueAt(user).entrySet()) { 13408 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13409 if (dumpAll) { 13410 pw.println(":"); 13411 ArrayList<Intent> intents = ent.getValue(); 13412 final int N = intents.size(); 13413 for (int i=0; i<N; i++) { 13414 sb.setLength(0); 13415 sb.append(" Intent: "); 13416 intents.get(i).toShortString(sb, false, true, false, false); 13417 pw.println(sb.toString()); 13418 Bundle bundle = intents.get(i).getExtras(); 13419 if (bundle != null) { 13420 pw.print(" "); 13421 pw.println(bundle.toString()); 13422 } 13423 } 13424 } else { 13425 pw.println(""); 13426 } 13427 } 13428 } 13429 } 13430 13431 if (!onlyHistory && dumpAll) { 13432 pw.println(); 13433 for (BroadcastQueue queue : mBroadcastQueues) { 13434 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13435 + queue.mBroadcastsScheduled); 13436 } 13437 pw.println(" mHandler:"); 13438 mHandler.dump(new PrintWriterPrinter(pw), " "); 13439 needSep = true; 13440 printedAnything = true; 13441 } 13442 13443 if (!printedAnything) { 13444 pw.println(" (nothing)"); 13445 } 13446 } 13447 13448 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13449 int opti, boolean dumpAll, String dumpPackage) { 13450 boolean needSep; 13451 boolean printedAnything = false; 13452 13453 ItemMatcher matcher = new ItemMatcher(); 13454 matcher.build(args, opti); 13455 13456 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13457 13458 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13459 printedAnything |= needSep; 13460 13461 if (mLaunchingProviders.size() > 0) { 13462 boolean printed = false; 13463 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13464 ContentProviderRecord r = mLaunchingProviders.get(i); 13465 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13466 continue; 13467 } 13468 if (!printed) { 13469 if (needSep) pw.println(); 13470 needSep = true; 13471 pw.println(" Launching content providers:"); 13472 printed = true; 13473 printedAnything = true; 13474 } 13475 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13476 pw.println(r); 13477 } 13478 } 13479 13480 if (mGrantedUriPermissions.size() > 0) { 13481 boolean printed = false; 13482 int dumpUid = -2; 13483 if (dumpPackage != null) { 13484 try { 13485 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13486 } catch (NameNotFoundException e) { 13487 dumpUid = -1; 13488 } 13489 } 13490 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13491 int uid = mGrantedUriPermissions.keyAt(i); 13492 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13493 continue; 13494 } 13495 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13496 if (!printed) { 13497 if (needSep) pw.println(); 13498 needSep = true; 13499 pw.println(" Granted Uri Permissions:"); 13500 printed = true; 13501 printedAnything = true; 13502 } 13503 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13504 for (UriPermission perm : perms.values()) { 13505 pw.print(" "); pw.println(perm); 13506 if (dumpAll) { 13507 perm.dump(pw, " "); 13508 } 13509 } 13510 } 13511 } 13512 13513 if (!printedAnything) { 13514 pw.println(" (nothing)"); 13515 } 13516 } 13517 13518 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13519 int opti, boolean dumpAll, String dumpPackage) { 13520 boolean printed = false; 13521 13522 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13523 13524 if (mIntentSenderRecords.size() > 0) { 13525 Iterator<WeakReference<PendingIntentRecord>> it 13526 = mIntentSenderRecords.values().iterator(); 13527 while (it.hasNext()) { 13528 WeakReference<PendingIntentRecord> ref = it.next(); 13529 PendingIntentRecord rec = ref != null ? ref.get(): null; 13530 if (dumpPackage != null && (rec == null 13531 || !dumpPackage.equals(rec.key.packageName))) { 13532 continue; 13533 } 13534 printed = true; 13535 if (rec != null) { 13536 pw.print(" * "); pw.println(rec); 13537 if (dumpAll) { 13538 rec.dump(pw, " "); 13539 } 13540 } else { 13541 pw.print(" * "); pw.println(ref); 13542 } 13543 } 13544 } 13545 13546 if (!printed) { 13547 pw.println(" (nothing)"); 13548 } 13549 } 13550 13551 private static final int dumpProcessList(PrintWriter pw, 13552 ActivityManagerService service, List list, 13553 String prefix, String normalLabel, String persistentLabel, 13554 String dumpPackage) { 13555 int numPers = 0; 13556 final int N = list.size()-1; 13557 for (int i=N; i>=0; i--) { 13558 ProcessRecord r = (ProcessRecord)list.get(i); 13559 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13560 continue; 13561 } 13562 pw.println(String.format("%s%s #%2d: %s", 13563 prefix, (r.persistent ? persistentLabel : normalLabel), 13564 i, r.toString())); 13565 if (r.persistent) { 13566 numPers++; 13567 } 13568 } 13569 return numPers; 13570 } 13571 13572 private static final boolean dumpProcessOomList(PrintWriter pw, 13573 ActivityManagerService service, List<ProcessRecord> origList, 13574 String prefix, String normalLabel, String persistentLabel, 13575 boolean inclDetails, String dumpPackage) { 13576 13577 ArrayList<Pair<ProcessRecord, Integer>> list 13578 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13579 for (int i=0; i<origList.size(); i++) { 13580 ProcessRecord r = origList.get(i); 13581 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13582 continue; 13583 } 13584 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13585 } 13586 13587 if (list.size() <= 0) { 13588 return false; 13589 } 13590 13591 Comparator<Pair<ProcessRecord, Integer>> comparator 13592 = new Comparator<Pair<ProcessRecord, Integer>>() { 13593 @Override 13594 public int compare(Pair<ProcessRecord, Integer> object1, 13595 Pair<ProcessRecord, Integer> object2) { 13596 if (object1.first.setAdj != object2.first.setAdj) { 13597 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13598 } 13599 if (object1.second.intValue() != object2.second.intValue()) { 13600 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13601 } 13602 return 0; 13603 } 13604 }; 13605 13606 Collections.sort(list, comparator); 13607 13608 final long curRealtime = SystemClock.elapsedRealtime(); 13609 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13610 final long curUptime = SystemClock.uptimeMillis(); 13611 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13612 13613 for (int i=list.size()-1; i>=0; i--) { 13614 ProcessRecord r = list.get(i).first; 13615 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13616 char schedGroup; 13617 switch (r.setSchedGroup) { 13618 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13619 schedGroup = 'B'; 13620 break; 13621 case Process.THREAD_GROUP_DEFAULT: 13622 schedGroup = 'F'; 13623 break; 13624 default: 13625 schedGroup = '?'; 13626 break; 13627 } 13628 char foreground; 13629 if (r.foregroundActivities) { 13630 foreground = 'A'; 13631 } else if (r.foregroundServices) { 13632 foreground = 'S'; 13633 } else { 13634 foreground = ' '; 13635 } 13636 String procState = ProcessList.makeProcStateString(r.curProcState); 13637 pw.print(prefix); 13638 pw.print(r.persistent ? persistentLabel : normalLabel); 13639 pw.print(" #"); 13640 int num = (origList.size()-1)-list.get(i).second; 13641 if (num < 10) pw.print(' '); 13642 pw.print(num); 13643 pw.print(": "); 13644 pw.print(oomAdj); 13645 pw.print(' '); 13646 pw.print(schedGroup); 13647 pw.print('/'); 13648 pw.print(foreground); 13649 pw.print('/'); 13650 pw.print(procState); 13651 pw.print(" trm:"); 13652 if (r.trimMemoryLevel < 10) pw.print(' '); 13653 pw.print(r.trimMemoryLevel); 13654 pw.print(' '); 13655 pw.print(r.toShortString()); 13656 pw.print(" ("); 13657 pw.print(r.adjType); 13658 pw.println(')'); 13659 if (r.adjSource != null || r.adjTarget != null) { 13660 pw.print(prefix); 13661 pw.print(" "); 13662 if (r.adjTarget instanceof ComponentName) { 13663 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13664 } else if (r.adjTarget != null) { 13665 pw.print(r.adjTarget.toString()); 13666 } else { 13667 pw.print("{null}"); 13668 } 13669 pw.print("<="); 13670 if (r.adjSource instanceof ProcessRecord) { 13671 pw.print("Proc{"); 13672 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13673 pw.println("}"); 13674 } else if (r.adjSource != null) { 13675 pw.println(r.adjSource.toString()); 13676 } else { 13677 pw.println("{null}"); 13678 } 13679 } 13680 if (inclDetails) { 13681 pw.print(prefix); 13682 pw.print(" "); 13683 pw.print("oom: max="); pw.print(r.maxAdj); 13684 pw.print(" curRaw="); pw.print(r.curRawAdj); 13685 pw.print(" setRaw="); pw.print(r.setRawAdj); 13686 pw.print(" cur="); pw.print(r.curAdj); 13687 pw.print(" set="); pw.println(r.setAdj); 13688 pw.print(prefix); 13689 pw.print(" "); 13690 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13691 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13692 pw.print(" lastPss="); pw.print(r.lastPss); 13693 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13694 pw.print(prefix); 13695 pw.print(" "); 13696 pw.print("cached="); pw.print(r.cached); 13697 pw.print(" empty="); pw.print(r.empty); 13698 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13699 13700 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13701 if (r.lastWakeTime != 0) { 13702 long wtime; 13703 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13704 synchronized (stats) { 13705 wtime = stats.getProcessWakeTime(r.info.uid, 13706 r.pid, curRealtime); 13707 } 13708 long timeUsed = wtime - r.lastWakeTime; 13709 pw.print(prefix); 13710 pw.print(" "); 13711 pw.print("keep awake over "); 13712 TimeUtils.formatDuration(realtimeSince, pw); 13713 pw.print(" used "); 13714 TimeUtils.formatDuration(timeUsed, pw); 13715 pw.print(" ("); 13716 pw.print((timeUsed*100)/realtimeSince); 13717 pw.println("%)"); 13718 } 13719 if (r.lastCpuTime != 0) { 13720 long timeUsed = r.curCpuTime - r.lastCpuTime; 13721 pw.print(prefix); 13722 pw.print(" "); 13723 pw.print("run cpu over "); 13724 TimeUtils.formatDuration(uptimeSince, pw); 13725 pw.print(" used "); 13726 TimeUtils.formatDuration(timeUsed, pw); 13727 pw.print(" ("); 13728 pw.print((timeUsed*100)/uptimeSince); 13729 pw.println("%)"); 13730 } 13731 } 13732 } 13733 } 13734 return true; 13735 } 13736 13737 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13738 String[] args) { 13739 ArrayList<ProcessRecord> procs; 13740 synchronized (this) { 13741 if (args != null && args.length > start 13742 && args[start].charAt(0) != '-') { 13743 procs = new ArrayList<ProcessRecord>(); 13744 int pid = -1; 13745 try { 13746 pid = Integer.parseInt(args[start]); 13747 } catch (NumberFormatException e) { 13748 } 13749 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13750 ProcessRecord proc = mLruProcesses.get(i); 13751 if (proc.pid == pid) { 13752 procs.add(proc); 13753 } else if (allPkgs && proc.pkgList != null 13754 && proc.pkgList.containsKey(args[start])) { 13755 procs.add(proc); 13756 } else if (proc.processName.equals(args[start])) { 13757 procs.add(proc); 13758 } 13759 } 13760 if (procs.size() <= 0) { 13761 return null; 13762 } 13763 } else { 13764 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13765 } 13766 } 13767 return procs; 13768 } 13769 13770 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13771 PrintWriter pw, String[] args) { 13772 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13773 if (procs == null) { 13774 pw.println("No process found for: " + args[0]); 13775 return; 13776 } 13777 13778 long uptime = SystemClock.uptimeMillis(); 13779 long realtime = SystemClock.elapsedRealtime(); 13780 pw.println("Applications Graphics Acceleration Info:"); 13781 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13782 13783 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13784 ProcessRecord r = procs.get(i); 13785 if (r.thread != null) { 13786 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13787 pw.flush(); 13788 try { 13789 TransferPipe tp = new TransferPipe(); 13790 try { 13791 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13792 tp.go(fd); 13793 } finally { 13794 tp.kill(); 13795 } 13796 } catch (IOException e) { 13797 pw.println("Failure while dumping the app: " + r); 13798 pw.flush(); 13799 } catch (RemoteException e) { 13800 pw.println("Got a RemoteException while dumping the app " + r); 13801 pw.flush(); 13802 } 13803 } 13804 } 13805 } 13806 13807 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13808 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13809 if (procs == null) { 13810 pw.println("No process found for: " + args[0]); 13811 return; 13812 } 13813 13814 pw.println("Applications Database Info:"); 13815 13816 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13817 ProcessRecord r = procs.get(i); 13818 if (r.thread != null) { 13819 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13820 pw.flush(); 13821 try { 13822 TransferPipe tp = new TransferPipe(); 13823 try { 13824 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13825 tp.go(fd); 13826 } finally { 13827 tp.kill(); 13828 } 13829 } catch (IOException e) { 13830 pw.println("Failure while dumping the app: " + r); 13831 pw.flush(); 13832 } catch (RemoteException e) { 13833 pw.println("Got a RemoteException while dumping the app " + r); 13834 pw.flush(); 13835 } 13836 } 13837 } 13838 } 13839 13840 final static class MemItem { 13841 final boolean isProc; 13842 final String label; 13843 final String shortLabel; 13844 final long pss; 13845 final int id; 13846 final boolean hasActivities; 13847 ArrayList<MemItem> subitems; 13848 13849 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13850 boolean _hasActivities) { 13851 isProc = true; 13852 label = _label; 13853 shortLabel = _shortLabel; 13854 pss = _pss; 13855 id = _id; 13856 hasActivities = _hasActivities; 13857 } 13858 13859 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13860 isProc = false; 13861 label = _label; 13862 shortLabel = _shortLabel; 13863 pss = _pss; 13864 id = _id; 13865 hasActivities = false; 13866 } 13867 } 13868 13869 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13870 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13871 if (sort && !isCompact) { 13872 Collections.sort(items, new Comparator<MemItem>() { 13873 @Override 13874 public int compare(MemItem lhs, MemItem rhs) { 13875 if (lhs.pss < rhs.pss) { 13876 return 1; 13877 } else if (lhs.pss > rhs.pss) { 13878 return -1; 13879 } 13880 return 0; 13881 } 13882 }); 13883 } 13884 13885 for (int i=0; i<items.size(); i++) { 13886 MemItem mi = items.get(i); 13887 if (!isCompact) { 13888 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13889 } else if (mi.isProc) { 13890 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13891 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13892 pw.println(mi.hasActivities ? ",a" : ",e"); 13893 } else { 13894 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13895 pw.println(mi.pss); 13896 } 13897 if (mi.subitems != null) { 13898 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13899 true, isCompact); 13900 } 13901 } 13902 } 13903 13904 // These are in KB. 13905 static final long[] DUMP_MEM_BUCKETS = new long[] { 13906 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13907 120*1024, 160*1024, 200*1024, 13908 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13909 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13910 }; 13911 13912 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13913 boolean stackLike) { 13914 int start = label.lastIndexOf('.'); 13915 if (start >= 0) start++; 13916 else start = 0; 13917 int end = label.length(); 13918 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13919 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13920 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13921 out.append(bucket); 13922 out.append(stackLike ? "MB." : "MB "); 13923 out.append(label, start, end); 13924 return; 13925 } 13926 } 13927 out.append(memKB/1024); 13928 out.append(stackLike ? "MB." : "MB "); 13929 out.append(label, start, end); 13930 } 13931 13932 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13933 ProcessList.NATIVE_ADJ, 13934 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13935 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13936 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13937 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13938 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13939 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13940 }; 13941 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13942 "Native", 13943 "System", "Persistent", "Persistent Service", "Foreground", 13944 "Visible", "Perceptible", 13945 "Heavy Weight", "Backup", 13946 "A Services", "Home", 13947 "Previous", "B Services", "Cached" 13948 }; 13949 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13950 "native", 13951 "sys", "pers", "persvc", "fore", 13952 "vis", "percept", 13953 "heavy", "backup", 13954 "servicea", "home", 13955 "prev", "serviceb", "cached" 13956 }; 13957 13958 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13959 long realtime, boolean isCheckinRequest, boolean isCompact) { 13960 if (isCheckinRequest || isCompact) { 13961 // short checkin version 13962 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13963 } else { 13964 pw.println("Applications Memory Usage (kB):"); 13965 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13966 } 13967 } 13968 13969 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13970 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13971 boolean dumpDetails = false; 13972 boolean dumpFullDetails = false; 13973 boolean dumpDalvik = false; 13974 boolean oomOnly = false; 13975 boolean isCompact = false; 13976 boolean localOnly = false; 13977 boolean packages = false; 13978 13979 int opti = 0; 13980 while (opti < args.length) { 13981 String opt = args[opti]; 13982 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13983 break; 13984 } 13985 opti++; 13986 if ("-a".equals(opt)) { 13987 dumpDetails = true; 13988 dumpFullDetails = true; 13989 dumpDalvik = true; 13990 } else if ("-d".equals(opt)) { 13991 dumpDalvik = true; 13992 } else if ("-c".equals(opt)) { 13993 isCompact = true; 13994 } else if ("--oom".equals(opt)) { 13995 oomOnly = true; 13996 } else if ("--local".equals(opt)) { 13997 localOnly = true; 13998 } else if ("--package".equals(opt)) { 13999 packages = true; 14000 } else if ("-h".equals(opt)) { 14001 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14002 pw.println(" -a: include all available information for each process."); 14003 pw.println(" -d: include dalvik details when dumping process details."); 14004 pw.println(" -c: dump in a compact machine-parseable representation."); 14005 pw.println(" --oom: only show processes organized by oom adj."); 14006 pw.println(" --local: only collect details locally, don't call process."); 14007 pw.println(" --package: interpret process arg as package, dumping all"); 14008 pw.println(" processes that have loaded that package."); 14009 pw.println("If [process] is specified it can be the name or "); 14010 pw.println("pid of a specific process to dump."); 14011 return; 14012 } else { 14013 pw.println("Unknown argument: " + opt + "; use -h for help"); 14014 } 14015 } 14016 14017 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14018 long uptime = SystemClock.uptimeMillis(); 14019 long realtime = SystemClock.elapsedRealtime(); 14020 final long[] tmpLong = new long[1]; 14021 14022 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14023 if (procs == null) { 14024 // No Java processes. Maybe they want to print a native process. 14025 if (args != null && args.length > opti 14026 && args[opti].charAt(0) != '-') { 14027 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14028 = new ArrayList<ProcessCpuTracker.Stats>(); 14029 updateCpuStatsNow(); 14030 int findPid = -1; 14031 try { 14032 findPid = Integer.parseInt(args[opti]); 14033 } catch (NumberFormatException e) { 14034 } 14035 synchronized (mProcessCpuTracker) { 14036 final int N = mProcessCpuTracker.countStats(); 14037 for (int i=0; i<N; i++) { 14038 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14039 if (st.pid == findPid || (st.baseName != null 14040 && st.baseName.equals(args[opti]))) { 14041 nativeProcs.add(st); 14042 } 14043 } 14044 } 14045 if (nativeProcs.size() > 0) { 14046 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14047 isCompact); 14048 Debug.MemoryInfo mi = null; 14049 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14050 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14051 final int pid = r.pid; 14052 if (!isCheckinRequest && dumpDetails) { 14053 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14054 } 14055 if (mi == null) { 14056 mi = new Debug.MemoryInfo(); 14057 } 14058 if (dumpDetails || (!brief && !oomOnly)) { 14059 Debug.getMemoryInfo(pid, mi); 14060 } else { 14061 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14062 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14063 } 14064 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14065 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14066 if (isCheckinRequest) { 14067 pw.println(); 14068 } 14069 } 14070 return; 14071 } 14072 } 14073 pw.println("No process found for: " + args[opti]); 14074 return; 14075 } 14076 14077 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14078 dumpDetails = true; 14079 } 14080 14081 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14082 14083 String[] innerArgs = new String[args.length-opti]; 14084 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14085 14086 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14087 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14088 long nativePss=0, dalvikPss=0, otherPss=0; 14089 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14090 14091 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14092 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14093 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14094 14095 long totalPss = 0; 14096 long cachedPss = 0; 14097 14098 Debug.MemoryInfo mi = null; 14099 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14100 final ProcessRecord r = procs.get(i); 14101 final IApplicationThread thread; 14102 final int pid; 14103 final int oomAdj; 14104 final boolean hasActivities; 14105 synchronized (this) { 14106 thread = r.thread; 14107 pid = r.pid; 14108 oomAdj = r.getSetAdjWithServices(); 14109 hasActivities = r.activities.size() > 0; 14110 } 14111 if (thread != null) { 14112 if (!isCheckinRequest && dumpDetails) { 14113 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14114 } 14115 if (mi == null) { 14116 mi = new Debug.MemoryInfo(); 14117 } 14118 if (dumpDetails || (!brief && !oomOnly)) { 14119 Debug.getMemoryInfo(pid, mi); 14120 } else { 14121 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14122 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14123 } 14124 if (dumpDetails) { 14125 if (localOnly) { 14126 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14127 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14128 if (isCheckinRequest) { 14129 pw.println(); 14130 } 14131 } else { 14132 try { 14133 pw.flush(); 14134 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14135 dumpDalvik, innerArgs); 14136 } catch (RemoteException e) { 14137 if (!isCheckinRequest) { 14138 pw.println("Got RemoteException!"); 14139 pw.flush(); 14140 } 14141 } 14142 } 14143 } 14144 14145 final long myTotalPss = mi.getTotalPss(); 14146 final long myTotalUss = mi.getTotalUss(); 14147 14148 synchronized (this) { 14149 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14150 // Record this for posterity if the process has been stable. 14151 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14152 } 14153 } 14154 14155 if (!isCheckinRequest && mi != null) { 14156 totalPss += myTotalPss; 14157 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14158 (hasActivities ? " / activities)" : ")"), 14159 r.processName, myTotalPss, pid, hasActivities); 14160 procMems.add(pssItem); 14161 procMemsMap.put(pid, pssItem); 14162 14163 nativePss += mi.nativePss; 14164 dalvikPss += mi.dalvikPss; 14165 otherPss += mi.otherPss; 14166 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14167 long mem = mi.getOtherPss(j); 14168 miscPss[j] += mem; 14169 otherPss -= mem; 14170 } 14171 14172 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14173 cachedPss += myTotalPss; 14174 } 14175 14176 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14177 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14178 || oomIndex == (oomPss.length-1)) { 14179 oomPss[oomIndex] += myTotalPss; 14180 if (oomProcs[oomIndex] == null) { 14181 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14182 } 14183 oomProcs[oomIndex].add(pssItem); 14184 break; 14185 } 14186 } 14187 } 14188 } 14189 } 14190 14191 long nativeProcTotalPss = 0; 14192 14193 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14194 // If we are showing aggregations, also look for native processes to 14195 // include so that our aggregations are more accurate. 14196 updateCpuStatsNow(); 14197 synchronized (mProcessCpuTracker) { 14198 final int N = mProcessCpuTracker.countStats(); 14199 for (int i=0; i<N; i++) { 14200 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14201 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14202 if (mi == null) { 14203 mi = new Debug.MemoryInfo(); 14204 } 14205 if (!brief && !oomOnly) { 14206 Debug.getMemoryInfo(st.pid, mi); 14207 } else { 14208 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14209 mi.nativePrivateDirty = (int)tmpLong[0]; 14210 } 14211 14212 final long myTotalPss = mi.getTotalPss(); 14213 totalPss += myTotalPss; 14214 nativeProcTotalPss += myTotalPss; 14215 14216 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14217 st.name, myTotalPss, st.pid, false); 14218 procMems.add(pssItem); 14219 14220 nativePss += mi.nativePss; 14221 dalvikPss += mi.dalvikPss; 14222 otherPss += mi.otherPss; 14223 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14224 long mem = mi.getOtherPss(j); 14225 miscPss[j] += mem; 14226 otherPss -= mem; 14227 } 14228 oomPss[0] += myTotalPss; 14229 if (oomProcs[0] == null) { 14230 oomProcs[0] = new ArrayList<MemItem>(); 14231 } 14232 oomProcs[0].add(pssItem); 14233 } 14234 } 14235 } 14236 14237 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14238 14239 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14240 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14241 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14242 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14243 String label = Debug.MemoryInfo.getOtherLabel(j); 14244 catMems.add(new MemItem(label, label, miscPss[j], j)); 14245 } 14246 14247 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14248 for (int j=0; j<oomPss.length; j++) { 14249 if (oomPss[j] != 0) { 14250 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14251 : DUMP_MEM_OOM_LABEL[j]; 14252 MemItem item = new MemItem(label, label, oomPss[j], 14253 DUMP_MEM_OOM_ADJ[j]); 14254 item.subitems = oomProcs[j]; 14255 oomMems.add(item); 14256 } 14257 } 14258 14259 if (!brief && !oomOnly && !isCompact) { 14260 pw.println(); 14261 pw.println("Total PSS by process:"); 14262 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14263 pw.println(); 14264 } 14265 if (!isCompact) { 14266 pw.println("Total PSS by OOM adjustment:"); 14267 } 14268 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14269 if (!brief && !oomOnly) { 14270 PrintWriter out = categoryPw != null ? categoryPw : pw; 14271 if (!isCompact) { 14272 out.println(); 14273 out.println("Total PSS by category:"); 14274 } 14275 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14276 } 14277 if (!isCompact) { 14278 pw.println(); 14279 } 14280 MemInfoReader memInfo = new MemInfoReader(); 14281 memInfo.readMemInfo(); 14282 if (nativeProcTotalPss > 0) { 14283 synchronized (this) { 14284 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14285 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14286 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14287 nativeProcTotalPss); 14288 } 14289 } 14290 if (!brief) { 14291 if (!isCompact) { 14292 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14293 pw.print(" kB (status "); 14294 switch (mLastMemoryLevel) { 14295 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14296 pw.println("normal)"); 14297 break; 14298 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14299 pw.println("moderate)"); 14300 break; 14301 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14302 pw.println("low)"); 14303 break; 14304 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14305 pw.println("critical)"); 14306 break; 14307 default: 14308 pw.print(mLastMemoryLevel); 14309 pw.println(")"); 14310 break; 14311 } 14312 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14313 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14314 pw.print(cachedPss); pw.print(" cached pss + "); 14315 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14316 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14317 } else { 14318 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14319 pw.print(cachedPss + memInfo.getCachedSizeKb() 14320 + memInfo.getFreeSizeKb()); pw.print(","); 14321 pw.println(totalPss - cachedPss); 14322 } 14323 } 14324 if (!isCompact) { 14325 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14326 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14327 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14328 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14329 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14330 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14331 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14332 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14333 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14334 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14335 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14336 } 14337 if (!brief) { 14338 if (memInfo.getZramTotalSizeKb() != 0) { 14339 if (!isCompact) { 14340 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14341 pw.print(" kB physical used for "); 14342 pw.print(memInfo.getSwapTotalSizeKb() 14343 - memInfo.getSwapFreeSizeKb()); 14344 pw.print(" kB in swap ("); 14345 pw.print(memInfo.getSwapTotalSizeKb()); 14346 pw.println(" kB total swap)"); 14347 } else { 14348 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14349 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14350 pw.println(memInfo.getSwapFreeSizeKb()); 14351 } 14352 } 14353 final int[] SINGLE_LONG_FORMAT = new int[] { 14354 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14355 }; 14356 long[] longOut = new long[1]; 14357 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14358 SINGLE_LONG_FORMAT, null, longOut, null); 14359 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14360 longOut[0] = 0; 14361 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14362 SINGLE_LONG_FORMAT, null, longOut, null); 14363 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14364 longOut[0] = 0; 14365 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14366 SINGLE_LONG_FORMAT, null, longOut, null); 14367 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14368 longOut[0] = 0; 14369 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14370 SINGLE_LONG_FORMAT, null, longOut, null); 14371 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14372 if (!isCompact) { 14373 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14374 pw.print(" KSM: "); pw.print(sharing); 14375 pw.print(" kB saved from shared "); 14376 pw.print(shared); pw.println(" kB"); 14377 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14378 pw.print(voltile); pw.println(" kB volatile"); 14379 } 14380 pw.print(" Tuning: "); 14381 pw.print(ActivityManager.staticGetMemoryClass()); 14382 pw.print(" (large "); 14383 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14384 pw.print("), oom "); 14385 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14386 pw.print(" kB"); 14387 pw.print(", restore limit "); 14388 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14389 pw.print(" kB"); 14390 if (ActivityManager.isLowRamDeviceStatic()) { 14391 pw.print(" (low-ram)"); 14392 } 14393 if (ActivityManager.isHighEndGfx()) { 14394 pw.print(" (high-end-gfx)"); 14395 } 14396 pw.println(); 14397 } else { 14398 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14399 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14400 pw.println(voltile); 14401 pw.print("tuning,"); 14402 pw.print(ActivityManager.staticGetMemoryClass()); 14403 pw.print(','); 14404 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14405 pw.print(','); 14406 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14407 if (ActivityManager.isLowRamDeviceStatic()) { 14408 pw.print(",low-ram"); 14409 } 14410 if (ActivityManager.isHighEndGfx()) { 14411 pw.print(",high-end-gfx"); 14412 } 14413 pw.println(); 14414 } 14415 } 14416 } 14417 } 14418 14419 /** 14420 * Searches array of arguments for the specified string 14421 * @param args array of argument strings 14422 * @param value value to search for 14423 * @return true if the value is contained in the array 14424 */ 14425 private static boolean scanArgs(String[] args, String value) { 14426 if (args != null) { 14427 for (String arg : args) { 14428 if (value.equals(arg)) { 14429 return true; 14430 } 14431 } 14432 } 14433 return false; 14434 } 14435 14436 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14437 ContentProviderRecord cpr, boolean always) { 14438 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14439 14440 if (!inLaunching || always) { 14441 synchronized (cpr) { 14442 cpr.launchingApp = null; 14443 cpr.notifyAll(); 14444 } 14445 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14446 String names[] = cpr.info.authority.split(";"); 14447 for (int j = 0; j < names.length; j++) { 14448 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14449 } 14450 } 14451 14452 for (int i=0; i<cpr.connections.size(); i++) { 14453 ContentProviderConnection conn = cpr.connections.get(i); 14454 if (conn.waiting) { 14455 // If this connection is waiting for the provider, then we don't 14456 // need to mess with its process unless we are always removing 14457 // or for some reason the provider is not currently launching. 14458 if (inLaunching && !always) { 14459 continue; 14460 } 14461 } 14462 ProcessRecord capp = conn.client; 14463 conn.dead = true; 14464 if (conn.stableCount > 0) { 14465 if (!capp.persistent && capp.thread != null 14466 && capp.pid != 0 14467 && capp.pid != MY_PID) { 14468 capp.kill("depends on provider " 14469 + cpr.name.flattenToShortString() 14470 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14471 } 14472 } else if (capp.thread != null && conn.provider.provider != null) { 14473 try { 14474 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14475 } catch (RemoteException e) { 14476 } 14477 // In the protocol here, we don't expect the client to correctly 14478 // clean up this connection, we'll just remove it. 14479 cpr.connections.remove(i); 14480 conn.client.conProviders.remove(conn); 14481 } 14482 } 14483 14484 if (inLaunching && always) { 14485 mLaunchingProviders.remove(cpr); 14486 } 14487 return inLaunching; 14488 } 14489 14490 /** 14491 * Main code for cleaning up a process when it has gone away. This is 14492 * called both as a result of the process dying, or directly when stopping 14493 * a process when running in single process mode. 14494 * 14495 * @return Returns true if the given process has been restarted, so the 14496 * app that was passed in must remain on the process lists. 14497 */ 14498 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14499 boolean restarting, boolean allowRestart, int index) { 14500 if (index >= 0) { 14501 removeLruProcessLocked(app); 14502 ProcessList.remove(app.pid); 14503 } 14504 14505 mProcessesToGc.remove(app); 14506 mPendingPssProcesses.remove(app); 14507 14508 // Dismiss any open dialogs. 14509 if (app.crashDialog != null && !app.forceCrashReport) { 14510 app.crashDialog.dismiss(); 14511 app.crashDialog = null; 14512 } 14513 if (app.anrDialog != null) { 14514 app.anrDialog.dismiss(); 14515 app.anrDialog = null; 14516 } 14517 if (app.waitDialog != null) { 14518 app.waitDialog.dismiss(); 14519 app.waitDialog = null; 14520 } 14521 14522 app.crashing = false; 14523 app.notResponding = false; 14524 14525 app.resetPackageList(mProcessStats); 14526 app.unlinkDeathRecipient(); 14527 app.makeInactive(mProcessStats); 14528 app.waitingToKill = null; 14529 app.forcingToForeground = null; 14530 updateProcessForegroundLocked(app, false, false); 14531 app.foregroundActivities = false; 14532 app.hasShownUi = false; 14533 app.treatLikeActivity = false; 14534 app.hasAboveClient = false; 14535 app.hasClientActivities = false; 14536 14537 mServices.killServicesLocked(app, allowRestart); 14538 14539 boolean restart = false; 14540 14541 // Remove published content providers. 14542 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14543 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14544 final boolean always = app.bad || !allowRestart; 14545 if (removeDyingProviderLocked(app, cpr, always) || always) { 14546 // We left the provider in the launching list, need to 14547 // restart it. 14548 restart = true; 14549 } 14550 14551 cpr.provider = null; 14552 cpr.proc = null; 14553 } 14554 app.pubProviders.clear(); 14555 14556 // Take care of any launching providers waiting for this process. 14557 if (checkAppInLaunchingProvidersLocked(app, false)) { 14558 restart = true; 14559 } 14560 14561 // Unregister from connected content providers. 14562 if (!app.conProviders.isEmpty()) { 14563 for (int i=0; i<app.conProviders.size(); i++) { 14564 ContentProviderConnection conn = app.conProviders.get(i); 14565 conn.provider.connections.remove(conn); 14566 } 14567 app.conProviders.clear(); 14568 } 14569 14570 // At this point there may be remaining entries in mLaunchingProviders 14571 // where we were the only one waiting, so they are no longer of use. 14572 // Look for these and clean up if found. 14573 // XXX Commented out for now. Trying to figure out a way to reproduce 14574 // the actual situation to identify what is actually going on. 14575 if (false) { 14576 for (int i=0; i<mLaunchingProviders.size(); i++) { 14577 ContentProviderRecord cpr = (ContentProviderRecord) 14578 mLaunchingProviders.get(i); 14579 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14580 synchronized (cpr) { 14581 cpr.launchingApp = null; 14582 cpr.notifyAll(); 14583 } 14584 } 14585 } 14586 } 14587 14588 skipCurrentReceiverLocked(app); 14589 14590 // Unregister any receivers. 14591 for (int i=app.receivers.size()-1; i>=0; i--) { 14592 removeReceiverLocked(app.receivers.valueAt(i)); 14593 } 14594 app.receivers.clear(); 14595 14596 // If the app is undergoing backup, tell the backup manager about it 14597 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14598 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14599 + mBackupTarget.appInfo + " died during backup"); 14600 try { 14601 IBackupManager bm = IBackupManager.Stub.asInterface( 14602 ServiceManager.getService(Context.BACKUP_SERVICE)); 14603 bm.agentDisconnected(app.info.packageName); 14604 } catch (RemoteException e) { 14605 // can't happen; backup manager is local 14606 } 14607 } 14608 14609 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14610 ProcessChangeItem item = mPendingProcessChanges.get(i); 14611 if (item.pid == app.pid) { 14612 mPendingProcessChanges.remove(i); 14613 mAvailProcessChanges.add(item); 14614 } 14615 } 14616 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14617 14618 // If the caller is restarting this app, then leave it in its 14619 // current lists and let the caller take care of it. 14620 if (restarting) { 14621 return false; 14622 } 14623 14624 if (!app.persistent || app.isolated) { 14625 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14626 "Removing non-persistent process during cleanup: " + app); 14627 mProcessNames.remove(app.processName, app.uid); 14628 mIsolatedProcesses.remove(app.uid); 14629 if (mHeavyWeightProcess == app) { 14630 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14631 mHeavyWeightProcess.userId, 0)); 14632 mHeavyWeightProcess = null; 14633 } 14634 } else if (!app.removed) { 14635 // This app is persistent, so we need to keep its record around. 14636 // If it is not already on the pending app list, add it there 14637 // and start a new process for it. 14638 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14639 mPersistentStartingProcesses.add(app); 14640 restart = true; 14641 } 14642 } 14643 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14644 "Clean-up removing on hold: " + app); 14645 mProcessesOnHold.remove(app); 14646 14647 if (app == mHomeProcess) { 14648 mHomeProcess = null; 14649 } 14650 if (app == mPreviousProcess) { 14651 mPreviousProcess = null; 14652 } 14653 14654 if (restart && !app.isolated) { 14655 // We have components that still need to be running in the 14656 // process, so re-launch it. 14657 if (index < 0) { 14658 ProcessList.remove(app.pid); 14659 } 14660 mProcessNames.put(app.processName, app.uid, app); 14661 startProcessLocked(app, "restart", app.processName); 14662 return true; 14663 } else if (app.pid > 0 && app.pid != MY_PID) { 14664 // Goodbye! 14665 boolean removed; 14666 synchronized (mPidsSelfLocked) { 14667 mPidsSelfLocked.remove(app.pid); 14668 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14669 } 14670 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14671 if (app.isolated) { 14672 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14673 } 14674 app.setPid(0); 14675 } 14676 return false; 14677 } 14678 14679 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14680 // Look through the content providers we are waiting to have launched, 14681 // and if any run in this process then either schedule a restart of 14682 // the process or kill the client waiting for it if this process has 14683 // gone bad. 14684 int NL = mLaunchingProviders.size(); 14685 boolean restart = false; 14686 for (int i=0; i<NL; i++) { 14687 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14688 if (cpr.launchingApp == app) { 14689 if (!alwaysBad && !app.bad) { 14690 restart = true; 14691 } else { 14692 removeDyingProviderLocked(app, cpr, true); 14693 // cpr should have been removed from mLaunchingProviders 14694 NL = mLaunchingProviders.size(); 14695 i--; 14696 } 14697 } 14698 } 14699 return restart; 14700 } 14701 14702 // ========================================================= 14703 // SERVICES 14704 // ========================================================= 14705 14706 @Override 14707 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14708 int flags) { 14709 enforceNotIsolatedCaller("getServices"); 14710 synchronized (this) { 14711 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14712 } 14713 } 14714 14715 @Override 14716 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14717 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14718 synchronized (this) { 14719 return mServices.getRunningServiceControlPanelLocked(name); 14720 } 14721 } 14722 14723 @Override 14724 public ComponentName startService(IApplicationThread caller, Intent service, 14725 String resolvedType, int userId) { 14726 enforceNotIsolatedCaller("startService"); 14727 // Refuse possible leaked file descriptors 14728 if (service != null && service.hasFileDescriptors() == true) { 14729 throw new IllegalArgumentException("File descriptors passed in Intent"); 14730 } 14731 14732 if (DEBUG_SERVICE) 14733 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14734 synchronized(this) { 14735 final int callingPid = Binder.getCallingPid(); 14736 final int callingUid = Binder.getCallingUid(); 14737 final long origId = Binder.clearCallingIdentity(); 14738 ComponentName res = mServices.startServiceLocked(caller, service, 14739 resolvedType, callingPid, callingUid, userId); 14740 Binder.restoreCallingIdentity(origId); 14741 return res; 14742 } 14743 } 14744 14745 ComponentName startServiceInPackage(int uid, 14746 Intent service, String resolvedType, int userId) { 14747 synchronized(this) { 14748 if (DEBUG_SERVICE) 14749 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14750 final long origId = Binder.clearCallingIdentity(); 14751 ComponentName res = mServices.startServiceLocked(null, service, 14752 resolvedType, -1, uid, userId); 14753 Binder.restoreCallingIdentity(origId); 14754 return res; 14755 } 14756 } 14757 14758 @Override 14759 public int stopService(IApplicationThread caller, Intent service, 14760 String resolvedType, int userId) { 14761 enforceNotIsolatedCaller("stopService"); 14762 // Refuse possible leaked file descriptors 14763 if (service != null && service.hasFileDescriptors() == true) { 14764 throw new IllegalArgumentException("File descriptors passed in Intent"); 14765 } 14766 14767 synchronized(this) { 14768 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14769 } 14770 } 14771 14772 @Override 14773 public IBinder peekService(Intent service, String resolvedType) { 14774 enforceNotIsolatedCaller("peekService"); 14775 // Refuse possible leaked file descriptors 14776 if (service != null && service.hasFileDescriptors() == true) { 14777 throw new IllegalArgumentException("File descriptors passed in Intent"); 14778 } 14779 synchronized(this) { 14780 return mServices.peekServiceLocked(service, resolvedType); 14781 } 14782 } 14783 14784 @Override 14785 public boolean stopServiceToken(ComponentName className, IBinder token, 14786 int startId) { 14787 synchronized(this) { 14788 return mServices.stopServiceTokenLocked(className, token, startId); 14789 } 14790 } 14791 14792 @Override 14793 public void setServiceForeground(ComponentName className, IBinder token, 14794 int id, Notification notification, boolean removeNotification) { 14795 synchronized(this) { 14796 mServices.setServiceForegroundLocked(className, token, id, notification, 14797 removeNotification); 14798 } 14799 } 14800 14801 @Override 14802 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14803 boolean requireFull, String name, String callerPackage) { 14804 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14805 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14806 } 14807 14808 int unsafeConvertIncomingUser(int userId) { 14809 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14810 ? mCurrentUserId : userId; 14811 } 14812 14813 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14814 int allowMode, String name, String callerPackage) { 14815 final int callingUserId = UserHandle.getUserId(callingUid); 14816 if (callingUserId == userId) { 14817 return userId; 14818 } 14819 14820 // Note that we may be accessing mCurrentUserId outside of a lock... 14821 // shouldn't be a big deal, if this is being called outside 14822 // of a locked context there is intrinsically a race with 14823 // the value the caller will receive and someone else changing it. 14824 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14825 // we will switch to the calling user if access to the current user fails. 14826 int targetUserId = unsafeConvertIncomingUser(userId); 14827 14828 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14829 final boolean allow; 14830 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14831 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14832 // If the caller has this permission, they always pass go. And collect $200. 14833 allow = true; 14834 } else if (allowMode == ALLOW_FULL_ONLY) { 14835 // We require full access, sucks to be you. 14836 allow = false; 14837 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14838 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14839 // If the caller does not have either permission, they are always doomed. 14840 allow = false; 14841 } else if (allowMode == ALLOW_NON_FULL) { 14842 // We are blanket allowing non-full access, you lucky caller! 14843 allow = true; 14844 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14845 // We may or may not allow this depending on whether the two users are 14846 // in the same profile. 14847 synchronized (mUserProfileGroupIdsSelfLocked) { 14848 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14849 UserInfo.NO_PROFILE_GROUP_ID); 14850 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14851 UserInfo.NO_PROFILE_GROUP_ID); 14852 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14853 && callingProfile == targetProfile; 14854 } 14855 } else { 14856 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14857 } 14858 if (!allow) { 14859 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14860 // In this case, they would like to just execute as their 14861 // owner user instead of failing. 14862 targetUserId = callingUserId; 14863 } else { 14864 StringBuilder builder = new StringBuilder(128); 14865 builder.append("Permission Denial: "); 14866 builder.append(name); 14867 if (callerPackage != null) { 14868 builder.append(" from "); 14869 builder.append(callerPackage); 14870 } 14871 builder.append(" asks to run as user "); 14872 builder.append(userId); 14873 builder.append(" but is calling from user "); 14874 builder.append(UserHandle.getUserId(callingUid)); 14875 builder.append("; this requires "); 14876 builder.append(INTERACT_ACROSS_USERS_FULL); 14877 if (allowMode != ALLOW_FULL_ONLY) { 14878 builder.append(" or "); 14879 builder.append(INTERACT_ACROSS_USERS); 14880 } 14881 String msg = builder.toString(); 14882 Slog.w(TAG, msg); 14883 throw new SecurityException(msg); 14884 } 14885 } 14886 } 14887 if (!allowAll && targetUserId < 0) { 14888 throw new IllegalArgumentException( 14889 "Call does not support special user #" + targetUserId); 14890 } 14891 // Check shell permission 14892 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14893 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14894 targetUserId)) { 14895 throw new SecurityException("Shell does not have permission to access user " 14896 + targetUserId + "\n " + Debug.getCallers(3)); 14897 } 14898 } 14899 return targetUserId; 14900 } 14901 14902 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14903 String className, int flags) { 14904 boolean result = false; 14905 // For apps that don't have pre-defined UIDs, check for permission 14906 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14907 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14908 if (ActivityManager.checkUidPermission( 14909 INTERACT_ACROSS_USERS, 14910 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14911 ComponentName comp = new ComponentName(aInfo.packageName, className); 14912 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14913 + " requests FLAG_SINGLE_USER, but app does not hold " 14914 + INTERACT_ACROSS_USERS; 14915 Slog.w(TAG, msg); 14916 throw new SecurityException(msg); 14917 } 14918 // Permission passed 14919 result = true; 14920 } 14921 } else if ("system".equals(componentProcessName)) { 14922 result = true; 14923 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14924 // Phone app and persistent apps are allowed to export singleuser providers. 14925 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14926 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14927 } 14928 if (DEBUG_MU) { 14929 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14930 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14931 } 14932 return result; 14933 } 14934 14935 /** 14936 * Checks to see if the caller is in the same app as the singleton 14937 * component, or the component is in a special app. It allows special apps 14938 * to export singleton components but prevents exporting singleton 14939 * components for regular apps. 14940 */ 14941 boolean isValidSingletonCall(int callingUid, int componentUid) { 14942 int componentAppId = UserHandle.getAppId(componentUid); 14943 return UserHandle.isSameApp(callingUid, componentUid) 14944 || componentAppId == Process.SYSTEM_UID 14945 || componentAppId == Process.PHONE_UID 14946 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14947 == PackageManager.PERMISSION_GRANTED; 14948 } 14949 14950 public int bindService(IApplicationThread caller, IBinder token, 14951 Intent service, String resolvedType, 14952 IServiceConnection connection, int flags, int userId) { 14953 enforceNotIsolatedCaller("bindService"); 14954 14955 // Refuse possible leaked file descriptors 14956 if (service != null && service.hasFileDescriptors() == true) { 14957 throw new IllegalArgumentException("File descriptors passed in Intent"); 14958 } 14959 14960 synchronized(this) { 14961 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14962 connection, flags, userId); 14963 } 14964 } 14965 14966 public boolean unbindService(IServiceConnection connection) { 14967 synchronized (this) { 14968 return mServices.unbindServiceLocked(connection); 14969 } 14970 } 14971 14972 public void publishService(IBinder token, Intent intent, IBinder service) { 14973 // Refuse possible leaked file descriptors 14974 if (intent != null && intent.hasFileDescriptors() == true) { 14975 throw new IllegalArgumentException("File descriptors passed in Intent"); 14976 } 14977 14978 synchronized(this) { 14979 if (!(token instanceof ServiceRecord)) { 14980 throw new IllegalArgumentException("Invalid service token"); 14981 } 14982 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14983 } 14984 } 14985 14986 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14987 // Refuse possible leaked file descriptors 14988 if (intent != null && intent.hasFileDescriptors() == true) { 14989 throw new IllegalArgumentException("File descriptors passed in Intent"); 14990 } 14991 14992 synchronized(this) { 14993 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14994 } 14995 } 14996 14997 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14998 synchronized(this) { 14999 if (!(token instanceof ServiceRecord)) { 15000 throw new IllegalArgumentException("Invalid service token"); 15001 } 15002 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15003 } 15004 } 15005 15006 // ========================================================= 15007 // BACKUP AND RESTORE 15008 // ========================================================= 15009 15010 // Cause the target app to be launched if necessary and its backup agent 15011 // instantiated. The backup agent will invoke backupAgentCreated() on the 15012 // activity manager to announce its creation. 15013 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15014 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15015 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15016 15017 synchronized(this) { 15018 // !!! TODO: currently no check here that we're already bound 15019 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15020 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15021 synchronized (stats) { 15022 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15023 } 15024 15025 // Backup agent is now in use, its package can't be stopped. 15026 try { 15027 AppGlobals.getPackageManager().setPackageStoppedState( 15028 app.packageName, false, UserHandle.getUserId(app.uid)); 15029 } catch (RemoteException e) { 15030 } catch (IllegalArgumentException e) { 15031 Slog.w(TAG, "Failed trying to unstop package " 15032 + app.packageName + ": " + e); 15033 } 15034 15035 BackupRecord r = new BackupRecord(ss, app, backupMode); 15036 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15037 ? new ComponentName(app.packageName, app.backupAgentName) 15038 : new ComponentName("android", "FullBackupAgent"); 15039 // startProcessLocked() returns existing proc's record if it's already running 15040 ProcessRecord proc = startProcessLocked(app.processName, app, 15041 false, 0, "backup", hostingName, false, false, false); 15042 if (proc == null) { 15043 Slog.e(TAG, "Unable to start backup agent process " + r); 15044 return false; 15045 } 15046 15047 r.app = proc; 15048 mBackupTarget = r; 15049 mBackupAppName = app.packageName; 15050 15051 // Try not to kill the process during backup 15052 updateOomAdjLocked(proc); 15053 15054 // If the process is already attached, schedule the creation of the backup agent now. 15055 // If it is not yet live, this will be done when it attaches to the framework. 15056 if (proc.thread != null) { 15057 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15058 try { 15059 proc.thread.scheduleCreateBackupAgent(app, 15060 compatibilityInfoForPackageLocked(app), backupMode); 15061 } catch (RemoteException e) { 15062 // Will time out on the backup manager side 15063 } 15064 } else { 15065 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15066 } 15067 // Invariants: at this point, the target app process exists and the application 15068 // is either already running or in the process of coming up. mBackupTarget and 15069 // mBackupAppName describe the app, so that when it binds back to the AM we 15070 // know that it's scheduled for a backup-agent operation. 15071 } 15072 15073 return true; 15074 } 15075 15076 @Override 15077 public void clearPendingBackup() { 15078 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15079 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15080 15081 synchronized (this) { 15082 mBackupTarget = null; 15083 mBackupAppName = null; 15084 } 15085 } 15086 15087 // A backup agent has just come up 15088 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15089 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15090 + " = " + agent); 15091 15092 synchronized(this) { 15093 if (!agentPackageName.equals(mBackupAppName)) { 15094 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15095 return; 15096 } 15097 } 15098 15099 long oldIdent = Binder.clearCallingIdentity(); 15100 try { 15101 IBackupManager bm = IBackupManager.Stub.asInterface( 15102 ServiceManager.getService(Context.BACKUP_SERVICE)); 15103 bm.agentConnected(agentPackageName, agent); 15104 } catch (RemoteException e) { 15105 // can't happen; the backup manager service is local 15106 } catch (Exception e) { 15107 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15108 e.printStackTrace(); 15109 } finally { 15110 Binder.restoreCallingIdentity(oldIdent); 15111 } 15112 } 15113 15114 // done with this agent 15115 public void unbindBackupAgent(ApplicationInfo appInfo) { 15116 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15117 if (appInfo == null) { 15118 Slog.w(TAG, "unbind backup agent for null app"); 15119 return; 15120 } 15121 15122 synchronized(this) { 15123 try { 15124 if (mBackupAppName == null) { 15125 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15126 return; 15127 } 15128 15129 if (!mBackupAppName.equals(appInfo.packageName)) { 15130 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15131 return; 15132 } 15133 15134 // Not backing this app up any more; reset its OOM adjustment 15135 final ProcessRecord proc = mBackupTarget.app; 15136 updateOomAdjLocked(proc); 15137 15138 // If the app crashed during backup, 'thread' will be null here 15139 if (proc.thread != null) { 15140 try { 15141 proc.thread.scheduleDestroyBackupAgent(appInfo, 15142 compatibilityInfoForPackageLocked(appInfo)); 15143 } catch (Exception e) { 15144 Slog.e(TAG, "Exception when unbinding backup agent:"); 15145 e.printStackTrace(); 15146 } 15147 } 15148 } finally { 15149 mBackupTarget = null; 15150 mBackupAppName = null; 15151 } 15152 } 15153 } 15154 // ========================================================= 15155 // BROADCASTS 15156 // ========================================================= 15157 15158 private final List getStickiesLocked(String action, IntentFilter filter, 15159 List cur, int userId) { 15160 final ContentResolver resolver = mContext.getContentResolver(); 15161 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15162 if (stickies == null) { 15163 return cur; 15164 } 15165 final ArrayList<Intent> list = stickies.get(action); 15166 if (list == null) { 15167 return cur; 15168 } 15169 int N = list.size(); 15170 for (int i=0; i<N; i++) { 15171 Intent intent = list.get(i); 15172 if (filter.match(resolver, intent, true, TAG) >= 0) { 15173 if (cur == null) { 15174 cur = new ArrayList<Intent>(); 15175 } 15176 cur.add(intent); 15177 } 15178 } 15179 return cur; 15180 } 15181 15182 boolean isPendingBroadcastProcessLocked(int pid) { 15183 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15184 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15185 } 15186 15187 void skipPendingBroadcastLocked(int pid) { 15188 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15189 for (BroadcastQueue queue : mBroadcastQueues) { 15190 queue.skipPendingBroadcastLocked(pid); 15191 } 15192 } 15193 15194 // The app just attached; send any pending broadcasts that it should receive 15195 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15196 boolean didSomething = false; 15197 for (BroadcastQueue queue : mBroadcastQueues) { 15198 didSomething |= queue.sendPendingBroadcastsLocked(app); 15199 } 15200 return didSomething; 15201 } 15202 15203 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15204 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15205 enforceNotIsolatedCaller("registerReceiver"); 15206 int callingUid; 15207 int callingPid; 15208 synchronized(this) { 15209 ProcessRecord callerApp = null; 15210 if (caller != null) { 15211 callerApp = getRecordForAppLocked(caller); 15212 if (callerApp == null) { 15213 throw new SecurityException( 15214 "Unable to find app for caller " + caller 15215 + " (pid=" + Binder.getCallingPid() 15216 + ") when registering receiver " + receiver); 15217 } 15218 if (callerApp.info.uid != Process.SYSTEM_UID && 15219 !callerApp.pkgList.containsKey(callerPackage) && 15220 !"android".equals(callerPackage)) { 15221 throw new SecurityException("Given caller package " + callerPackage 15222 + " is not running in process " + callerApp); 15223 } 15224 callingUid = callerApp.info.uid; 15225 callingPid = callerApp.pid; 15226 } else { 15227 callerPackage = null; 15228 callingUid = Binder.getCallingUid(); 15229 callingPid = Binder.getCallingPid(); 15230 } 15231 15232 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15233 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15234 15235 List allSticky = null; 15236 15237 // Look for any matching sticky broadcasts... 15238 Iterator actions = filter.actionsIterator(); 15239 if (actions != null) { 15240 while (actions.hasNext()) { 15241 String action = (String)actions.next(); 15242 allSticky = getStickiesLocked(action, filter, allSticky, 15243 UserHandle.USER_ALL); 15244 allSticky = getStickiesLocked(action, filter, allSticky, 15245 UserHandle.getUserId(callingUid)); 15246 } 15247 } else { 15248 allSticky = getStickiesLocked(null, filter, allSticky, 15249 UserHandle.USER_ALL); 15250 allSticky = getStickiesLocked(null, filter, allSticky, 15251 UserHandle.getUserId(callingUid)); 15252 } 15253 15254 // The first sticky in the list is returned directly back to 15255 // the client. 15256 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15257 15258 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15259 + ": " + sticky); 15260 15261 if (receiver == null) { 15262 return sticky; 15263 } 15264 15265 ReceiverList rl 15266 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15267 if (rl == null) { 15268 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15269 userId, receiver); 15270 if (rl.app != null) { 15271 rl.app.receivers.add(rl); 15272 } else { 15273 try { 15274 receiver.asBinder().linkToDeath(rl, 0); 15275 } catch (RemoteException e) { 15276 return sticky; 15277 } 15278 rl.linkedToDeath = true; 15279 } 15280 mRegisteredReceivers.put(receiver.asBinder(), rl); 15281 } else if (rl.uid != callingUid) { 15282 throw new IllegalArgumentException( 15283 "Receiver requested to register for uid " + callingUid 15284 + " was previously registered for uid " + rl.uid); 15285 } else if (rl.pid != callingPid) { 15286 throw new IllegalArgumentException( 15287 "Receiver requested to register for pid " + callingPid 15288 + " was previously registered for pid " + rl.pid); 15289 } else if (rl.userId != userId) { 15290 throw new IllegalArgumentException( 15291 "Receiver requested to register for user " + userId 15292 + " was previously registered for user " + rl.userId); 15293 } 15294 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15295 permission, callingUid, userId); 15296 rl.add(bf); 15297 if (!bf.debugCheck()) { 15298 Slog.w(TAG, "==> For Dynamic broadast"); 15299 } 15300 mReceiverResolver.addFilter(bf); 15301 15302 // Enqueue broadcasts for all existing stickies that match 15303 // this filter. 15304 if (allSticky != null) { 15305 ArrayList receivers = new ArrayList(); 15306 receivers.add(bf); 15307 15308 int N = allSticky.size(); 15309 for (int i=0; i<N; i++) { 15310 Intent intent = (Intent)allSticky.get(i); 15311 BroadcastQueue queue = broadcastQueueForIntent(intent); 15312 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15313 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15314 null, null, false, true, true, -1); 15315 queue.enqueueParallelBroadcastLocked(r); 15316 queue.scheduleBroadcastsLocked(); 15317 } 15318 } 15319 15320 return sticky; 15321 } 15322 } 15323 15324 public void unregisterReceiver(IIntentReceiver receiver) { 15325 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15326 15327 final long origId = Binder.clearCallingIdentity(); 15328 try { 15329 boolean doTrim = false; 15330 15331 synchronized(this) { 15332 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15333 if (rl != null) { 15334 final BroadcastRecord r = rl.curBroadcast; 15335 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { 15336 final boolean doNext = r.queue.finishReceiverLocked( 15337 r, r.resultCode, r.resultData, r.resultExtras, 15338 r.resultAbort, false); 15339 if (doNext) { 15340 doTrim = true; 15341 r.queue.processNextBroadcast(false); 15342 } 15343 } 15344 15345 if (rl.app != null) { 15346 rl.app.receivers.remove(rl); 15347 } 15348 removeReceiverLocked(rl); 15349 if (rl.linkedToDeath) { 15350 rl.linkedToDeath = false; 15351 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15352 } 15353 } 15354 } 15355 15356 // If we actually concluded any broadcasts, we might now be able 15357 // to trim the recipients' apps from our working set 15358 if (doTrim) { 15359 trimApplications(); 15360 return; 15361 } 15362 15363 } finally { 15364 Binder.restoreCallingIdentity(origId); 15365 } 15366 } 15367 15368 void removeReceiverLocked(ReceiverList rl) { 15369 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15370 int N = rl.size(); 15371 for (int i=0; i<N; i++) { 15372 mReceiverResolver.removeFilter(rl.get(i)); 15373 } 15374 } 15375 15376 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15377 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15378 ProcessRecord r = mLruProcesses.get(i); 15379 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15380 try { 15381 r.thread.dispatchPackageBroadcast(cmd, packages); 15382 } catch (RemoteException ex) { 15383 } 15384 } 15385 } 15386 } 15387 15388 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15389 int callingUid, int[] users) { 15390 List<ResolveInfo> receivers = null; 15391 try { 15392 HashSet<ComponentName> singleUserReceivers = null; 15393 boolean scannedFirstReceivers = false; 15394 for (int user : users) { 15395 // Skip users that have Shell restrictions 15396 if (callingUid == Process.SHELL_UID 15397 && getUserManagerLocked().hasUserRestriction( 15398 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15399 continue; 15400 } 15401 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15402 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15403 if (user != 0 && newReceivers != null) { 15404 // If this is not the primary user, we need to check for 15405 // any receivers that should be filtered out. 15406 for (int i=0; i<newReceivers.size(); i++) { 15407 ResolveInfo ri = newReceivers.get(i); 15408 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15409 newReceivers.remove(i); 15410 i--; 15411 } 15412 } 15413 } 15414 if (newReceivers != null && newReceivers.size() == 0) { 15415 newReceivers = null; 15416 } 15417 if (receivers == null) { 15418 receivers = newReceivers; 15419 } else if (newReceivers != null) { 15420 // We need to concatenate the additional receivers 15421 // found with what we have do far. This would be easy, 15422 // but we also need to de-dup any receivers that are 15423 // singleUser. 15424 if (!scannedFirstReceivers) { 15425 // Collect any single user receivers we had already retrieved. 15426 scannedFirstReceivers = true; 15427 for (int i=0; i<receivers.size(); i++) { 15428 ResolveInfo ri = receivers.get(i); 15429 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15430 ComponentName cn = new ComponentName( 15431 ri.activityInfo.packageName, ri.activityInfo.name); 15432 if (singleUserReceivers == null) { 15433 singleUserReceivers = new HashSet<ComponentName>(); 15434 } 15435 singleUserReceivers.add(cn); 15436 } 15437 } 15438 } 15439 // Add the new results to the existing results, tracking 15440 // and de-dupping single user receivers. 15441 for (int i=0; i<newReceivers.size(); i++) { 15442 ResolveInfo ri = newReceivers.get(i); 15443 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15444 ComponentName cn = new ComponentName( 15445 ri.activityInfo.packageName, ri.activityInfo.name); 15446 if (singleUserReceivers == null) { 15447 singleUserReceivers = new HashSet<ComponentName>(); 15448 } 15449 if (!singleUserReceivers.contains(cn)) { 15450 singleUserReceivers.add(cn); 15451 receivers.add(ri); 15452 } 15453 } else { 15454 receivers.add(ri); 15455 } 15456 } 15457 } 15458 } 15459 } catch (RemoteException ex) { 15460 // pm is in same process, this will never happen. 15461 } 15462 return receivers; 15463 } 15464 15465 private final int broadcastIntentLocked(ProcessRecord callerApp, 15466 String callerPackage, Intent intent, String resolvedType, 15467 IIntentReceiver resultTo, int resultCode, String resultData, 15468 Bundle map, String requiredPermission, int appOp, 15469 boolean ordered, boolean sticky, int callingPid, int callingUid, 15470 int userId) { 15471 intent = new Intent(intent); 15472 15473 // By default broadcasts do not go to stopped apps. 15474 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15475 15476 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15477 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15478 + " ordered=" + ordered + " userid=" + userId); 15479 if ((resultTo != null) && !ordered) { 15480 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15481 } 15482 15483 userId = handleIncomingUser(callingPid, callingUid, userId, 15484 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15485 15486 // Make sure that the user who is receiving this broadcast is running. 15487 // If not, we will just skip it. 15488 15489 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15490 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15491 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15492 Slog.w(TAG, "Skipping broadcast of " + intent 15493 + ": user " + userId + " is stopped"); 15494 return ActivityManager.BROADCAST_SUCCESS; 15495 } 15496 } 15497 15498 /* 15499 * Prevent non-system code (defined here to be non-persistent 15500 * processes) from sending protected broadcasts. 15501 */ 15502 int callingAppId = UserHandle.getAppId(callingUid); 15503 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15504 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15505 || callingAppId == Process.NFC_UID || callingUid == 0) { 15506 // Always okay. 15507 } else if (callerApp == null || !callerApp.persistent) { 15508 try { 15509 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15510 intent.getAction())) { 15511 String msg = "Permission Denial: not allowed to send broadcast " 15512 + intent.getAction() + " from pid=" 15513 + callingPid + ", uid=" + callingUid; 15514 Slog.w(TAG, msg); 15515 throw new SecurityException(msg); 15516 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15517 // Special case for compatibility: we don't want apps to send this, 15518 // but historically it has not been protected and apps may be using it 15519 // to poke their own app widget. So, instead of making it protected, 15520 // just limit it to the caller. 15521 if (callerApp == null) { 15522 String msg = "Permission Denial: not allowed to send broadcast " 15523 + intent.getAction() + " from unknown caller."; 15524 Slog.w(TAG, msg); 15525 throw new SecurityException(msg); 15526 } else if (intent.getComponent() != null) { 15527 // They are good enough to send to an explicit component... verify 15528 // it is being sent to the calling app. 15529 if (!intent.getComponent().getPackageName().equals( 15530 callerApp.info.packageName)) { 15531 String msg = "Permission Denial: not allowed to send broadcast " 15532 + intent.getAction() + " to " 15533 + intent.getComponent().getPackageName() + " from " 15534 + callerApp.info.packageName; 15535 Slog.w(TAG, msg); 15536 throw new SecurityException(msg); 15537 } 15538 } else { 15539 // Limit broadcast to their own package. 15540 intent.setPackage(callerApp.info.packageName); 15541 } 15542 } 15543 } catch (RemoteException e) { 15544 Slog.w(TAG, "Remote exception", e); 15545 return ActivityManager.BROADCAST_SUCCESS; 15546 } 15547 } 15548 15549 // Handle special intents: if this broadcast is from the package 15550 // manager about a package being removed, we need to remove all of 15551 // its activities from the history stack. 15552 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15553 intent.getAction()); 15554 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15555 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15556 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15557 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15558 || uidRemoved) { 15559 if (checkComponentPermission( 15560 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15561 callingPid, callingUid, -1, true) 15562 == PackageManager.PERMISSION_GRANTED) { 15563 if (uidRemoved) { 15564 final Bundle intentExtras = intent.getExtras(); 15565 final int uid = intentExtras != null 15566 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15567 if (uid >= 0) { 15568 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15569 synchronized (bs) { 15570 bs.removeUidStatsLocked(uid); 15571 } 15572 mAppOpsService.uidRemoved(uid); 15573 } 15574 } else { 15575 // If resources are unavailable just force stop all 15576 // those packages and flush the attribute cache as well. 15577 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15578 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15579 if (list != null && (list.length > 0)) { 15580 for (String pkg : list) { 15581 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15582 "storage unmount"); 15583 } 15584 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15585 sendPackageBroadcastLocked( 15586 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15587 } 15588 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15589 intent.getAction())) { 15590 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15591 } else { 15592 Uri data = intent.getData(); 15593 String ssp; 15594 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15595 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15596 intent.getAction()); 15597 boolean fullUninstall = removed && 15598 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15599 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15600 forceStopPackageLocked(ssp, UserHandle.getAppId( 15601 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15602 false, fullUninstall, userId, 15603 removed ? "pkg removed" : "pkg changed"); 15604 } 15605 if (removed) { 15606 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15607 new String[] {ssp}, userId); 15608 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15609 mAppOpsService.packageRemoved( 15610 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15611 15612 // Remove all permissions granted from/to this package 15613 removeUriPermissionsForPackageLocked(ssp, userId, true); 15614 } 15615 } 15616 } 15617 } 15618 } 15619 } else { 15620 String msg = "Permission Denial: " + intent.getAction() 15621 + " broadcast from " + callerPackage + " (pid=" + callingPid 15622 + ", uid=" + callingUid + ")" 15623 + " requires " 15624 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15625 Slog.w(TAG, msg); 15626 throw new SecurityException(msg); 15627 } 15628 15629 // Special case for adding a package: by default turn on compatibility 15630 // mode. 15631 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15632 Uri data = intent.getData(); 15633 String ssp; 15634 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15635 mCompatModePackages.handlePackageAddedLocked(ssp, 15636 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15637 } 15638 } 15639 15640 /* 15641 * If this is the time zone changed action, queue up a message that will reset the timezone 15642 * of all currently running processes. This message will get queued up before the broadcast 15643 * happens. 15644 */ 15645 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15646 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15647 } 15648 15649 /* 15650 * If the user set the time, let all running processes know. 15651 */ 15652 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15653 final int is24Hour = intent.getBooleanExtra( 15654 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15655 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15656 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15657 synchronized (stats) { 15658 stats.noteCurrentTimeChangedLocked(); 15659 } 15660 } 15661 15662 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15663 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15664 } 15665 15666 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15667 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15668 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15669 } 15670 15671 // Add to the sticky list if requested. 15672 if (sticky) { 15673 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15674 callingPid, callingUid) 15675 != PackageManager.PERMISSION_GRANTED) { 15676 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15677 + callingPid + ", uid=" + callingUid 15678 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15679 Slog.w(TAG, msg); 15680 throw new SecurityException(msg); 15681 } 15682 if (requiredPermission != null) { 15683 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15684 + " and enforce permission " + requiredPermission); 15685 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15686 } 15687 if (intent.getComponent() != null) { 15688 throw new SecurityException( 15689 "Sticky broadcasts can't target a specific component"); 15690 } 15691 // We use userId directly here, since the "all" target is maintained 15692 // as a separate set of sticky broadcasts. 15693 if (userId != UserHandle.USER_ALL) { 15694 // But first, if this is not a broadcast to all users, then 15695 // make sure it doesn't conflict with an existing broadcast to 15696 // all users. 15697 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15698 UserHandle.USER_ALL); 15699 if (stickies != null) { 15700 ArrayList<Intent> list = stickies.get(intent.getAction()); 15701 if (list != null) { 15702 int N = list.size(); 15703 int i; 15704 for (i=0; i<N; i++) { 15705 if (intent.filterEquals(list.get(i))) { 15706 throw new IllegalArgumentException( 15707 "Sticky broadcast " + intent + " for user " 15708 + userId + " conflicts with existing global broadcast"); 15709 } 15710 } 15711 } 15712 } 15713 } 15714 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15715 if (stickies == null) { 15716 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15717 mStickyBroadcasts.put(userId, stickies); 15718 } 15719 ArrayList<Intent> list = stickies.get(intent.getAction()); 15720 if (list == null) { 15721 list = new ArrayList<Intent>(); 15722 stickies.put(intent.getAction(), list); 15723 } 15724 int N = list.size(); 15725 int i; 15726 for (i=0; i<N; i++) { 15727 if (intent.filterEquals(list.get(i))) { 15728 // This sticky already exists, replace it. 15729 list.set(i, new Intent(intent)); 15730 break; 15731 } 15732 } 15733 if (i >= N) { 15734 list.add(new Intent(intent)); 15735 } 15736 } 15737 15738 int[] users; 15739 if (userId == UserHandle.USER_ALL) { 15740 // Caller wants broadcast to go to all started users. 15741 users = mStartedUserArray; 15742 } else { 15743 // Caller wants broadcast to go to one specific user. 15744 users = new int[] {userId}; 15745 } 15746 15747 // Figure out who all will receive this broadcast. 15748 List receivers = null; 15749 List<BroadcastFilter> registeredReceivers = null; 15750 // Need to resolve the intent to interested receivers... 15751 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15752 == 0) { 15753 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15754 } 15755 if (intent.getComponent() == null) { 15756 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15757 // Query one target user at a time, excluding shell-restricted users 15758 UserManagerService ums = getUserManagerLocked(); 15759 for (int i = 0; i < users.length; i++) { 15760 if (ums.hasUserRestriction( 15761 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15762 continue; 15763 } 15764 List<BroadcastFilter> registeredReceiversForUser = 15765 mReceiverResolver.queryIntent(intent, 15766 resolvedType, false, users[i]); 15767 if (registeredReceivers == null) { 15768 registeredReceivers = registeredReceiversForUser; 15769 } else if (registeredReceiversForUser != null) { 15770 registeredReceivers.addAll(registeredReceiversForUser); 15771 } 15772 } 15773 } else { 15774 registeredReceivers = mReceiverResolver.queryIntent(intent, 15775 resolvedType, false, userId); 15776 } 15777 } 15778 15779 final boolean replacePending = 15780 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15781 15782 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15783 + " replacePending=" + replacePending); 15784 15785 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15786 if (!ordered && NR > 0) { 15787 // If we are not serializing this broadcast, then send the 15788 // registered receivers separately so they don't wait for the 15789 // components to be launched. 15790 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15791 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15792 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15793 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15794 ordered, sticky, false, userId); 15795 if (DEBUG_BROADCAST) Slog.v( 15796 TAG, "Enqueueing parallel broadcast " + r); 15797 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15798 if (!replaced) { 15799 queue.enqueueParallelBroadcastLocked(r); 15800 queue.scheduleBroadcastsLocked(); 15801 } 15802 registeredReceivers = null; 15803 NR = 0; 15804 } 15805 15806 // Merge into one list. 15807 int ir = 0; 15808 if (receivers != null) { 15809 // A special case for PACKAGE_ADDED: do not allow the package 15810 // being added to see this broadcast. This prevents them from 15811 // using this as a back door to get run as soon as they are 15812 // installed. Maybe in the future we want to have a special install 15813 // broadcast or such for apps, but we'd like to deliberately make 15814 // this decision. 15815 String skipPackages[] = null; 15816 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15817 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15818 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15819 Uri data = intent.getData(); 15820 if (data != null) { 15821 String pkgName = data.getSchemeSpecificPart(); 15822 if (pkgName != null) { 15823 skipPackages = new String[] { pkgName }; 15824 } 15825 } 15826 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15827 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15828 } 15829 if (skipPackages != null && (skipPackages.length > 0)) { 15830 for (String skipPackage : skipPackages) { 15831 if (skipPackage != null) { 15832 int NT = receivers.size(); 15833 for (int it=0; it<NT; it++) { 15834 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15835 if (curt.activityInfo.packageName.equals(skipPackage)) { 15836 receivers.remove(it); 15837 it--; 15838 NT--; 15839 } 15840 } 15841 } 15842 } 15843 } 15844 15845 int NT = receivers != null ? receivers.size() : 0; 15846 int it = 0; 15847 ResolveInfo curt = null; 15848 BroadcastFilter curr = null; 15849 while (it < NT && ir < NR) { 15850 if (curt == null) { 15851 curt = (ResolveInfo)receivers.get(it); 15852 } 15853 if (curr == null) { 15854 curr = registeredReceivers.get(ir); 15855 } 15856 if (curr.getPriority() >= curt.priority) { 15857 // Insert this broadcast record into the final list. 15858 receivers.add(it, curr); 15859 ir++; 15860 curr = null; 15861 it++; 15862 NT++; 15863 } else { 15864 // Skip to the next ResolveInfo in the final list. 15865 it++; 15866 curt = null; 15867 } 15868 } 15869 } 15870 while (ir < NR) { 15871 if (receivers == null) { 15872 receivers = new ArrayList(); 15873 } 15874 receivers.add(registeredReceivers.get(ir)); 15875 ir++; 15876 } 15877 15878 if ((receivers != null && receivers.size() > 0) 15879 || resultTo != null) { 15880 BroadcastQueue queue = broadcastQueueForIntent(intent); 15881 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15882 callerPackage, callingPid, callingUid, resolvedType, 15883 requiredPermission, appOp, receivers, resultTo, resultCode, 15884 resultData, map, ordered, sticky, false, userId); 15885 if (DEBUG_BROADCAST) Slog.v( 15886 TAG, "Enqueueing ordered broadcast " + r 15887 + ": prev had " + queue.mOrderedBroadcasts.size()); 15888 if (DEBUG_BROADCAST) { 15889 int seq = r.intent.getIntExtra("seq", -1); 15890 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15891 } 15892 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15893 if (!replaced) { 15894 queue.enqueueOrderedBroadcastLocked(r); 15895 queue.scheduleBroadcastsLocked(); 15896 } 15897 } 15898 15899 return ActivityManager.BROADCAST_SUCCESS; 15900 } 15901 15902 final Intent verifyBroadcastLocked(Intent intent) { 15903 // Refuse possible leaked file descriptors 15904 if (intent != null && intent.hasFileDescriptors() == true) { 15905 throw new IllegalArgumentException("File descriptors passed in Intent"); 15906 } 15907 15908 int flags = intent.getFlags(); 15909 15910 if (!mProcessesReady) { 15911 // if the caller really truly claims to know what they're doing, go 15912 // ahead and allow the broadcast without launching any receivers 15913 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15914 intent = new Intent(intent); 15915 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15916 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15917 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15918 + " before boot completion"); 15919 throw new IllegalStateException("Cannot broadcast before boot completed"); 15920 } 15921 } 15922 15923 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15924 throw new IllegalArgumentException( 15925 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15926 } 15927 15928 return intent; 15929 } 15930 15931 public final int broadcastIntent(IApplicationThread caller, 15932 Intent intent, String resolvedType, IIntentReceiver resultTo, 15933 int resultCode, String resultData, Bundle map, 15934 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15935 enforceNotIsolatedCaller("broadcastIntent"); 15936 synchronized(this) { 15937 intent = verifyBroadcastLocked(intent); 15938 15939 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15940 final int callingPid = Binder.getCallingPid(); 15941 final int callingUid = Binder.getCallingUid(); 15942 final long origId = Binder.clearCallingIdentity(); 15943 int res = broadcastIntentLocked(callerApp, 15944 callerApp != null ? callerApp.info.packageName : null, 15945 intent, resolvedType, resultTo, 15946 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15947 callingPid, callingUid, userId); 15948 Binder.restoreCallingIdentity(origId); 15949 return res; 15950 } 15951 } 15952 15953 int broadcastIntentInPackage(String packageName, int uid, 15954 Intent intent, String resolvedType, IIntentReceiver resultTo, 15955 int resultCode, String resultData, Bundle map, 15956 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15957 synchronized(this) { 15958 intent = verifyBroadcastLocked(intent); 15959 15960 final long origId = Binder.clearCallingIdentity(); 15961 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15962 resultTo, resultCode, resultData, map, requiredPermission, 15963 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15964 Binder.restoreCallingIdentity(origId); 15965 return res; 15966 } 15967 } 15968 15969 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15970 // Refuse possible leaked file descriptors 15971 if (intent != null && intent.hasFileDescriptors() == true) { 15972 throw new IllegalArgumentException("File descriptors passed in Intent"); 15973 } 15974 15975 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15976 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15977 15978 synchronized(this) { 15979 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15980 != PackageManager.PERMISSION_GRANTED) { 15981 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15982 + Binder.getCallingPid() 15983 + ", uid=" + Binder.getCallingUid() 15984 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15985 Slog.w(TAG, msg); 15986 throw new SecurityException(msg); 15987 } 15988 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15989 if (stickies != null) { 15990 ArrayList<Intent> list = stickies.get(intent.getAction()); 15991 if (list != null) { 15992 int N = list.size(); 15993 int i; 15994 for (i=0; i<N; i++) { 15995 if (intent.filterEquals(list.get(i))) { 15996 list.remove(i); 15997 break; 15998 } 15999 } 16000 if (list.size() <= 0) { 16001 stickies.remove(intent.getAction()); 16002 } 16003 } 16004 if (stickies.size() <= 0) { 16005 mStickyBroadcasts.remove(userId); 16006 } 16007 } 16008 } 16009 } 16010 16011 void backgroundServicesFinishedLocked(int userId) { 16012 for (BroadcastQueue queue : mBroadcastQueues) { 16013 queue.backgroundServicesFinishedLocked(userId); 16014 } 16015 } 16016 16017 public void finishReceiver(IBinder who, int resultCode, String resultData, 16018 Bundle resultExtras, boolean resultAbort, int flags) { 16019 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16020 16021 // Refuse possible leaked file descriptors 16022 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16023 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16024 } 16025 16026 final long origId = Binder.clearCallingIdentity(); 16027 try { 16028 boolean doNext = false; 16029 BroadcastRecord r; 16030 16031 synchronized(this) { 16032 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 16033 ? mFgBroadcastQueue : mBgBroadcastQueue; 16034 r = queue.getMatchingOrderedReceiver(who); 16035 if (r != null) { 16036 doNext = r.queue.finishReceiverLocked(r, resultCode, 16037 resultData, resultExtras, resultAbort, true); 16038 } 16039 } 16040 16041 if (doNext) { 16042 r.queue.processNextBroadcast(false); 16043 } 16044 trimApplications(); 16045 } finally { 16046 Binder.restoreCallingIdentity(origId); 16047 } 16048 } 16049 16050 // ========================================================= 16051 // INSTRUMENTATION 16052 // ========================================================= 16053 16054 public boolean startInstrumentation(ComponentName className, 16055 String profileFile, int flags, Bundle arguments, 16056 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16057 int userId, String abiOverride) { 16058 enforceNotIsolatedCaller("startInstrumentation"); 16059 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16060 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16061 // Refuse possible leaked file descriptors 16062 if (arguments != null && arguments.hasFileDescriptors()) { 16063 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16064 } 16065 16066 synchronized(this) { 16067 InstrumentationInfo ii = null; 16068 ApplicationInfo ai = null; 16069 try { 16070 ii = mContext.getPackageManager().getInstrumentationInfo( 16071 className, STOCK_PM_FLAGS); 16072 ai = AppGlobals.getPackageManager().getApplicationInfo( 16073 ii.targetPackage, STOCK_PM_FLAGS, userId); 16074 } catch (PackageManager.NameNotFoundException e) { 16075 } catch (RemoteException e) { 16076 } 16077 if (ii == null) { 16078 reportStartInstrumentationFailure(watcher, className, 16079 "Unable to find instrumentation info for: " + className); 16080 return false; 16081 } 16082 if (ai == null) { 16083 reportStartInstrumentationFailure(watcher, className, 16084 "Unable to find instrumentation target package: " + ii.targetPackage); 16085 return false; 16086 } 16087 16088 int match = mContext.getPackageManager().checkSignatures( 16089 ii.targetPackage, ii.packageName); 16090 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16091 String msg = "Permission Denial: starting instrumentation " 16092 + className + " from pid=" 16093 + Binder.getCallingPid() 16094 + ", uid=" + Binder.getCallingPid() 16095 + " not allowed because package " + ii.packageName 16096 + " does not have a signature matching the target " 16097 + ii.targetPackage; 16098 reportStartInstrumentationFailure(watcher, className, msg); 16099 throw new SecurityException(msg); 16100 } 16101 16102 final long origId = Binder.clearCallingIdentity(); 16103 // Instrumentation can kill and relaunch even persistent processes 16104 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16105 "start instr"); 16106 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16107 app.instrumentationClass = className; 16108 app.instrumentationInfo = ai; 16109 app.instrumentationProfileFile = profileFile; 16110 app.instrumentationArguments = arguments; 16111 app.instrumentationWatcher = watcher; 16112 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16113 app.instrumentationResultClass = className; 16114 Binder.restoreCallingIdentity(origId); 16115 } 16116 16117 return true; 16118 } 16119 16120 /** 16121 * Report errors that occur while attempting to start Instrumentation. Always writes the 16122 * error to the logs, but if somebody is watching, send the report there too. This enables 16123 * the "am" command to report errors with more information. 16124 * 16125 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16126 * @param cn The component name of the instrumentation. 16127 * @param report The error report. 16128 */ 16129 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16130 ComponentName cn, String report) { 16131 Slog.w(TAG, report); 16132 try { 16133 if (watcher != null) { 16134 Bundle results = new Bundle(); 16135 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16136 results.putString("Error", report); 16137 watcher.instrumentationStatus(cn, -1, results); 16138 } 16139 } catch (RemoteException e) { 16140 Slog.w(TAG, e); 16141 } 16142 } 16143 16144 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16145 if (app.instrumentationWatcher != null) { 16146 try { 16147 // NOTE: IInstrumentationWatcher *must* be oneway here 16148 app.instrumentationWatcher.instrumentationFinished( 16149 app.instrumentationClass, 16150 resultCode, 16151 results); 16152 } catch (RemoteException e) { 16153 } 16154 } 16155 if (app.instrumentationUiAutomationConnection != null) { 16156 try { 16157 app.instrumentationUiAutomationConnection.shutdown(); 16158 } catch (RemoteException re) { 16159 /* ignore */ 16160 } 16161 // Only a UiAutomation can set this flag and now that 16162 // it is finished we make sure it is reset to its default. 16163 mUserIsMonkey = false; 16164 } 16165 app.instrumentationWatcher = null; 16166 app.instrumentationUiAutomationConnection = null; 16167 app.instrumentationClass = null; 16168 app.instrumentationInfo = null; 16169 app.instrumentationProfileFile = null; 16170 app.instrumentationArguments = null; 16171 16172 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16173 "finished inst"); 16174 } 16175 16176 public void finishInstrumentation(IApplicationThread target, 16177 int resultCode, Bundle results) { 16178 int userId = UserHandle.getCallingUserId(); 16179 // Refuse possible leaked file descriptors 16180 if (results != null && results.hasFileDescriptors()) { 16181 throw new IllegalArgumentException("File descriptors passed in Intent"); 16182 } 16183 16184 synchronized(this) { 16185 ProcessRecord app = getRecordForAppLocked(target); 16186 if (app == null) { 16187 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16188 return; 16189 } 16190 final long origId = Binder.clearCallingIdentity(); 16191 finishInstrumentationLocked(app, resultCode, results); 16192 Binder.restoreCallingIdentity(origId); 16193 } 16194 } 16195 16196 // ========================================================= 16197 // CONFIGURATION 16198 // ========================================================= 16199 16200 public ConfigurationInfo getDeviceConfigurationInfo() { 16201 ConfigurationInfo config = new ConfigurationInfo(); 16202 synchronized (this) { 16203 config.reqTouchScreen = mConfiguration.touchscreen; 16204 config.reqKeyboardType = mConfiguration.keyboard; 16205 config.reqNavigation = mConfiguration.navigation; 16206 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16207 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16208 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16209 } 16210 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16211 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16212 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16213 } 16214 config.reqGlEsVersion = GL_ES_VERSION; 16215 } 16216 return config; 16217 } 16218 16219 ActivityStack getFocusedStack() { 16220 return mStackSupervisor.getFocusedStack(); 16221 } 16222 16223 public Configuration getConfiguration() { 16224 Configuration ci; 16225 synchronized(this) { 16226 ci = new Configuration(mConfiguration); 16227 } 16228 return ci; 16229 } 16230 16231 public void updatePersistentConfiguration(Configuration values) { 16232 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16233 "updateConfiguration()"); 16234 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16235 "updateConfiguration()"); 16236 if (values == null) { 16237 throw new NullPointerException("Configuration must not be null"); 16238 } 16239 16240 synchronized(this) { 16241 final long origId = Binder.clearCallingIdentity(); 16242 updateConfigurationLocked(values, null, true, false); 16243 Binder.restoreCallingIdentity(origId); 16244 } 16245 } 16246 16247 public void updateConfiguration(Configuration values) { 16248 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16249 "updateConfiguration()"); 16250 16251 synchronized(this) { 16252 if (values == null && mWindowManager != null) { 16253 // sentinel: fetch the current configuration from the window manager 16254 values = mWindowManager.computeNewConfiguration(); 16255 } 16256 16257 if (mWindowManager != null) { 16258 mProcessList.applyDisplaySize(mWindowManager); 16259 } 16260 16261 final long origId = Binder.clearCallingIdentity(); 16262 if (values != null) { 16263 Settings.System.clearConfiguration(values); 16264 } 16265 updateConfigurationLocked(values, null, false, false); 16266 Binder.restoreCallingIdentity(origId); 16267 } 16268 } 16269 16270 /** 16271 * Do either or both things: (1) change the current configuration, and (2) 16272 * make sure the given activity is running with the (now) current 16273 * configuration. Returns true if the activity has been left running, or 16274 * false if <var>starting</var> is being destroyed to match the new 16275 * configuration. 16276 * @param persistent TODO 16277 */ 16278 boolean updateConfigurationLocked(Configuration values, 16279 ActivityRecord starting, boolean persistent, boolean initLocale) { 16280 int changes = 0; 16281 16282 if (values != null) { 16283 Configuration newConfig = new Configuration(mConfiguration); 16284 changes = newConfig.updateFrom(values); 16285 if (changes != 0) { 16286 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16287 Slog.i(TAG, "Updating configuration to: " + values); 16288 } 16289 16290 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16291 16292 if (values.locale != null && !initLocale) { 16293 saveLocaleLocked(values.locale, 16294 !values.locale.equals(mConfiguration.locale), 16295 values.userSetLocale); 16296 } 16297 16298 mConfigurationSeq++; 16299 if (mConfigurationSeq <= 0) { 16300 mConfigurationSeq = 1; 16301 } 16302 newConfig.seq = mConfigurationSeq; 16303 mConfiguration = newConfig; 16304 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16305 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16306 //mUsageStatsService.noteStartConfig(newConfig); 16307 16308 final Configuration configCopy = new Configuration(mConfiguration); 16309 16310 // TODO: If our config changes, should we auto dismiss any currently 16311 // showing dialogs? 16312 mShowDialogs = shouldShowDialogs(newConfig); 16313 16314 AttributeCache ac = AttributeCache.instance(); 16315 if (ac != null) { 16316 ac.updateConfiguration(configCopy); 16317 } 16318 16319 // Make sure all resources in our process are updated 16320 // right now, so that anyone who is going to retrieve 16321 // resource values after we return will be sure to get 16322 // the new ones. This is especially important during 16323 // boot, where the first config change needs to guarantee 16324 // all resources have that config before following boot 16325 // code is executed. 16326 mSystemThread.applyConfigurationToResources(configCopy); 16327 16328 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16329 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16330 msg.obj = new Configuration(configCopy); 16331 mHandler.sendMessage(msg); 16332 } 16333 16334 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16335 ProcessRecord app = mLruProcesses.get(i); 16336 try { 16337 if (app.thread != null) { 16338 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16339 + app.processName + " new config " + mConfiguration); 16340 app.thread.scheduleConfigurationChanged(configCopy); 16341 } 16342 } catch (Exception e) { 16343 } 16344 } 16345 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16346 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16347 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16348 | Intent.FLAG_RECEIVER_FOREGROUND); 16349 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16350 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16351 Process.SYSTEM_UID, UserHandle.USER_ALL); 16352 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16353 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16354 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16355 broadcastIntentLocked(null, null, intent, 16356 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16357 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16358 } 16359 } 16360 } 16361 16362 boolean kept = true; 16363 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16364 // mainStack is null during startup. 16365 if (mainStack != null) { 16366 if (changes != 0 && starting == null) { 16367 // If the configuration changed, and the caller is not already 16368 // in the process of starting an activity, then find the top 16369 // activity to check if its configuration needs to change. 16370 starting = mainStack.topRunningActivityLocked(null); 16371 } 16372 16373 if (starting != null) { 16374 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16375 // And we need to make sure at this point that all other activities 16376 // are made visible with the correct configuration. 16377 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16378 } 16379 } 16380 16381 if (values != null && mWindowManager != null) { 16382 mWindowManager.setNewConfiguration(mConfiguration); 16383 } 16384 16385 return kept; 16386 } 16387 16388 /** 16389 * Decide based on the configuration whether we should shouw the ANR, 16390 * crash, etc dialogs. The idea is that if there is no affordnace to 16391 * press the on-screen buttons, we shouldn't show the dialog. 16392 * 16393 * A thought: SystemUI might also want to get told about this, the Power 16394 * dialog / global actions also might want different behaviors. 16395 */ 16396 private static final boolean shouldShowDialogs(Configuration config) { 16397 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16398 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16399 } 16400 16401 /** 16402 * Save the locale. You must be inside a synchronized (this) block. 16403 */ 16404 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16405 if(isDiff) { 16406 SystemProperties.set("user.language", l.getLanguage()); 16407 SystemProperties.set("user.region", l.getCountry()); 16408 } 16409 16410 if(isPersist) { 16411 SystemProperties.set("persist.sys.language", l.getLanguage()); 16412 SystemProperties.set("persist.sys.country", l.getCountry()); 16413 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16414 16415 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16416 } 16417 } 16418 16419 @Override 16420 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16421 synchronized (this) { 16422 ActivityRecord srec = ActivityRecord.forToken(token); 16423 if (srec.task != null && srec.task.stack != null) { 16424 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16425 } 16426 } 16427 return false; 16428 } 16429 16430 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16431 Intent resultData) { 16432 16433 synchronized (this) { 16434 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16435 if (stack != null) { 16436 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16437 } 16438 return false; 16439 } 16440 } 16441 16442 public int getLaunchedFromUid(IBinder activityToken) { 16443 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16444 if (srec == null) { 16445 return -1; 16446 } 16447 return srec.launchedFromUid; 16448 } 16449 16450 public String getLaunchedFromPackage(IBinder activityToken) { 16451 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16452 if (srec == null) { 16453 return null; 16454 } 16455 return srec.launchedFromPackage; 16456 } 16457 16458 // ========================================================= 16459 // LIFETIME MANAGEMENT 16460 // ========================================================= 16461 16462 // Returns which broadcast queue the app is the current [or imminent] receiver 16463 // on, or 'null' if the app is not an active broadcast recipient. 16464 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16465 BroadcastRecord r = app.curReceiver; 16466 if (r != null) { 16467 return r.queue; 16468 } 16469 16470 // It's not the current receiver, but it might be starting up to become one 16471 synchronized (this) { 16472 for (BroadcastQueue queue : mBroadcastQueues) { 16473 r = queue.mPendingBroadcast; 16474 if (r != null && r.curApp == app) { 16475 // found it; report which queue it's in 16476 return queue; 16477 } 16478 } 16479 } 16480 16481 return null; 16482 } 16483 16484 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16485 boolean doingAll, long now) { 16486 if (mAdjSeq == app.adjSeq) { 16487 // This adjustment has already been computed. 16488 return app.curRawAdj; 16489 } 16490 16491 if (app.thread == null) { 16492 app.adjSeq = mAdjSeq; 16493 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16494 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16495 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16496 } 16497 16498 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16499 app.adjSource = null; 16500 app.adjTarget = null; 16501 app.empty = false; 16502 app.cached = false; 16503 16504 final int activitiesSize = app.activities.size(); 16505 16506 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16507 // The max adjustment doesn't allow this app to be anything 16508 // below foreground, so it is not worth doing work for it. 16509 app.adjType = "fixed"; 16510 app.adjSeq = mAdjSeq; 16511 app.curRawAdj = app.maxAdj; 16512 app.foregroundActivities = false; 16513 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16514 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16515 // System processes can do UI, and when they do we want to have 16516 // them trim their memory after the user leaves the UI. To 16517 // facilitate this, here we need to determine whether or not it 16518 // is currently showing UI. 16519 app.systemNoUi = true; 16520 if (app == TOP_APP) { 16521 app.systemNoUi = false; 16522 } else if (activitiesSize > 0) { 16523 for (int j = 0; j < activitiesSize; j++) { 16524 final ActivityRecord r = app.activities.get(j); 16525 if (r.visible) { 16526 app.systemNoUi = false; 16527 } 16528 } 16529 } 16530 if (!app.systemNoUi) { 16531 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16532 } 16533 return (app.curAdj=app.maxAdj); 16534 } 16535 16536 app.systemNoUi = false; 16537 16538 // Determine the importance of the process, starting with most 16539 // important to least, and assign an appropriate OOM adjustment. 16540 int adj; 16541 int schedGroup; 16542 int procState; 16543 boolean foregroundActivities = false; 16544 BroadcastQueue queue; 16545 if (app == TOP_APP) { 16546 // The last app on the list is the foreground app. 16547 adj = ProcessList.FOREGROUND_APP_ADJ; 16548 schedGroup = Process.THREAD_GROUP_DEFAULT; 16549 app.adjType = "top-activity"; 16550 foregroundActivities = true; 16551 procState = ActivityManager.PROCESS_STATE_TOP; 16552 } else if (app.instrumentationClass != null) { 16553 // Don't want to kill running instrumentation. 16554 adj = ProcessList.FOREGROUND_APP_ADJ; 16555 schedGroup = Process.THREAD_GROUP_DEFAULT; 16556 app.adjType = "instrumentation"; 16557 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16558 } else if ((queue = isReceivingBroadcast(app)) != null) { 16559 // An app that is currently receiving a broadcast also 16560 // counts as being in the foreground for OOM killer purposes. 16561 // It's placed in a sched group based on the nature of the 16562 // broadcast as reflected by which queue it's active in. 16563 adj = ProcessList.FOREGROUND_APP_ADJ; 16564 schedGroup = (queue == mFgBroadcastQueue) 16565 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16566 app.adjType = "broadcast"; 16567 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16568 } else if (app.executingServices.size() > 0) { 16569 // An app that is currently executing a service callback also 16570 // counts as being in the foreground. 16571 adj = ProcessList.FOREGROUND_APP_ADJ; 16572 schedGroup = app.execServicesFg ? 16573 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16574 app.adjType = "exec-service"; 16575 procState = ActivityManager.PROCESS_STATE_SERVICE; 16576 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16577 } else { 16578 // As far as we know the process is empty. We may change our mind later. 16579 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16580 // At this point we don't actually know the adjustment. Use the cached adj 16581 // value that the caller wants us to. 16582 adj = cachedAdj; 16583 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16584 app.cached = true; 16585 app.empty = true; 16586 app.adjType = "cch-empty"; 16587 } 16588 16589 // Examine all activities if not already foreground. 16590 if (!foregroundActivities && activitiesSize > 0) { 16591 for (int j = 0; j < activitiesSize; j++) { 16592 final ActivityRecord r = app.activities.get(j); 16593 if (r.app != app) { 16594 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16595 + app + "?!?"); 16596 continue; 16597 } 16598 if (r.visible) { 16599 // App has a visible activity; only upgrade adjustment. 16600 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16601 adj = ProcessList.VISIBLE_APP_ADJ; 16602 app.adjType = "visible"; 16603 } 16604 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16605 procState = ActivityManager.PROCESS_STATE_TOP; 16606 } 16607 schedGroup = Process.THREAD_GROUP_DEFAULT; 16608 app.cached = false; 16609 app.empty = false; 16610 foregroundActivities = true; 16611 break; 16612 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16613 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16614 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16615 app.adjType = "pausing"; 16616 } 16617 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16618 procState = ActivityManager.PROCESS_STATE_TOP; 16619 } 16620 schedGroup = Process.THREAD_GROUP_DEFAULT; 16621 app.cached = false; 16622 app.empty = false; 16623 foregroundActivities = true; 16624 } else if (r.state == ActivityState.STOPPING) { 16625 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16626 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16627 app.adjType = "stopping"; 16628 } 16629 // For the process state, we will at this point consider the 16630 // process to be cached. It will be cached either as an activity 16631 // or empty depending on whether the activity is finishing. We do 16632 // this so that we can treat the process as cached for purposes of 16633 // memory trimming (determing current memory level, trim command to 16634 // send to process) since there can be an arbitrary number of stopping 16635 // processes and they should soon all go into the cached state. 16636 if (!r.finishing) { 16637 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16638 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16639 } 16640 } 16641 app.cached = false; 16642 app.empty = false; 16643 foregroundActivities = true; 16644 } else { 16645 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16646 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16647 app.adjType = "cch-act"; 16648 } 16649 } 16650 } 16651 } 16652 16653 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16654 if (app.foregroundServices) { 16655 // The user is aware of this app, so make it visible. 16656 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16657 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16658 app.cached = false; 16659 app.adjType = "fg-service"; 16660 schedGroup = Process.THREAD_GROUP_DEFAULT; 16661 } else if (app.forcingToForeground != null) { 16662 // The user is aware of this app, so make it visible. 16663 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16664 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16665 app.cached = false; 16666 app.adjType = "force-fg"; 16667 app.adjSource = app.forcingToForeground; 16668 schedGroup = Process.THREAD_GROUP_DEFAULT; 16669 } 16670 } 16671 16672 if (app == mHeavyWeightProcess) { 16673 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16674 // We don't want to kill the current heavy-weight process. 16675 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16676 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16677 app.cached = false; 16678 app.adjType = "heavy"; 16679 } 16680 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16681 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16682 } 16683 } 16684 16685 if (app == mHomeProcess) { 16686 if (adj > ProcessList.HOME_APP_ADJ) { 16687 // This process is hosting what we currently consider to be the 16688 // home app, so we don't want to let it go into the background. 16689 adj = ProcessList.HOME_APP_ADJ; 16690 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16691 app.cached = false; 16692 app.adjType = "home"; 16693 } 16694 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16695 procState = ActivityManager.PROCESS_STATE_HOME; 16696 } 16697 } 16698 16699 if (app == mPreviousProcess && app.activities.size() > 0) { 16700 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16701 // This was the previous process that showed UI to the user. 16702 // We want to try to keep it around more aggressively, to give 16703 // a good experience around switching between two apps. 16704 adj = ProcessList.PREVIOUS_APP_ADJ; 16705 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16706 app.cached = false; 16707 app.adjType = "previous"; 16708 } 16709 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16710 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16711 } 16712 } 16713 16714 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16715 + " reason=" + app.adjType); 16716 16717 // By default, we use the computed adjustment. It may be changed if 16718 // there are applications dependent on our services or providers, but 16719 // this gives us a baseline and makes sure we don't get into an 16720 // infinite recursion. 16721 app.adjSeq = mAdjSeq; 16722 app.curRawAdj = adj; 16723 app.hasStartedServices = false; 16724 16725 if (mBackupTarget != null && app == mBackupTarget.app) { 16726 // If possible we want to avoid killing apps while they're being backed up 16727 if (adj > ProcessList.BACKUP_APP_ADJ) { 16728 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16729 adj = ProcessList.BACKUP_APP_ADJ; 16730 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16731 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16732 } 16733 app.adjType = "backup"; 16734 app.cached = false; 16735 } 16736 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16737 procState = ActivityManager.PROCESS_STATE_BACKUP; 16738 } 16739 } 16740 16741 boolean mayBeTop = false; 16742 16743 for (int is = app.services.size()-1; 16744 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16745 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16746 || procState > ActivityManager.PROCESS_STATE_TOP); 16747 is--) { 16748 ServiceRecord s = app.services.valueAt(is); 16749 if (s.startRequested) { 16750 app.hasStartedServices = true; 16751 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16752 procState = ActivityManager.PROCESS_STATE_SERVICE; 16753 } 16754 if (app.hasShownUi && app != mHomeProcess) { 16755 // If this process has shown some UI, let it immediately 16756 // go to the LRU list because it may be pretty heavy with 16757 // UI stuff. We'll tag it with a label just to help 16758 // debug and understand what is going on. 16759 if (adj > ProcessList.SERVICE_ADJ) { 16760 app.adjType = "cch-started-ui-services"; 16761 } 16762 } else { 16763 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16764 // This service has seen some activity within 16765 // recent memory, so we will keep its process ahead 16766 // of the background processes. 16767 if (adj > ProcessList.SERVICE_ADJ) { 16768 adj = ProcessList.SERVICE_ADJ; 16769 app.adjType = "started-services"; 16770 app.cached = false; 16771 } 16772 } 16773 // If we have let the service slide into the background 16774 // state, still have some text describing what it is doing 16775 // even though the service no longer has an impact. 16776 if (adj > ProcessList.SERVICE_ADJ) { 16777 app.adjType = "cch-started-services"; 16778 } 16779 } 16780 } 16781 for (int conni = s.connections.size()-1; 16782 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16783 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16784 || procState > ActivityManager.PROCESS_STATE_TOP); 16785 conni--) { 16786 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16787 for (int i = 0; 16788 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16789 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16790 || procState > ActivityManager.PROCESS_STATE_TOP); 16791 i++) { 16792 // XXX should compute this based on the max of 16793 // all connected clients. 16794 ConnectionRecord cr = clist.get(i); 16795 if (cr.binding.client == app) { 16796 // Binding to ourself is not interesting. 16797 continue; 16798 } 16799 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16800 ProcessRecord client = cr.binding.client; 16801 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16802 TOP_APP, doingAll, now); 16803 int clientProcState = client.curProcState; 16804 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16805 // If the other app is cached for any reason, for purposes here 16806 // we are going to consider it empty. The specific cached state 16807 // doesn't propagate except under certain conditions. 16808 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16809 } 16810 String adjType = null; 16811 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16812 // Not doing bind OOM management, so treat 16813 // this guy more like a started service. 16814 if (app.hasShownUi && app != mHomeProcess) { 16815 // If this process has shown some UI, let it immediately 16816 // go to the LRU list because it may be pretty heavy with 16817 // UI stuff. We'll tag it with a label just to help 16818 // debug and understand what is going on. 16819 if (adj > clientAdj) { 16820 adjType = "cch-bound-ui-services"; 16821 } 16822 app.cached = false; 16823 clientAdj = adj; 16824 clientProcState = procState; 16825 } else { 16826 if (now >= (s.lastActivity 16827 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16828 // This service has not seen activity within 16829 // recent memory, so allow it to drop to the 16830 // LRU list if there is no other reason to keep 16831 // it around. We'll also tag it with a label just 16832 // to help debug and undertand what is going on. 16833 if (adj > clientAdj) { 16834 adjType = "cch-bound-services"; 16835 } 16836 clientAdj = adj; 16837 } 16838 } 16839 } 16840 if (adj > clientAdj) { 16841 // If this process has recently shown UI, and 16842 // the process that is binding to it is less 16843 // important than being visible, then we don't 16844 // care about the binding as much as we care 16845 // about letting this process get into the LRU 16846 // list to be killed and restarted if needed for 16847 // memory. 16848 if (app.hasShownUi && app != mHomeProcess 16849 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16850 adjType = "cch-bound-ui-services"; 16851 } else { 16852 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16853 |Context.BIND_IMPORTANT)) != 0) { 16854 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16855 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16856 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16857 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16858 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16859 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16860 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16861 adj = clientAdj; 16862 } else { 16863 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16864 adj = ProcessList.VISIBLE_APP_ADJ; 16865 } 16866 } 16867 if (!client.cached) { 16868 app.cached = false; 16869 } 16870 adjType = "service"; 16871 } 16872 } 16873 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16874 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16875 schedGroup = Process.THREAD_GROUP_DEFAULT; 16876 } 16877 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16878 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16879 // Special handling of clients who are in the top state. 16880 // We *may* want to consider this process to be in the 16881 // top state as well, but only if there is not another 16882 // reason for it to be running. Being on the top is a 16883 // special state, meaning you are specifically running 16884 // for the current top app. If the process is already 16885 // running in the background for some other reason, it 16886 // is more important to continue considering it to be 16887 // in the background state. 16888 mayBeTop = true; 16889 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16890 } else { 16891 // Special handling for above-top states (persistent 16892 // processes). These should not bring the current process 16893 // into the top state, since they are not on top. Instead 16894 // give them the best state after that. 16895 clientProcState = 16896 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16897 } 16898 } 16899 } else { 16900 if (clientProcState < 16901 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16902 clientProcState = 16903 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16904 } 16905 } 16906 if (procState > clientProcState) { 16907 procState = clientProcState; 16908 } 16909 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16910 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16911 app.pendingUiClean = true; 16912 } 16913 if (adjType != null) { 16914 app.adjType = adjType; 16915 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16916 .REASON_SERVICE_IN_USE; 16917 app.adjSource = cr.binding.client; 16918 app.adjSourceProcState = clientProcState; 16919 app.adjTarget = s.name; 16920 } 16921 } 16922 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16923 app.treatLikeActivity = true; 16924 } 16925 final ActivityRecord a = cr.activity; 16926 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16927 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16928 (a.visible || a.state == ActivityState.RESUMED 16929 || a.state == ActivityState.PAUSING)) { 16930 adj = ProcessList.FOREGROUND_APP_ADJ; 16931 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16932 schedGroup = Process.THREAD_GROUP_DEFAULT; 16933 } 16934 app.cached = false; 16935 app.adjType = "service"; 16936 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16937 .REASON_SERVICE_IN_USE; 16938 app.adjSource = a; 16939 app.adjSourceProcState = procState; 16940 app.adjTarget = s.name; 16941 } 16942 } 16943 } 16944 } 16945 } 16946 16947 for (int provi = app.pubProviders.size()-1; 16948 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16949 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16950 || procState > ActivityManager.PROCESS_STATE_TOP); 16951 provi--) { 16952 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16953 for (int i = cpr.connections.size()-1; 16954 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16955 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16956 || procState > ActivityManager.PROCESS_STATE_TOP); 16957 i--) { 16958 ContentProviderConnection conn = cpr.connections.get(i); 16959 ProcessRecord client = conn.client; 16960 if (client == app) { 16961 // Being our own client is not interesting. 16962 continue; 16963 } 16964 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16965 int clientProcState = client.curProcState; 16966 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16967 // If the other app is cached for any reason, for purposes here 16968 // we are going to consider it empty. 16969 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16970 } 16971 if (adj > clientAdj) { 16972 if (app.hasShownUi && app != mHomeProcess 16973 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16974 app.adjType = "cch-ui-provider"; 16975 } else { 16976 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16977 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16978 app.adjType = "provider"; 16979 } 16980 app.cached &= client.cached; 16981 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16982 .REASON_PROVIDER_IN_USE; 16983 app.adjSource = client; 16984 app.adjSourceProcState = clientProcState; 16985 app.adjTarget = cpr.name; 16986 } 16987 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16988 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16989 // Special handling of clients who are in the top state. 16990 // We *may* want to consider this process to be in the 16991 // top state as well, but only if there is not another 16992 // reason for it to be running. Being on the top is a 16993 // special state, meaning you are specifically running 16994 // for the current top app. If the process is already 16995 // running in the background for some other reason, it 16996 // is more important to continue considering it to be 16997 // in the background state. 16998 mayBeTop = true; 16999 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17000 } else { 17001 // Special handling for above-top states (persistent 17002 // processes). These should not bring the current process 17003 // into the top state, since they are not on top. Instead 17004 // give them the best state after that. 17005 clientProcState = 17006 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17007 } 17008 } 17009 if (procState > clientProcState) { 17010 procState = clientProcState; 17011 } 17012 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17013 schedGroup = Process.THREAD_GROUP_DEFAULT; 17014 } 17015 } 17016 // If the provider has external (non-framework) process 17017 // dependencies, ensure that its adjustment is at least 17018 // FOREGROUND_APP_ADJ. 17019 if (cpr.hasExternalProcessHandles()) { 17020 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17021 adj = ProcessList.FOREGROUND_APP_ADJ; 17022 schedGroup = Process.THREAD_GROUP_DEFAULT; 17023 app.cached = false; 17024 app.adjType = "provider"; 17025 app.adjTarget = cpr.name; 17026 } 17027 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17028 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17029 } 17030 } 17031 } 17032 17033 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17034 // A client of one of our services or providers is in the top state. We 17035 // *may* want to be in the top state, but not if we are already running in 17036 // the background for some other reason. For the decision here, we are going 17037 // to pick out a few specific states that we want to remain in when a client 17038 // is top (states that tend to be longer-term) and otherwise allow it to go 17039 // to the top state. 17040 switch (procState) { 17041 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17042 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17043 case ActivityManager.PROCESS_STATE_SERVICE: 17044 // These all are longer-term states, so pull them up to the top 17045 // of the background states, but not all the way to the top state. 17046 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17047 break; 17048 default: 17049 // Otherwise, top is a better choice, so take it. 17050 procState = ActivityManager.PROCESS_STATE_TOP; 17051 break; 17052 } 17053 } 17054 17055 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17056 if (app.hasClientActivities) { 17057 // This is a cached process, but with client activities. Mark it so. 17058 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17059 app.adjType = "cch-client-act"; 17060 } else if (app.treatLikeActivity) { 17061 // This is a cached process, but somebody wants us to treat it like it has 17062 // an activity, okay! 17063 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17064 app.adjType = "cch-as-act"; 17065 } 17066 } 17067 17068 if (adj == ProcessList.SERVICE_ADJ) { 17069 if (doingAll) { 17070 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17071 mNewNumServiceProcs++; 17072 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17073 if (!app.serviceb) { 17074 // This service isn't far enough down on the LRU list to 17075 // normally be a B service, but if we are low on RAM and it 17076 // is large we want to force it down since we would prefer to 17077 // keep launcher over it. 17078 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17079 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17080 app.serviceHighRam = true; 17081 app.serviceb = true; 17082 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17083 } else { 17084 mNewNumAServiceProcs++; 17085 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17086 } 17087 } else { 17088 app.serviceHighRam = false; 17089 } 17090 } 17091 if (app.serviceb) { 17092 adj = ProcessList.SERVICE_B_ADJ; 17093 } 17094 } 17095 17096 app.curRawAdj = adj; 17097 17098 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17099 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17100 if (adj > app.maxAdj) { 17101 adj = app.maxAdj; 17102 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17103 schedGroup = Process.THREAD_GROUP_DEFAULT; 17104 } 17105 } 17106 17107 // Do final modification to adj. Everything we do between here and applying 17108 // the final setAdj must be done in this function, because we will also use 17109 // it when computing the final cached adj later. Note that we don't need to 17110 // worry about this for max adj above, since max adj will always be used to 17111 // keep it out of the cached vaues. 17112 app.curAdj = app.modifyRawOomAdj(adj); 17113 app.curSchedGroup = schedGroup; 17114 app.curProcState = procState; 17115 app.foregroundActivities = foregroundActivities; 17116 17117 return app.curRawAdj; 17118 } 17119 17120 /** 17121 * Schedule PSS collection of a process. 17122 */ 17123 void requestPssLocked(ProcessRecord proc, int procState) { 17124 if (mPendingPssProcesses.contains(proc)) { 17125 return; 17126 } 17127 if (mPendingPssProcesses.size() == 0) { 17128 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17129 } 17130 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17131 proc.pssProcState = procState; 17132 mPendingPssProcesses.add(proc); 17133 } 17134 17135 /** 17136 * Schedule PSS collection of all processes. 17137 */ 17138 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17139 if (!always) { 17140 if (now < (mLastFullPssTime + 17141 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17142 return; 17143 } 17144 } 17145 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17146 mLastFullPssTime = now; 17147 mFullPssPending = true; 17148 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17149 mPendingPssProcesses.clear(); 17150 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17151 ProcessRecord app = mLruProcesses.get(i); 17152 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17153 app.pssProcState = app.setProcState; 17154 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17155 isSleeping(), now); 17156 mPendingPssProcesses.add(app); 17157 } 17158 } 17159 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17160 } 17161 17162 /** 17163 * Ask a given process to GC right now. 17164 */ 17165 final void performAppGcLocked(ProcessRecord app) { 17166 try { 17167 app.lastRequestedGc = SystemClock.uptimeMillis(); 17168 if (app.thread != null) { 17169 if (app.reportLowMemory) { 17170 app.reportLowMemory = false; 17171 app.thread.scheduleLowMemory(); 17172 } else { 17173 app.thread.processInBackground(); 17174 } 17175 } 17176 } catch (Exception e) { 17177 // whatever. 17178 } 17179 } 17180 17181 /** 17182 * Returns true if things are idle enough to perform GCs. 17183 */ 17184 private final boolean canGcNowLocked() { 17185 boolean processingBroadcasts = false; 17186 for (BroadcastQueue q : mBroadcastQueues) { 17187 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17188 processingBroadcasts = true; 17189 } 17190 } 17191 return !processingBroadcasts 17192 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17193 } 17194 17195 /** 17196 * Perform GCs on all processes that are waiting for it, but only 17197 * if things are idle. 17198 */ 17199 final void performAppGcsLocked() { 17200 final int N = mProcessesToGc.size(); 17201 if (N <= 0) { 17202 return; 17203 } 17204 if (canGcNowLocked()) { 17205 while (mProcessesToGc.size() > 0) { 17206 ProcessRecord proc = mProcessesToGc.remove(0); 17207 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17208 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17209 <= SystemClock.uptimeMillis()) { 17210 // To avoid spamming the system, we will GC processes one 17211 // at a time, waiting a few seconds between each. 17212 performAppGcLocked(proc); 17213 scheduleAppGcsLocked(); 17214 return; 17215 } else { 17216 // It hasn't been long enough since we last GCed this 17217 // process... put it in the list to wait for its time. 17218 addProcessToGcListLocked(proc); 17219 break; 17220 } 17221 } 17222 } 17223 17224 scheduleAppGcsLocked(); 17225 } 17226 } 17227 17228 /** 17229 * If all looks good, perform GCs on all processes waiting for them. 17230 */ 17231 final void performAppGcsIfAppropriateLocked() { 17232 if (canGcNowLocked()) { 17233 performAppGcsLocked(); 17234 return; 17235 } 17236 // Still not idle, wait some more. 17237 scheduleAppGcsLocked(); 17238 } 17239 17240 /** 17241 * Schedule the execution of all pending app GCs. 17242 */ 17243 final void scheduleAppGcsLocked() { 17244 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17245 17246 if (mProcessesToGc.size() > 0) { 17247 // Schedule a GC for the time to the next process. 17248 ProcessRecord proc = mProcessesToGc.get(0); 17249 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17250 17251 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17252 long now = SystemClock.uptimeMillis(); 17253 if (when < (now+GC_TIMEOUT)) { 17254 when = now + GC_TIMEOUT; 17255 } 17256 mHandler.sendMessageAtTime(msg, when); 17257 } 17258 } 17259 17260 /** 17261 * Add a process to the array of processes waiting to be GCed. Keeps the 17262 * list in sorted order by the last GC time. The process can't already be 17263 * on the list. 17264 */ 17265 final void addProcessToGcListLocked(ProcessRecord proc) { 17266 boolean added = false; 17267 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17268 if (mProcessesToGc.get(i).lastRequestedGc < 17269 proc.lastRequestedGc) { 17270 added = true; 17271 mProcessesToGc.add(i+1, proc); 17272 break; 17273 } 17274 } 17275 if (!added) { 17276 mProcessesToGc.add(0, proc); 17277 } 17278 } 17279 17280 /** 17281 * Set up to ask a process to GC itself. This will either do it 17282 * immediately, or put it on the list of processes to gc the next 17283 * time things are idle. 17284 */ 17285 final void scheduleAppGcLocked(ProcessRecord app) { 17286 long now = SystemClock.uptimeMillis(); 17287 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17288 return; 17289 } 17290 if (!mProcessesToGc.contains(app)) { 17291 addProcessToGcListLocked(app); 17292 scheduleAppGcsLocked(); 17293 } 17294 } 17295 17296 final void checkExcessivePowerUsageLocked(boolean doKills) { 17297 updateCpuStatsNow(); 17298 17299 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17300 boolean doWakeKills = doKills; 17301 boolean doCpuKills = doKills; 17302 if (mLastPowerCheckRealtime == 0) { 17303 doWakeKills = false; 17304 } 17305 if (mLastPowerCheckUptime == 0) { 17306 doCpuKills = false; 17307 } 17308 if (stats.isScreenOn()) { 17309 doWakeKills = false; 17310 } 17311 final long curRealtime = SystemClock.elapsedRealtime(); 17312 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17313 final long curUptime = SystemClock.uptimeMillis(); 17314 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17315 mLastPowerCheckRealtime = curRealtime; 17316 mLastPowerCheckUptime = curUptime; 17317 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17318 doWakeKills = false; 17319 } 17320 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17321 doCpuKills = false; 17322 } 17323 int i = mLruProcesses.size(); 17324 while (i > 0) { 17325 i--; 17326 ProcessRecord app = mLruProcesses.get(i); 17327 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17328 long wtime; 17329 synchronized (stats) { 17330 wtime = stats.getProcessWakeTime(app.info.uid, 17331 app.pid, curRealtime); 17332 } 17333 long wtimeUsed = wtime - app.lastWakeTime; 17334 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17335 if (DEBUG_POWER) { 17336 StringBuilder sb = new StringBuilder(128); 17337 sb.append("Wake for "); 17338 app.toShortString(sb); 17339 sb.append(": over "); 17340 TimeUtils.formatDuration(realtimeSince, sb); 17341 sb.append(" used "); 17342 TimeUtils.formatDuration(wtimeUsed, sb); 17343 sb.append(" ("); 17344 sb.append((wtimeUsed*100)/realtimeSince); 17345 sb.append("%)"); 17346 Slog.i(TAG, sb.toString()); 17347 sb.setLength(0); 17348 sb.append("CPU for "); 17349 app.toShortString(sb); 17350 sb.append(": over "); 17351 TimeUtils.formatDuration(uptimeSince, sb); 17352 sb.append(" used "); 17353 TimeUtils.formatDuration(cputimeUsed, sb); 17354 sb.append(" ("); 17355 sb.append((cputimeUsed*100)/uptimeSince); 17356 sb.append("%)"); 17357 Slog.i(TAG, sb.toString()); 17358 } 17359 // If a process has held a wake lock for more 17360 // than 50% of the time during this period, 17361 // that sounds bad. Kill! 17362 if (doWakeKills && realtimeSince > 0 17363 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17364 synchronized (stats) { 17365 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17366 realtimeSince, wtimeUsed); 17367 } 17368 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17369 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17370 } else if (doCpuKills && uptimeSince > 0 17371 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17372 synchronized (stats) { 17373 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17374 uptimeSince, cputimeUsed); 17375 } 17376 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17377 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17378 } else { 17379 app.lastWakeTime = wtime; 17380 app.lastCpuTime = app.curCpuTime; 17381 } 17382 } 17383 } 17384 } 17385 17386 private final boolean applyOomAdjLocked(ProcessRecord app, 17387 ProcessRecord TOP_APP, boolean doingAll, long now) { 17388 boolean success = true; 17389 17390 if (app.curRawAdj != app.setRawAdj) { 17391 app.setRawAdj = app.curRawAdj; 17392 } 17393 17394 int changes = 0; 17395 17396 if (app.curAdj != app.setAdj) { 17397 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17398 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17399 TAG, "Set " + app.pid + " " + app.processName + 17400 " adj " + app.curAdj + ": " + app.adjType); 17401 app.setAdj = app.curAdj; 17402 } 17403 17404 if (app.setSchedGroup != app.curSchedGroup) { 17405 app.setSchedGroup = app.curSchedGroup; 17406 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17407 "Setting process group of " + app.processName 17408 + " to " + app.curSchedGroup); 17409 if (app.waitingToKill != null && 17410 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17411 app.kill(app.waitingToKill, true); 17412 success = false; 17413 } else { 17414 if (true) { 17415 long oldId = Binder.clearCallingIdentity(); 17416 try { 17417 Process.setProcessGroup(app.pid, app.curSchedGroup); 17418 } catch (Exception e) { 17419 Slog.w(TAG, "Failed setting process group of " + app.pid 17420 + " to " + app.curSchedGroup); 17421 e.printStackTrace(); 17422 } finally { 17423 Binder.restoreCallingIdentity(oldId); 17424 } 17425 } else { 17426 if (app.thread != null) { 17427 try { 17428 app.thread.setSchedulingGroup(app.curSchedGroup); 17429 } catch (RemoteException e) { 17430 } 17431 } 17432 } 17433 Process.setSwappiness(app.pid, 17434 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17435 } 17436 } 17437 if (app.repForegroundActivities != app.foregroundActivities) { 17438 app.repForegroundActivities = app.foregroundActivities; 17439 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17440 } 17441 if (app.repProcState != app.curProcState) { 17442 app.repProcState = app.curProcState; 17443 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17444 if (app.thread != null) { 17445 try { 17446 if (false) { 17447 //RuntimeException h = new RuntimeException("here"); 17448 Slog.i(TAG, "Sending new process state " + app.repProcState 17449 + " to " + app /*, h*/); 17450 } 17451 app.thread.setProcessState(app.repProcState); 17452 } catch (RemoteException e) { 17453 } 17454 } 17455 } 17456 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17457 app.setProcState)) { 17458 app.lastStateTime = now; 17459 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17460 isSleeping(), now); 17461 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17462 + ProcessList.makeProcStateString(app.setProcState) + " to " 17463 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17464 + (app.nextPssTime-now) + ": " + app); 17465 } else { 17466 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17467 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17468 requestPssLocked(app, app.setProcState); 17469 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17470 isSleeping(), now); 17471 } else if (false && DEBUG_PSS) { 17472 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17473 } 17474 } 17475 if (app.setProcState != app.curProcState) { 17476 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17477 "Proc state change of " + app.processName 17478 + " to " + app.curProcState); 17479 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17480 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17481 if (setImportant && !curImportant) { 17482 // This app is no longer something we consider important enough to allow to 17483 // use arbitrary amounts of battery power. Note 17484 // its current wake lock time to later know to kill it if 17485 // it is not behaving well. 17486 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17487 synchronized (stats) { 17488 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17489 app.pid, SystemClock.elapsedRealtime()); 17490 } 17491 app.lastCpuTime = app.curCpuTime; 17492 17493 } 17494 app.setProcState = app.curProcState; 17495 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17496 app.notCachedSinceIdle = false; 17497 } 17498 if (!doingAll) { 17499 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17500 } else { 17501 app.procStateChanged = true; 17502 } 17503 } 17504 17505 if (changes != 0) { 17506 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17507 int i = mPendingProcessChanges.size()-1; 17508 ProcessChangeItem item = null; 17509 while (i >= 0) { 17510 item = mPendingProcessChanges.get(i); 17511 if (item.pid == app.pid) { 17512 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17513 break; 17514 } 17515 i--; 17516 } 17517 if (i < 0) { 17518 // No existing item in pending changes; need a new one. 17519 final int NA = mAvailProcessChanges.size(); 17520 if (NA > 0) { 17521 item = mAvailProcessChanges.remove(NA-1); 17522 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17523 } else { 17524 item = new ProcessChangeItem(); 17525 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17526 } 17527 item.changes = 0; 17528 item.pid = app.pid; 17529 item.uid = app.info.uid; 17530 if (mPendingProcessChanges.size() == 0) { 17531 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17532 "*** Enqueueing dispatch processes changed!"); 17533 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17534 } 17535 mPendingProcessChanges.add(item); 17536 } 17537 item.changes |= changes; 17538 item.processState = app.repProcState; 17539 item.foregroundActivities = app.repForegroundActivities; 17540 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17541 + Integer.toHexString(System.identityHashCode(item)) 17542 + " " + app.toShortString() + ": changes=" + item.changes 17543 + " procState=" + item.processState 17544 + " foreground=" + item.foregroundActivities 17545 + " type=" + app.adjType + " source=" + app.adjSource 17546 + " target=" + app.adjTarget); 17547 } 17548 17549 return success; 17550 } 17551 17552 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17553 if (proc.thread != null) { 17554 if (proc.baseProcessTracker != null) { 17555 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17556 } 17557 if (proc.repProcState >= 0) { 17558 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17559 proc.repProcState); 17560 } 17561 } 17562 } 17563 17564 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17565 ProcessRecord TOP_APP, boolean doingAll, long now) { 17566 if (app.thread == null) { 17567 return false; 17568 } 17569 17570 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17571 17572 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17573 } 17574 17575 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17576 boolean oomAdj) { 17577 if (isForeground != proc.foregroundServices) { 17578 proc.foregroundServices = isForeground; 17579 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17580 proc.info.uid); 17581 if (isForeground) { 17582 if (curProcs == null) { 17583 curProcs = new ArrayList<ProcessRecord>(); 17584 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17585 } 17586 if (!curProcs.contains(proc)) { 17587 curProcs.add(proc); 17588 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17589 proc.info.packageName, proc.info.uid); 17590 } 17591 } else { 17592 if (curProcs != null) { 17593 if (curProcs.remove(proc)) { 17594 mBatteryStatsService.noteEvent( 17595 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17596 proc.info.packageName, proc.info.uid); 17597 if (curProcs.size() <= 0) { 17598 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17599 } 17600 } 17601 } 17602 } 17603 if (oomAdj) { 17604 updateOomAdjLocked(); 17605 } 17606 } 17607 } 17608 17609 private final ActivityRecord resumedAppLocked() { 17610 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17611 String pkg; 17612 int uid; 17613 if (act != null) { 17614 pkg = act.packageName; 17615 uid = act.info.applicationInfo.uid; 17616 } else { 17617 pkg = null; 17618 uid = -1; 17619 } 17620 // Has the UID or resumed package name changed? 17621 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17622 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17623 if (mCurResumedPackage != null) { 17624 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17625 mCurResumedPackage, mCurResumedUid); 17626 } 17627 mCurResumedPackage = pkg; 17628 mCurResumedUid = uid; 17629 if (mCurResumedPackage != null) { 17630 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17631 mCurResumedPackage, mCurResumedUid); 17632 } 17633 } 17634 return act; 17635 } 17636 17637 final boolean updateOomAdjLocked(ProcessRecord app) { 17638 final ActivityRecord TOP_ACT = resumedAppLocked(); 17639 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17640 final boolean wasCached = app.cached; 17641 17642 mAdjSeq++; 17643 17644 // This is the desired cached adjusment we want to tell it to use. 17645 // If our app is currently cached, we know it, and that is it. Otherwise, 17646 // we don't know it yet, and it needs to now be cached we will then 17647 // need to do a complete oom adj. 17648 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17649 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17650 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17651 SystemClock.uptimeMillis()); 17652 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17653 // Changed to/from cached state, so apps after it in the LRU 17654 // list may also be changed. 17655 updateOomAdjLocked(); 17656 } 17657 return success; 17658 } 17659 17660 final void updateOomAdjLocked() { 17661 final ActivityRecord TOP_ACT = resumedAppLocked(); 17662 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17663 final long now = SystemClock.uptimeMillis(); 17664 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17665 final int N = mLruProcesses.size(); 17666 17667 if (false) { 17668 RuntimeException e = new RuntimeException(); 17669 e.fillInStackTrace(); 17670 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17671 } 17672 17673 mAdjSeq++; 17674 mNewNumServiceProcs = 0; 17675 mNewNumAServiceProcs = 0; 17676 17677 final int emptyProcessLimit; 17678 final int cachedProcessLimit; 17679 if (mProcessLimit <= 0) { 17680 emptyProcessLimit = cachedProcessLimit = 0; 17681 } else if (mProcessLimit == 1) { 17682 emptyProcessLimit = 1; 17683 cachedProcessLimit = 0; 17684 } else { 17685 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17686 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17687 } 17688 17689 // Let's determine how many processes we have running vs. 17690 // how many slots we have for background processes; we may want 17691 // to put multiple processes in a slot of there are enough of 17692 // them. 17693 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17694 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17695 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17696 if (numEmptyProcs > cachedProcessLimit) { 17697 // If there are more empty processes than our limit on cached 17698 // processes, then use the cached process limit for the factor. 17699 // This ensures that the really old empty processes get pushed 17700 // down to the bottom, so if we are running low on memory we will 17701 // have a better chance at keeping around more cached processes 17702 // instead of a gazillion empty processes. 17703 numEmptyProcs = cachedProcessLimit; 17704 } 17705 int emptyFactor = numEmptyProcs/numSlots; 17706 if (emptyFactor < 1) emptyFactor = 1; 17707 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17708 if (cachedFactor < 1) cachedFactor = 1; 17709 int stepCached = 0; 17710 int stepEmpty = 0; 17711 int numCached = 0; 17712 int numEmpty = 0; 17713 int numTrimming = 0; 17714 17715 mNumNonCachedProcs = 0; 17716 mNumCachedHiddenProcs = 0; 17717 17718 // First update the OOM adjustment for each of the 17719 // application processes based on their current state. 17720 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17721 int nextCachedAdj = curCachedAdj+1; 17722 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17723 int nextEmptyAdj = curEmptyAdj+2; 17724 for (int i=N-1; i>=0; i--) { 17725 ProcessRecord app = mLruProcesses.get(i); 17726 if (!app.killedByAm && app.thread != null) { 17727 app.procStateChanged = false; 17728 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17729 17730 // If we haven't yet assigned the final cached adj 17731 // to the process, do that now. 17732 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17733 switch (app.curProcState) { 17734 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17735 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17736 // This process is a cached process holding activities... 17737 // assign it the next cached value for that type, and then 17738 // step that cached level. 17739 app.curRawAdj = curCachedAdj; 17740 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17741 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17742 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17743 + ")"); 17744 if (curCachedAdj != nextCachedAdj) { 17745 stepCached++; 17746 if (stepCached >= cachedFactor) { 17747 stepCached = 0; 17748 curCachedAdj = nextCachedAdj; 17749 nextCachedAdj += 2; 17750 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17751 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17752 } 17753 } 17754 } 17755 break; 17756 default: 17757 // For everything else, assign next empty cached process 17758 // level and bump that up. Note that this means that 17759 // long-running services that have dropped down to the 17760 // cached level will be treated as empty (since their process 17761 // state is still as a service), which is what we want. 17762 app.curRawAdj = curEmptyAdj; 17763 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17764 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17765 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17766 + ")"); 17767 if (curEmptyAdj != nextEmptyAdj) { 17768 stepEmpty++; 17769 if (stepEmpty >= emptyFactor) { 17770 stepEmpty = 0; 17771 curEmptyAdj = nextEmptyAdj; 17772 nextEmptyAdj += 2; 17773 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17774 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17775 } 17776 } 17777 } 17778 break; 17779 } 17780 } 17781 17782 applyOomAdjLocked(app, TOP_APP, true, now); 17783 17784 // Count the number of process types. 17785 switch (app.curProcState) { 17786 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17787 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17788 mNumCachedHiddenProcs++; 17789 numCached++; 17790 if (numCached > cachedProcessLimit) { 17791 app.kill("cached #" + numCached, true); 17792 } 17793 break; 17794 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17795 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17796 && app.lastActivityTime < oldTime) { 17797 app.kill("empty for " 17798 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17799 / 1000) + "s", true); 17800 } else { 17801 numEmpty++; 17802 if (numEmpty > emptyProcessLimit) { 17803 app.kill("empty #" + numEmpty, true); 17804 } 17805 } 17806 break; 17807 default: 17808 mNumNonCachedProcs++; 17809 break; 17810 } 17811 17812 if (app.isolated && app.services.size() <= 0) { 17813 // If this is an isolated process, and there are no 17814 // services running in it, then the process is no longer 17815 // needed. We agressively kill these because we can by 17816 // definition not re-use the same process again, and it is 17817 // good to avoid having whatever code was running in them 17818 // left sitting around after no longer needed. 17819 app.kill("isolated not needed", true); 17820 } 17821 17822 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17823 && !app.killedByAm) { 17824 numTrimming++; 17825 } 17826 } 17827 } 17828 17829 mNumServiceProcs = mNewNumServiceProcs; 17830 17831 // Now determine the memory trimming level of background processes. 17832 // Unfortunately we need to start at the back of the list to do this 17833 // properly. We only do this if the number of background apps we 17834 // are managing to keep around is less than half the maximum we desire; 17835 // if we are keeping a good number around, we'll let them use whatever 17836 // memory they want. 17837 final int numCachedAndEmpty = numCached + numEmpty; 17838 int memFactor; 17839 if (numCached <= ProcessList.TRIM_CACHED_APPS 17840 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17841 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17842 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17843 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17844 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17845 } else { 17846 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17847 } 17848 } else { 17849 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17850 } 17851 // We always allow the memory level to go up (better). We only allow it to go 17852 // down if we are in a state where that is allowed, *and* the total number of processes 17853 // has gone down since last time. 17854 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17855 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17856 + " last=" + mLastNumProcesses); 17857 if (memFactor > mLastMemoryLevel) { 17858 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17859 memFactor = mLastMemoryLevel; 17860 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17861 } 17862 } 17863 mLastMemoryLevel = memFactor; 17864 mLastNumProcesses = mLruProcesses.size(); 17865 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17866 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17867 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17868 if (mLowRamStartTime == 0) { 17869 mLowRamStartTime = now; 17870 } 17871 int step = 0; 17872 int fgTrimLevel; 17873 switch (memFactor) { 17874 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17875 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17876 break; 17877 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17878 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17879 break; 17880 default: 17881 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17882 break; 17883 } 17884 int factor = numTrimming/3; 17885 int minFactor = 2; 17886 if (mHomeProcess != null) minFactor++; 17887 if (mPreviousProcess != null) minFactor++; 17888 if (factor < minFactor) factor = minFactor; 17889 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17890 for (int i=N-1; i>=0; i--) { 17891 ProcessRecord app = mLruProcesses.get(i); 17892 if (allChanged || app.procStateChanged) { 17893 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17894 app.procStateChanged = false; 17895 } 17896 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17897 && !app.killedByAm) { 17898 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17899 try { 17900 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17901 "Trimming memory of " + app.processName 17902 + " to " + curLevel); 17903 app.thread.scheduleTrimMemory(curLevel); 17904 } catch (RemoteException e) { 17905 } 17906 if (false) { 17907 // For now we won't do this; our memory trimming seems 17908 // to be good enough at this point that destroying 17909 // activities causes more harm than good. 17910 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17911 && app != mHomeProcess && app != mPreviousProcess) { 17912 // Need to do this on its own message because the stack may not 17913 // be in a consistent state at this point. 17914 // For these apps we will also finish their activities 17915 // to help them free memory. 17916 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17917 } 17918 } 17919 } 17920 app.trimMemoryLevel = curLevel; 17921 step++; 17922 if (step >= factor) { 17923 step = 0; 17924 switch (curLevel) { 17925 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17926 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17927 break; 17928 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17929 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17930 break; 17931 } 17932 } 17933 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17934 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17935 && app.thread != null) { 17936 try { 17937 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17938 "Trimming memory of heavy-weight " + app.processName 17939 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17940 app.thread.scheduleTrimMemory( 17941 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17942 } catch (RemoteException e) { 17943 } 17944 } 17945 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17946 } else { 17947 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17948 || app.systemNoUi) && app.pendingUiClean) { 17949 // If this application is now in the background and it 17950 // had done UI, then give it the special trim level to 17951 // have it free UI resources. 17952 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17953 if (app.trimMemoryLevel < level && app.thread != null) { 17954 try { 17955 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17956 "Trimming memory of bg-ui " + app.processName 17957 + " to " + level); 17958 app.thread.scheduleTrimMemory(level); 17959 } catch (RemoteException e) { 17960 } 17961 } 17962 app.pendingUiClean = false; 17963 } 17964 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17965 try { 17966 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17967 "Trimming memory of fg " + app.processName 17968 + " to " + fgTrimLevel); 17969 app.thread.scheduleTrimMemory(fgTrimLevel); 17970 } catch (RemoteException e) { 17971 } 17972 } 17973 app.trimMemoryLevel = fgTrimLevel; 17974 } 17975 } 17976 } else { 17977 if (mLowRamStartTime != 0) { 17978 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17979 mLowRamStartTime = 0; 17980 } 17981 for (int i=N-1; i>=0; i--) { 17982 ProcessRecord app = mLruProcesses.get(i); 17983 if (allChanged || app.procStateChanged) { 17984 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17985 app.procStateChanged = false; 17986 } 17987 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17988 || app.systemNoUi) && app.pendingUiClean) { 17989 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17990 && app.thread != null) { 17991 try { 17992 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17993 "Trimming memory of ui hidden " + app.processName 17994 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17995 app.thread.scheduleTrimMemory( 17996 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17997 } catch (RemoteException e) { 17998 } 17999 } 18000 app.pendingUiClean = false; 18001 } 18002 app.trimMemoryLevel = 0; 18003 } 18004 } 18005 18006 if (mAlwaysFinishActivities) { 18007 // Need to do this on its own message because the stack may not 18008 // be in a consistent state at this point. 18009 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18010 } 18011 18012 if (allChanged) { 18013 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18014 } 18015 18016 if (mProcessStats.shouldWriteNowLocked(now)) { 18017 mHandler.post(new Runnable() { 18018 @Override public void run() { 18019 synchronized (ActivityManagerService.this) { 18020 mProcessStats.writeStateAsyncLocked(); 18021 } 18022 } 18023 }); 18024 } 18025 18026 if (DEBUG_OOM_ADJ) { 18027 if (false) { 18028 RuntimeException here = new RuntimeException("here"); 18029 here.fillInStackTrace(); 18030 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18031 } else { 18032 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18033 } 18034 } 18035 } 18036 18037 final void trimApplications() { 18038 synchronized (this) { 18039 int i; 18040 18041 // First remove any unused application processes whose package 18042 // has been removed. 18043 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18044 final ProcessRecord app = mRemovedProcesses.get(i); 18045 if (app.activities.size() == 0 18046 && app.curReceiver == null && app.services.size() == 0) { 18047 Slog.i( 18048 TAG, "Exiting empty application process " 18049 + app.processName + " (" 18050 + (app.thread != null ? app.thread.asBinder() : null) 18051 + ")\n"); 18052 if (app.pid > 0 && app.pid != MY_PID) { 18053 app.kill("empty", false); 18054 } else { 18055 try { 18056 app.thread.scheduleExit(); 18057 } catch (Exception e) { 18058 // Ignore exceptions. 18059 } 18060 } 18061 cleanUpApplicationRecordLocked(app, false, true, -1); 18062 mRemovedProcesses.remove(i); 18063 18064 if (app.persistent) { 18065 addAppLocked(app.info, false, null /* ABI override */); 18066 } 18067 } 18068 } 18069 18070 // Now update the oom adj for all processes. 18071 updateOomAdjLocked(); 18072 } 18073 } 18074 18075 /** This method sends the specified signal to each of the persistent apps */ 18076 public void signalPersistentProcesses(int sig) throws RemoteException { 18077 if (sig != Process.SIGNAL_USR1) { 18078 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18079 } 18080 18081 synchronized (this) { 18082 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18083 != PackageManager.PERMISSION_GRANTED) { 18084 throw new SecurityException("Requires permission " 18085 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18086 } 18087 18088 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18089 ProcessRecord r = mLruProcesses.get(i); 18090 if (r.thread != null && r.persistent) { 18091 Process.sendSignal(r.pid, sig); 18092 } 18093 } 18094 } 18095 } 18096 18097 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18098 if (proc == null || proc == mProfileProc) { 18099 proc = mProfileProc; 18100 profileType = mProfileType; 18101 clearProfilerLocked(); 18102 } 18103 if (proc == null) { 18104 return; 18105 } 18106 try { 18107 proc.thread.profilerControl(false, null, profileType); 18108 } catch (RemoteException e) { 18109 throw new IllegalStateException("Process disappeared"); 18110 } 18111 } 18112 18113 private void clearProfilerLocked() { 18114 if (mProfileFd != null) { 18115 try { 18116 mProfileFd.close(); 18117 } catch (IOException e) { 18118 } 18119 } 18120 mProfileApp = null; 18121 mProfileProc = null; 18122 mProfileFile = null; 18123 mProfileType = 0; 18124 mAutoStopProfiler = false; 18125 mSamplingInterval = 0; 18126 } 18127 18128 public boolean profileControl(String process, int userId, boolean start, 18129 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18130 18131 try { 18132 synchronized (this) { 18133 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18134 // its own permission. 18135 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18136 != PackageManager.PERMISSION_GRANTED) { 18137 throw new SecurityException("Requires permission " 18138 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18139 } 18140 18141 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18142 throw new IllegalArgumentException("null profile info or fd"); 18143 } 18144 18145 ProcessRecord proc = null; 18146 if (process != null) { 18147 proc = findProcessLocked(process, userId, "profileControl"); 18148 } 18149 18150 if (start && (proc == null || proc.thread == null)) { 18151 throw new IllegalArgumentException("Unknown process: " + process); 18152 } 18153 18154 if (start) { 18155 stopProfilerLocked(null, 0); 18156 setProfileApp(proc.info, proc.processName, profilerInfo); 18157 mProfileProc = proc; 18158 mProfileType = profileType; 18159 ParcelFileDescriptor fd = profilerInfo.profileFd; 18160 try { 18161 fd = fd.dup(); 18162 } catch (IOException e) { 18163 fd = null; 18164 } 18165 profilerInfo.profileFd = fd; 18166 proc.thread.profilerControl(start, profilerInfo, profileType); 18167 fd = null; 18168 mProfileFd = null; 18169 } else { 18170 stopProfilerLocked(proc, profileType); 18171 if (profilerInfo != null && profilerInfo.profileFd != null) { 18172 try { 18173 profilerInfo.profileFd.close(); 18174 } catch (IOException e) { 18175 } 18176 } 18177 } 18178 18179 return true; 18180 } 18181 } catch (RemoteException e) { 18182 throw new IllegalStateException("Process disappeared"); 18183 } finally { 18184 if (profilerInfo != null && profilerInfo.profileFd != null) { 18185 try { 18186 profilerInfo.profileFd.close(); 18187 } catch (IOException e) { 18188 } 18189 } 18190 } 18191 } 18192 18193 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18194 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18195 userId, true, ALLOW_FULL_ONLY, callName, null); 18196 ProcessRecord proc = null; 18197 try { 18198 int pid = Integer.parseInt(process); 18199 synchronized (mPidsSelfLocked) { 18200 proc = mPidsSelfLocked.get(pid); 18201 } 18202 } catch (NumberFormatException e) { 18203 } 18204 18205 if (proc == null) { 18206 ArrayMap<String, SparseArray<ProcessRecord>> all 18207 = mProcessNames.getMap(); 18208 SparseArray<ProcessRecord> procs = all.get(process); 18209 if (procs != null && procs.size() > 0) { 18210 proc = procs.valueAt(0); 18211 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18212 for (int i=1; i<procs.size(); i++) { 18213 ProcessRecord thisProc = procs.valueAt(i); 18214 if (thisProc.userId == userId) { 18215 proc = thisProc; 18216 break; 18217 } 18218 } 18219 } 18220 } 18221 } 18222 18223 return proc; 18224 } 18225 18226 public boolean dumpHeap(String process, int userId, boolean managed, 18227 String path, ParcelFileDescriptor fd) throws RemoteException { 18228 18229 try { 18230 synchronized (this) { 18231 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18232 // its own permission (same as profileControl). 18233 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18234 != PackageManager.PERMISSION_GRANTED) { 18235 throw new SecurityException("Requires permission " 18236 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18237 } 18238 18239 if (fd == null) { 18240 throw new IllegalArgumentException("null fd"); 18241 } 18242 18243 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18244 if (proc == null || proc.thread == null) { 18245 throw new IllegalArgumentException("Unknown process: " + process); 18246 } 18247 18248 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18249 if (!isDebuggable) { 18250 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18251 throw new SecurityException("Process not debuggable: " + proc); 18252 } 18253 } 18254 18255 proc.thread.dumpHeap(managed, path, fd); 18256 fd = null; 18257 return true; 18258 } 18259 } catch (RemoteException e) { 18260 throw new IllegalStateException("Process disappeared"); 18261 } finally { 18262 if (fd != null) { 18263 try { 18264 fd.close(); 18265 } catch (IOException e) { 18266 } 18267 } 18268 } 18269 } 18270 18271 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18272 public void monitor() { 18273 synchronized (this) { } 18274 } 18275 18276 void onCoreSettingsChange(Bundle settings) { 18277 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18278 ProcessRecord processRecord = mLruProcesses.get(i); 18279 try { 18280 if (processRecord.thread != null) { 18281 processRecord.thread.setCoreSettings(settings); 18282 } 18283 } catch (RemoteException re) { 18284 /* ignore */ 18285 } 18286 } 18287 } 18288 18289 // Multi-user methods 18290 18291 /** 18292 * Start user, if its not already running, but don't bring it to foreground. 18293 */ 18294 @Override 18295 public boolean startUserInBackground(final int userId) { 18296 return startUser(userId, /* foreground */ false); 18297 } 18298 18299 /** 18300 * Start user, if its not already running, and bring it to foreground. 18301 */ 18302 boolean startUserInForeground(final int userId, Dialog dlg) { 18303 boolean result = startUser(userId, /* foreground */ true); 18304 dlg.dismiss(); 18305 return result; 18306 } 18307 18308 /** 18309 * Refreshes the list of users related to the current user when either a 18310 * user switch happens or when a new related user is started in the 18311 * background. 18312 */ 18313 private void updateCurrentProfileIdsLocked() { 18314 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18315 mCurrentUserId, false /* enabledOnly */); 18316 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18317 for (int i = 0; i < currentProfileIds.length; i++) { 18318 currentProfileIds[i] = profiles.get(i).id; 18319 } 18320 mCurrentProfileIds = currentProfileIds; 18321 18322 synchronized (mUserProfileGroupIdsSelfLocked) { 18323 mUserProfileGroupIdsSelfLocked.clear(); 18324 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18325 for (int i = 0; i < users.size(); i++) { 18326 UserInfo user = users.get(i); 18327 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18328 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18329 } 18330 } 18331 } 18332 } 18333 18334 private Set getProfileIdsLocked(int userId) { 18335 Set userIds = new HashSet<Integer>(); 18336 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18337 userId, false /* enabledOnly */); 18338 for (UserInfo user : profiles) { 18339 userIds.add(Integer.valueOf(user.id)); 18340 } 18341 return userIds; 18342 } 18343 18344 @Override 18345 public boolean switchUser(final int userId) { 18346 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18347 String userName; 18348 synchronized (this) { 18349 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18350 if (userInfo == null) { 18351 Slog.w(TAG, "No user info for user #" + userId); 18352 return false; 18353 } 18354 if (userInfo.isManagedProfile()) { 18355 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18356 return false; 18357 } 18358 userName = userInfo.name; 18359 mTargetUserId = userId; 18360 } 18361 mHandler.removeMessages(START_USER_SWITCH_MSG); 18362 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18363 return true; 18364 } 18365 18366 private void showUserSwitchDialog(int userId, String userName) { 18367 // The dialog will show and then initiate the user switch by calling startUserInForeground 18368 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18369 true /* above system */); 18370 d.show(); 18371 } 18372 18373 private boolean startUser(final int userId, final boolean foreground) { 18374 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18375 != PackageManager.PERMISSION_GRANTED) { 18376 String msg = "Permission Denial: switchUser() from pid=" 18377 + Binder.getCallingPid() 18378 + ", uid=" + Binder.getCallingUid() 18379 + " requires " + INTERACT_ACROSS_USERS_FULL; 18380 Slog.w(TAG, msg); 18381 throw new SecurityException(msg); 18382 } 18383 18384 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18385 18386 final long ident = Binder.clearCallingIdentity(); 18387 try { 18388 synchronized (this) { 18389 final int oldUserId = mCurrentUserId; 18390 if (oldUserId == userId) { 18391 return true; 18392 } 18393 18394 mStackSupervisor.setLockTaskModeLocked(null, false); 18395 18396 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18397 if (userInfo == null) { 18398 Slog.w(TAG, "No user info for user #" + userId); 18399 return false; 18400 } 18401 if (foreground && userInfo.isManagedProfile()) { 18402 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18403 return false; 18404 } 18405 18406 if (foreground) { 18407 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18408 R.anim.screen_user_enter); 18409 } 18410 18411 boolean needStart = false; 18412 18413 // If the user we are switching to is not currently started, then 18414 // we need to start it now. 18415 if (mStartedUsers.get(userId) == null) { 18416 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18417 updateStartedUserArrayLocked(); 18418 needStart = true; 18419 } 18420 18421 final Integer userIdInt = Integer.valueOf(userId); 18422 mUserLru.remove(userIdInt); 18423 mUserLru.add(userIdInt); 18424 18425 if (foreground) { 18426 mCurrentUserId = userId; 18427 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18428 updateCurrentProfileIdsLocked(); 18429 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18430 // Once the internal notion of the active user has switched, we lock the device 18431 // with the option to show the user switcher on the keyguard. 18432 mWindowManager.lockNow(null); 18433 } else { 18434 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18435 updateCurrentProfileIdsLocked(); 18436 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18437 mUserLru.remove(currentUserIdInt); 18438 mUserLru.add(currentUserIdInt); 18439 } 18440 18441 final UserStartedState uss = mStartedUsers.get(userId); 18442 18443 // Make sure user is in the started state. If it is currently 18444 // stopping, we need to knock that off. 18445 if (uss.mState == UserStartedState.STATE_STOPPING) { 18446 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18447 // so we can just fairly silently bring the user back from 18448 // the almost-dead. 18449 uss.mState = UserStartedState.STATE_RUNNING; 18450 updateStartedUserArrayLocked(); 18451 needStart = true; 18452 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18453 // This means ACTION_SHUTDOWN has been sent, so we will 18454 // need to treat this as a new boot of the user. 18455 uss.mState = UserStartedState.STATE_BOOTING; 18456 updateStartedUserArrayLocked(); 18457 needStart = true; 18458 } 18459 18460 if (uss.mState == UserStartedState.STATE_BOOTING) { 18461 // Booting up a new user, need to tell system services about it. 18462 // Note that this is on the same handler as scheduling of broadcasts, 18463 // which is important because it needs to go first. 18464 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18465 } 18466 18467 if (foreground) { 18468 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18469 oldUserId)); 18470 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18471 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18472 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18473 oldUserId, userId, uss)); 18474 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18475 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18476 } 18477 18478 if (needStart) { 18479 // Send USER_STARTED broadcast 18480 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18481 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18482 | Intent.FLAG_RECEIVER_FOREGROUND); 18483 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18484 broadcastIntentLocked(null, null, intent, 18485 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18486 false, false, MY_PID, Process.SYSTEM_UID, userId); 18487 } 18488 18489 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18490 if (userId != UserHandle.USER_OWNER) { 18491 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18492 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18493 broadcastIntentLocked(null, null, intent, null, 18494 new IIntentReceiver.Stub() { 18495 public void performReceive(Intent intent, int resultCode, 18496 String data, Bundle extras, boolean ordered, 18497 boolean sticky, int sendingUser) { 18498 onUserInitialized(uss, foreground, oldUserId, userId); 18499 } 18500 }, 0, null, null, null, AppOpsManager.OP_NONE, 18501 true, false, MY_PID, Process.SYSTEM_UID, 18502 userId); 18503 uss.initializing = true; 18504 } else { 18505 getUserManagerLocked().makeInitialized(userInfo.id); 18506 } 18507 } 18508 18509 if (foreground) { 18510 if (!uss.initializing) { 18511 moveUserToForeground(uss, oldUserId, userId); 18512 } 18513 } else { 18514 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18515 } 18516 18517 if (needStart) { 18518 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18520 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18521 broadcastIntentLocked(null, null, intent, 18522 null, new IIntentReceiver.Stub() { 18523 @Override 18524 public void performReceive(Intent intent, int resultCode, String data, 18525 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18526 throws RemoteException { 18527 } 18528 }, 0, null, null, 18529 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18530 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18531 } 18532 } 18533 } finally { 18534 Binder.restoreCallingIdentity(ident); 18535 } 18536 18537 return true; 18538 } 18539 18540 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18541 long ident = Binder.clearCallingIdentity(); 18542 try { 18543 Intent intent; 18544 if (oldUserId >= 0) { 18545 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18546 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18547 int count = profiles.size(); 18548 for (int i = 0; i < count; i++) { 18549 int profileUserId = profiles.get(i).id; 18550 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18551 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18552 | Intent.FLAG_RECEIVER_FOREGROUND); 18553 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18554 broadcastIntentLocked(null, null, intent, 18555 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18556 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18557 } 18558 } 18559 if (newUserId >= 0) { 18560 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18561 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18562 int count = profiles.size(); 18563 for (int i = 0; i < count; i++) { 18564 int profileUserId = profiles.get(i).id; 18565 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18566 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18567 | Intent.FLAG_RECEIVER_FOREGROUND); 18568 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18569 broadcastIntentLocked(null, null, intent, 18570 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18571 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18572 } 18573 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18574 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18575 | Intent.FLAG_RECEIVER_FOREGROUND); 18576 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18577 broadcastIntentLocked(null, null, intent, 18578 null, null, 0, null, null, 18579 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18580 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18581 } 18582 } finally { 18583 Binder.restoreCallingIdentity(ident); 18584 } 18585 } 18586 18587 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18588 final int newUserId) { 18589 final int N = mUserSwitchObservers.beginBroadcast(); 18590 if (N > 0) { 18591 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18592 int mCount = 0; 18593 @Override 18594 public void sendResult(Bundle data) throws RemoteException { 18595 synchronized (ActivityManagerService.this) { 18596 if (mCurUserSwitchCallback == this) { 18597 mCount++; 18598 if (mCount == N) { 18599 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18600 } 18601 } 18602 } 18603 } 18604 }; 18605 synchronized (this) { 18606 uss.switching = true; 18607 mCurUserSwitchCallback = callback; 18608 } 18609 for (int i=0; i<N; i++) { 18610 try { 18611 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18612 newUserId, callback); 18613 } catch (RemoteException e) { 18614 } 18615 } 18616 } else { 18617 synchronized (this) { 18618 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18619 } 18620 } 18621 mUserSwitchObservers.finishBroadcast(); 18622 } 18623 18624 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18625 synchronized (this) { 18626 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18627 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18628 } 18629 } 18630 18631 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18632 mCurUserSwitchCallback = null; 18633 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18634 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18635 oldUserId, newUserId, uss)); 18636 } 18637 18638 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18639 synchronized (this) { 18640 if (foreground) { 18641 moveUserToForeground(uss, oldUserId, newUserId); 18642 } 18643 } 18644 18645 completeSwitchAndInitalize(uss, newUserId, true, false); 18646 } 18647 18648 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18649 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18650 if (homeInFront) { 18651 startHomeActivityLocked(newUserId); 18652 } else { 18653 mStackSupervisor.resumeTopActivitiesLocked(); 18654 } 18655 EventLogTags.writeAmSwitchUser(newUserId); 18656 getUserManagerLocked().userForeground(newUserId); 18657 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18658 } 18659 18660 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18661 completeSwitchAndInitalize(uss, newUserId, false, true); 18662 } 18663 18664 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18665 boolean clearInitializing, boolean clearSwitching) { 18666 boolean unfrozen = false; 18667 synchronized (this) { 18668 if (clearInitializing) { 18669 uss.initializing = false; 18670 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18671 } 18672 if (clearSwitching) { 18673 uss.switching = false; 18674 } 18675 if (!uss.switching && !uss.initializing) { 18676 mWindowManager.stopFreezingScreen(); 18677 unfrozen = true; 18678 } 18679 } 18680 if (unfrozen) { 18681 final int N = mUserSwitchObservers.beginBroadcast(); 18682 for (int i=0; i<N; i++) { 18683 try { 18684 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18685 } catch (RemoteException e) { 18686 } 18687 } 18688 mUserSwitchObservers.finishBroadcast(); 18689 } 18690 } 18691 18692 void scheduleStartProfilesLocked() { 18693 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18694 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18695 DateUtils.SECOND_IN_MILLIS); 18696 } 18697 } 18698 18699 void startProfilesLocked() { 18700 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18701 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18702 mCurrentUserId, false /* enabledOnly */); 18703 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18704 for (UserInfo user : profiles) { 18705 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18706 && user.id != mCurrentUserId) { 18707 toStart.add(user); 18708 } 18709 } 18710 final int n = toStart.size(); 18711 int i = 0; 18712 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18713 startUserInBackground(toStart.get(i).id); 18714 } 18715 if (i < n) { 18716 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18717 } 18718 } 18719 18720 void finishUserBoot(UserStartedState uss) { 18721 synchronized (this) { 18722 if (uss.mState == UserStartedState.STATE_BOOTING 18723 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18724 uss.mState = UserStartedState.STATE_RUNNING; 18725 final int userId = uss.mHandle.getIdentifier(); 18726 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18727 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18728 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18729 broadcastIntentLocked(null, null, intent, 18730 null, null, 0, null, null, 18731 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18732 true, false, MY_PID, Process.SYSTEM_UID, userId); 18733 } 18734 } 18735 } 18736 18737 void finishUserSwitch(UserStartedState uss) { 18738 synchronized (this) { 18739 finishUserBoot(uss); 18740 18741 startProfilesLocked(); 18742 18743 int num = mUserLru.size(); 18744 int i = 0; 18745 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18746 Integer oldUserId = mUserLru.get(i); 18747 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18748 if (oldUss == null) { 18749 // Shouldn't happen, but be sane if it does. 18750 mUserLru.remove(i); 18751 num--; 18752 continue; 18753 } 18754 if (oldUss.mState == UserStartedState.STATE_STOPPING 18755 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18756 // This user is already stopping, doesn't count. 18757 num--; 18758 i++; 18759 continue; 18760 } 18761 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18762 // Owner and current can't be stopped, but count as running. 18763 i++; 18764 continue; 18765 } 18766 // This is a user to be stopped. 18767 stopUserLocked(oldUserId, null); 18768 num--; 18769 i++; 18770 } 18771 } 18772 } 18773 18774 @Override 18775 public int stopUser(final int userId, final IStopUserCallback callback) { 18776 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18777 != PackageManager.PERMISSION_GRANTED) { 18778 String msg = "Permission Denial: switchUser() from pid=" 18779 + Binder.getCallingPid() 18780 + ", uid=" + Binder.getCallingUid() 18781 + " requires " + INTERACT_ACROSS_USERS_FULL; 18782 Slog.w(TAG, msg); 18783 throw new SecurityException(msg); 18784 } 18785 if (userId <= 0) { 18786 throw new IllegalArgumentException("Can't stop primary user " + userId); 18787 } 18788 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18789 synchronized (this) { 18790 return stopUserLocked(userId, callback); 18791 } 18792 } 18793 18794 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18795 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18796 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18797 return ActivityManager.USER_OP_IS_CURRENT; 18798 } 18799 18800 final UserStartedState uss = mStartedUsers.get(userId); 18801 if (uss == null) { 18802 // User is not started, nothing to do... but we do need to 18803 // callback if requested. 18804 if (callback != null) { 18805 mHandler.post(new Runnable() { 18806 @Override 18807 public void run() { 18808 try { 18809 callback.userStopped(userId); 18810 } catch (RemoteException e) { 18811 } 18812 } 18813 }); 18814 } 18815 return ActivityManager.USER_OP_SUCCESS; 18816 } 18817 18818 if (callback != null) { 18819 uss.mStopCallbacks.add(callback); 18820 } 18821 18822 if (uss.mState != UserStartedState.STATE_STOPPING 18823 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18824 uss.mState = UserStartedState.STATE_STOPPING; 18825 updateStartedUserArrayLocked(); 18826 18827 long ident = Binder.clearCallingIdentity(); 18828 try { 18829 // We are going to broadcast ACTION_USER_STOPPING and then 18830 // once that is done send a final ACTION_SHUTDOWN and then 18831 // stop the user. 18832 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18833 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18834 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18835 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18836 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18837 // This is the result receiver for the final shutdown broadcast. 18838 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18839 @Override 18840 public void performReceive(Intent intent, int resultCode, String data, 18841 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18842 finishUserStop(uss); 18843 } 18844 }; 18845 // This is the result receiver for the initial stopping broadcast. 18846 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18847 @Override 18848 public void performReceive(Intent intent, int resultCode, String data, 18849 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18850 // On to the next. 18851 synchronized (ActivityManagerService.this) { 18852 if (uss.mState != UserStartedState.STATE_STOPPING) { 18853 // Whoops, we are being started back up. Abort, abort! 18854 return; 18855 } 18856 uss.mState = UserStartedState.STATE_SHUTDOWN; 18857 } 18858 mBatteryStatsService.noteEvent( 18859 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18860 Integer.toString(userId), userId); 18861 mSystemServiceManager.stopUser(userId); 18862 broadcastIntentLocked(null, null, shutdownIntent, 18863 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18864 true, false, MY_PID, Process.SYSTEM_UID, userId); 18865 } 18866 }; 18867 // Kick things off. 18868 broadcastIntentLocked(null, null, stoppingIntent, 18869 null, stoppingReceiver, 0, null, null, 18870 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18871 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18872 } finally { 18873 Binder.restoreCallingIdentity(ident); 18874 } 18875 } 18876 18877 return ActivityManager.USER_OP_SUCCESS; 18878 } 18879 18880 void finishUserStop(UserStartedState uss) { 18881 final int userId = uss.mHandle.getIdentifier(); 18882 boolean stopped; 18883 ArrayList<IStopUserCallback> callbacks; 18884 synchronized (this) { 18885 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18886 if (mStartedUsers.get(userId) != uss) { 18887 stopped = false; 18888 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18889 stopped = false; 18890 } else { 18891 stopped = true; 18892 // User can no longer run. 18893 mStartedUsers.remove(userId); 18894 mUserLru.remove(Integer.valueOf(userId)); 18895 updateStartedUserArrayLocked(); 18896 18897 // Clean up all state and processes associated with the user. 18898 // Kill all the processes for the user. 18899 forceStopUserLocked(userId, "finish user"); 18900 } 18901 18902 // Explicitly remove the old information in mRecentTasks. 18903 removeRecentTasksForUserLocked(userId); 18904 } 18905 18906 for (int i=0; i<callbacks.size(); i++) { 18907 try { 18908 if (stopped) callbacks.get(i).userStopped(userId); 18909 else callbacks.get(i).userStopAborted(userId); 18910 } catch (RemoteException e) { 18911 } 18912 } 18913 18914 if (stopped) { 18915 mSystemServiceManager.cleanupUser(userId); 18916 synchronized (this) { 18917 mStackSupervisor.removeUserLocked(userId); 18918 } 18919 } 18920 } 18921 18922 @Override 18923 public UserInfo getCurrentUser() { 18924 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18925 != PackageManager.PERMISSION_GRANTED) && ( 18926 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18927 != PackageManager.PERMISSION_GRANTED)) { 18928 String msg = "Permission Denial: getCurrentUser() from pid=" 18929 + Binder.getCallingPid() 18930 + ", uid=" + Binder.getCallingUid() 18931 + " requires " + INTERACT_ACROSS_USERS; 18932 Slog.w(TAG, msg); 18933 throw new SecurityException(msg); 18934 } 18935 synchronized (this) { 18936 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18937 return getUserManagerLocked().getUserInfo(userId); 18938 } 18939 } 18940 18941 int getCurrentUserIdLocked() { 18942 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18943 } 18944 18945 @Override 18946 public boolean isUserRunning(int userId, boolean orStopped) { 18947 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18948 != PackageManager.PERMISSION_GRANTED) { 18949 String msg = "Permission Denial: isUserRunning() from pid=" 18950 + Binder.getCallingPid() 18951 + ", uid=" + Binder.getCallingUid() 18952 + " requires " + INTERACT_ACROSS_USERS; 18953 Slog.w(TAG, msg); 18954 throw new SecurityException(msg); 18955 } 18956 synchronized (this) { 18957 return isUserRunningLocked(userId, orStopped); 18958 } 18959 } 18960 18961 boolean isUserRunningLocked(int userId, boolean orStopped) { 18962 UserStartedState state = mStartedUsers.get(userId); 18963 if (state == null) { 18964 return false; 18965 } 18966 if (orStopped) { 18967 return true; 18968 } 18969 return state.mState != UserStartedState.STATE_STOPPING 18970 && state.mState != UserStartedState.STATE_SHUTDOWN; 18971 } 18972 18973 @Override 18974 public int[] getRunningUserIds() { 18975 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18976 != PackageManager.PERMISSION_GRANTED) { 18977 String msg = "Permission Denial: isUserRunning() from pid=" 18978 + Binder.getCallingPid() 18979 + ", uid=" + Binder.getCallingUid() 18980 + " requires " + INTERACT_ACROSS_USERS; 18981 Slog.w(TAG, msg); 18982 throw new SecurityException(msg); 18983 } 18984 synchronized (this) { 18985 return mStartedUserArray; 18986 } 18987 } 18988 18989 private void updateStartedUserArrayLocked() { 18990 int num = 0; 18991 for (int i=0; i<mStartedUsers.size(); i++) { 18992 UserStartedState uss = mStartedUsers.valueAt(i); 18993 // This list does not include stopping users. 18994 if (uss.mState != UserStartedState.STATE_STOPPING 18995 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18996 num++; 18997 } 18998 } 18999 mStartedUserArray = new int[num]; 19000 num = 0; 19001 for (int i=0; i<mStartedUsers.size(); i++) { 19002 UserStartedState uss = mStartedUsers.valueAt(i); 19003 if (uss.mState != UserStartedState.STATE_STOPPING 19004 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19005 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19006 num++; 19007 } 19008 } 19009 } 19010 19011 @Override 19012 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19013 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19014 != PackageManager.PERMISSION_GRANTED) { 19015 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19016 + Binder.getCallingPid() 19017 + ", uid=" + Binder.getCallingUid() 19018 + " requires " + INTERACT_ACROSS_USERS_FULL; 19019 Slog.w(TAG, msg); 19020 throw new SecurityException(msg); 19021 } 19022 19023 mUserSwitchObservers.register(observer); 19024 } 19025 19026 @Override 19027 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19028 mUserSwitchObservers.unregister(observer); 19029 } 19030 19031 private boolean userExists(int userId) { 19032 if (userId == 0) { 19033 return true; 19034 } 19035 UserManagerService ums = getUserManagerLocked(); 19036 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19037 } 19038 19039 int[] getUsersLocked() { 19040 UserManagerService ums = getUserManagerLocked(); 19041 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19042 } 19043 19044 UserManagerService getUserManagerLocked() { 19045 if (mUserManager == null) { 19046 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19047 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19048 } 19049 return mUserManager; 19050 } 19051 19052 private int applyUserId(int uid, int userId) { 19053 return UserHandle.getUid(userId, uid); 19054 } 19055 19056 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19057 if (info == null) return null; 19058 ApplicationInfo newInfo = new ApplicationInfo(info); 19059 newInfo.uid = applyUserId(info.uid, userId); 19060 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19061 + info.packageName; 19062 return newInfo; 19063 } 19064 19065 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19066 if (aInfo == null 19067 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19068 return aInfo; 19069 } 19070 19071 ActivityInfo info = new ActivityInfo(aInfo); 19072 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19073 return info; 19074 } 19075 19076 private final class LocalService extends ActivityManagerInternal { 19077 @Override 19078 public void goingToSleep() { 19079 ActivityManagerService.this.goingToSleep(); 19080 } 19081 19082 @Override 19083 public void wakingUp() { 19084 ActivityManagerService.this.wakingUp(); 19085 } 19086 19087 @Override 19088 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19089 String processName, String abiOverride, int uid, Runnable crashHandler) { 19090 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19091 processName, abiOverride, uid, crashHandler); 19092 } 19093 } 19094 19095 /** 19096 * An implementation of IAppTask, that allows an app to manage its own tasks via 19097 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19098 * only the process that calls getAppTasks() can call the AppTask methods. 19099 */ 19100 class AppTaskImpl extends IAppTask.Stub { 19101 private int mTaskId; 19102 private int mCallingUid; 19103 19104 public AppTaskImpl(int taskId, int callingUid) { 19105 mTaskId = taskId; 19106 mCallingUid = callingUid; 19107 } 19108 19109 private void checkCaller() { 19110 if (mCallingUid != Binder.getCallingUid()) { 19111 throw new SecurityException("Caller " + mCallingUid 19112 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19113 } 19114 } 19115 19116 @Override 19117 public void finishAndRemoveTask() { 19118 checkCaller(); 19119 19120 synchronized (ActivityManagerService.this) { 19121 long origId = Binder.clearCallingIdentity(); 19122 try { 19123 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19124 if (tr == null) { 19125 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19126 } 19127 // Only kill the process if we are not a new document 19128 int flags = tr.getBaseIntent().getFlags(); 19129 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19130 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19131 removeTaskByIdLocked(mTaskId, 19132 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19133 } finally { 19134 Binder.restoreCallingIdentity(origId); 19135 } 19136 } 19137 } 19138 19139 @Override 19140 public ActivityManager.RecentTaskInfo getTaskInfo() { 19141 checkCaller(); 19142 19143 synchronized (ActivityManagerService.this) { 19144 long origId = Binder.clearCallingIdentity(); 19145 try { 19146 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19147 if (tr == null) { 19148 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19149 } 19150 return createRecentTaskInfoFromTaskRecord(tr); 19151 } finally { 19152 Binder.restoreCallingIdentity(origId); 19153 } 19154 } 19155 } 19156 19157 @Override 19158 public void moveToFront() { 19159 checkCaller(); 19160 19161 final TaskRecord tr; 19162 synchronized (ActivityManagerService.this) { 19163 tr = recentTaskForIdLocked(mTaskId); 19164 if (tr == null) { 19165 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19166 } 19167 if (tr.getRootActivity() != null) { 19168 moveTaskToFrontLocked(tr.taskId, 0, null); 19169 return; 19170 } 19171 } 19172 19173 startActivityFromRecentsInner(tr.taskId, null); 19174 } 19175 19176 @Override 19177 public int startActivity(IBinder whoThread, String callingPackage, 19178 Intent intent, String resolvedType, Bundle options) { 19179 checkCaller(); 19180 19181 int callingUser = UserHandle.getCallingUserId(); 19182 TaskRecord tr; 19183 IApplicationThread appThread; 19184 synchronized (ActivityManagerService.this) { 19185 tr = recentTaskForIdLocked(mTaskId); 19186 if (tr == null) { 19187 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19188 } 19189 appThread = ApplicationThreadNative.asInterface(whoThread); 19190 if (appThread == null) { 19191 throw new IllegalArgumentException("Bad app thread " + appThread); 19192 } 19193 } 19194 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19195 resolvedType, null, null, null, null, 0, 0, null, null, 19196 null, options, callingUser, null, tr); 19197 } 19198 19199 @Override 19200 public void setExcludeFromRecents(boolean exclude) { 19201 checkCaller(); 19202 19203 synchronized (ActivityManagerService.this) { 19204 long origId = Binder.clearCallingIdentity(); 19205 try { 19206 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19207 if (tr == null) { 19208 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19209 } 19210 Intent intent = tr.getBaseIntent(); 19211 if (exclude) { 19212 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19213 } else { 19214 intent.setFlags(intent.getFlags() 19215 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19216 } 19217 } finally { 19218 Binder.restoreCallingIdentity(origId); 19219 } 19220 } 19221 } 19222 } 19223} 19224