ActivityManagerService.java revision 27f36f426702acf7ba3103997e5009da2cd67c80
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.os.BackgroundThread; 65import com.android.internal.os.BatteryStatsImpl; 66import com.android.internal.os.ProcessCpuTracker; 67import com.android.internal.os.TransferPipe; 68import com.android.internal.os.Zygote; 69import com.android.internal.util.FastPrintWriter; 70import com.android.internal.util.FastXmlSerializer; 71import com.android.internal.util.MemInfoReader; 72import com.android.internal.util.Preconditions; 73import com.android.server.AppOpsService; 74import com.android.server.AttributeCache; 75import com.android.server.IntentResolver; 76import com.android.server.LocalServices; 77import com.android.server.ServiceThread; 78import com.android.server.SystemService; 79import com.android.server.SystemServiceManager; 80import com.android.server.Watchdog; 81import com.android.server.am.ActivityStack.ActivityState; 82import com.android.server.firewall.IntentFirewall; 83import com.android.server.pm.Installer; 84import com.android.server.pm.UserManagerService; 85import com.android.server.statusbar.StatusBarManagerInternal; 86import com.android.server.wm.AppTransition; 87import com.android.server.wm.WindowManagerService; 88import com.google.android.collect.Lists; 89import com.google.android.collect.Maps; 90 91import libcore.io.IoUtils; 92 93import org.xmlpull.v1.XmlPullParser; 94import org.xmlpull.v1.XmlPullParserException; 95import org.xmlpull.v1.XmlSerializer; 96 97import android.app.Activity; 98import android.app.ActivityManager; 99import android.app.ActivityManager.RunningTaskInfo; 100import android.app.ActivityManager.StackInfo; 101import android.app.ActivityManagerInternal; 102import android.app.ActivityManagerNative; 103import android.app.ActivityOptions; 104import android.app.ActivityThread; 105import android.app.AlertDialog; 106import android.app.AppGlobals; 107import android.app.ApplicationErrorReport; 108import android.app.Dialog; 109import android.app.IActivityController; 110import android.app.IApplicationThread; 111import android.app.IInstrumentationWatcher; 112import android.app.INotificationManager; 113import android.app.IProcessObserver; 114import android.app.IServiceConnection; 115import android.app.IStopUserCallback; 116import android.app.IUiAutomationConnection; 117import android.app.IUserSwitchObserver; 118import android.app.Instrumentation; 119import android.app.Notification; 120import android.app.NotificationManager; 121import android.app.PendingIntent; 122import android.app.backup.IBackupManager; 123import android.content.ActivityNotFoundException; 124import android.content.BroadcastReceiver; 125import android.content.ClipData; 126import android.content.ComponentCallbacks2; 127import android.content.ComponentName; 128import android.content.ContentProvider; 129import android.content.ContentResolver; 130import android.content.Context; 131import android.content.DialogInterface; 132import android.content.IContentProvider; 133import android.content.IIntentReceiver; 134import android.content.IIntentSender; 135import android.content.Intent; 136import android.content.IntentFilter; 137import android.content.IntentSender; 138import android.content.pm.ActivityInfo; 139import android.content.pm.ApplicationInfo; 140import android.content.pm.ConfigurationInfo; 141import android.content.pm.IPackageDataObserver; 142import android.content.pm.IPackageManager; 143import android.content.pm.InstrumentationInfo; 144import android.content.pm.PackageInfo; 145import android.content.pm.PackageManager; 146import android.content.pm.ParceledListSlice; 147import android.content.pm.UserInfo; 148import android.content.pm.PackageManager.NameNotFoundException; 149import android.content.pm.PathPermission; 150import android.content.pm.ProviderInfo; 151import android.content.pm.ResolveInfo; 152import android.content.pm.ServiceInfo; 153import android.content.res.CompatibilityInfo; 154import android.content.res.Configuration; 155import android.net.Proxy; 156import android.net.ProxyInfo; 157import android.net.Uri; 158import android.os.Binder; 159import android.os.Build; 160import android.os.Bundle; 161import android.os.Debug; 162import android.os.DropBoxManager; 163import android.os.Environment; 164import android.os.FactoryTest; 165import android.os.FileObserver; 166import android.os.FileUtils; 167import android.os.Handler; 168import android.os.IBinder; 169import android.os.IPermissionController; 170import android.os.IRemoteCallback; 171import android.os.IUserManager; 172import android.os.Looper; 173import android.os.Message; 174import android.os.Parcel; 175import android.os.ParcelFileDescriptor; 176import android.os.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; 203 204import dalvik.system.VMRuntime; 205 206import java.io.BufferedInputStream; 207import java.io.BufferedOutputStream; 208import java.io.DataInputStream; 209import java.io.DataOutputStream; 210import java.io.File; 211import java.io.FileDescriptor; 212import java.io.FileInputStream; 213import java.io.FileNotFoundException; 214import java.io.FileOutputStream; 215import java.io.IOException; 216import java.io.InputStreamReader; 217import java.io.PrintWriter; 218import java.io.StringWriter; 219import java.lang.ref.WeakReference; 220import java.util.ArrayList; 221import java.util.Arrays; 222import java.util.Collections; 223import java.util.Comparator; 224import java.util.HashMap; 225import java.util.HashSet; 226import java.util.Iterator; 227import java.util.List; 228import java.util.Locale; 229import java.util.Map; 230import java.util.Set; 231import java.util.concurrent.atomic.AtomicBoolean; 232import java.util.concurrent.atomic.AtomicLong; 233 234public final class ActivityManagerService extends ActivityManagerNative 235 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 236 237 private static final String USER_DATA_DIR = "/data/user/"; 238 // File that stores last updated system version and called preboot receivers 239 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 240 241 static final String TAG = "ActivityManager"; 242 static final String TAG_MU = "ActivityManagerServiceMU"; 243 static final boolean DEBUG = false; 244 static final boolean localLOGV = DEBUG; 245 static final boolean DEBUG_BACKUP = localLOGV || false; 246 static final boolean DEBUG_BROADCAST = localLOGV || false; 247 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 248 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 249 static final boolean DEBUG_CLEANUP = localLOGV || false; 250 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 251 static final boolean DEBUG_FOCUS = false; 252 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 253 static final boolean DEBUG_MU = localLOGV || false; 254 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 255 static final boolean DEBUG_LRU = localLOGV || false; 256 static final boolean DEBUG_PAUSE = localLOGV || false; 257 static final boolean DEBUG_POWER = localLOGV || false; 258 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 259 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 260 static final boolean DEBUG_PROCESSES = localLOGV || false; 261 static final boolean DEBUG_PROVIDER = localLOGV || false; 262 static final boolean DEBUG_RESULTS = localLOGV || false; 263 static final boolean DEBUG_SERVICE = localLOGV || false; 264 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 265 static final boolean DEBUG_STACK = localLOGV || false; 266 static final boolean DEBUG_SWITCH = localLOGV || false; 267 static final boolean DEBUG_TASKS = localLOGV || false; 268 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 269 static final boolean DEBUG_TRANSITION = localLOGV || false; 270 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 271 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 272 static final boolean DEBUG_VISBILITY = localLOGV || false; 273 static final boolean DEBUG_PSS = localLOGV || false; 274 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 275 static final boolean DEBUG_RECENTS = localLOGV || false; 276 static final boolean VALIDATE_TOKENS = false; 277 static final boolean SHOW_ACTIVITY_START_TIME = true; 278 279 // Control over CPU and battery monitoring. 280 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 281 static final boolean MONITOR_CPU_USAGE = true; 282 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 283 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 284 static final boolean MONITOR_THREAD_CPU_USAGE = false; 285 286 // The flags that are set for all calls we make to the package manager. 287 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 288 289 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 290 291 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 292 293 // Maximum number recent bitmaps to keep in memory. 294 static final int MAX_RECENT_BITMAPS = 5; 295 296 // Amount of time after a call to stopAppSwitches() during which we will 297 // prevent further untrusted switches from happening. 298 static final long APP_SWITCH_DELAY_TIME = 5*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real. 302 static final int PROC_START_TIMEOUT = 10*1000; 303 304 // How long we wait for a launched process to attach to the activity manager 305 // before we decide it's never going to come up for real, when the process was 306 // started with a wrapper for instrumentation (such as Valgrind) because it 307 // could take much longer than usual. 308 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 309 310 // How long to wait after going idle before forcing apps to GC. 311 static final int GC_TIMEOUT = 5*1000; 312 313 // The minimum amount of time between successive GC requests for a process. 314 static final int GC_MIN_INTERVAL = 60*1000; 315 316 // The minimum amount of time between successive PSS requests for a process. 317 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process 320 // when the request is due to the memory state being lowered. 321 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 322 323 // The rate at which we check for apps using excessive power -- 15 mins. 324 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on wake locks to start killing things. 328 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // The minimum sample duration we will allow before deciding we have 331 // enough data on CPU usage to start killing things. 332 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 333 334 // How long we allow a receiver to run before giving up on it. 335 static final int BROADCAST_FG_TIMEOUT = 10*1000; 336 static final int BROADCAST_BG_TIMEOUT = 60*1000; 337 338 // How long we wait until we timeout on key dispatching. 339 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 340 341 // How long we wait until we timeout on key dispatching during instrumentation. 342 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 343 344 // Amount of time we wait for observers to handle a user switch before 345 // giving up on them and unfreezing the screen. 346 static final int USER_SWITCH_TIMEOUT = 2*1000; 347 348 // Maximum number of users we allow to be running at a time. 349 static final int MAX_RUNNING_USERS = 3; 350 351 // How long to wait in getAssistContextExtras for the activity and foreground services 352 // to respond with the result. 353 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 354 355 // Maximum number of persisted Uri grants a package is allowed 356 static final int MAX_PERSISTED_URI_GRANTS = 128; 357 358 static final int MY_PID = Process.myPid(); 359 360 static final String[] EMPTY_STRING_ARRAY = new String[0]; 361 362 // How many bytes to write into the dropbox log before truncating 363 static final int DROPBOX_MAX_SIZE = 256 * 1024; 364 365 // Access modes for handleIncomingUser. 366 static final int ALLOW_NON_FULL = 0; 367 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 368 static final int ALLOW_FULL_ONLY = 2; 369 370 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 371 372 /** All system services */ 373 SystemServiceManager mSystemServiceManager; 374 375 private Installer mInstaller; 376 377 /** Run all ActivityStacks through this */ 378 ActivityStackSupervisor mStackSupervisor; 379 380 public IntentFirewall mIntentFirewall; 381 382 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 383 // default actuion automatically. Important for devices without direct input 384 // devices. 385 private boolean mShowDialogs = true; 386 387 BroadcastQueue mFgBroadcastQueue; 388 BroadcastQueue mBgBroadcastQueue; 389 // Convenient for easy iteration over the queues. Foreground is first 390 // so that dispatch of foreground broadcasts gets precedence. 391 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 392 393 BroadcastQueue broadcastQueueForIntent(Intent intent) { 394 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 395 if (DEBUG_BACKGROUND_BROADCAST) { 396 Slog.i(TAG, "Broadcast intent " + intent + " on " 397 + (isFg ? "foreground" : "background") 398 + " queue"); 399 } 400 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 401 } 402 403 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 404 for (BroadcastQueue queue : mBroadcastQueues) { 405 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 406 if (r != null) { 407 return r; 408 } 409 } 410 return null; 411 } 412 413 /** 414 * Activity we have told the window manager to have key focus. 415 */ 416 ActivityRecord mFocusedActivity = null; 417 418 /** 419 * List of intents that were used to start the most recent tasks. 420 */ 421 ArrayList<TaskRecord> mRecentTasks; 422 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 423 424 /** 425 * For addAppTask: cached of the last activity component that was added. 426 */ 427 ComponentName mLastAddedTaskComponent; 428 429 /** 430 * For addAppTask: cached of the last activity uid that was added. 431 */ 432 int mLastAddedTaskUid; 433 434 /** 435 * For addAppTask: cached of the last ActivityInfo that was added. 436 */ 437 ActivityInfo mLastAddedTaskActivity; 438 439 public class PendingAssistExtras extends Binder implements Runnable { 440 public final ActivityRecord activity; 441 public final Bundle extras; 442 public final Intent intent; 443 public final String hint; 444 public final int userHandle; 445 public boolean haveResult = false; 446 public Bundle result = null; 447 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 448 String _hint, int _userHandle) { 449 activity = _activity; 450 extras = _extras; 451 intent = _intent; 452 hint = _hint; 453 userHandle = _userHandle; 454 } 455 @Override 456 public void run() { 457 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 458 synchronized (this) { 459 haveResult = true; 460 notifyAll(); 461 } 462 } 463 } 464 465 final ArrayList<PendingAssistExtras> mPendingAssistExtras 466 = new ArrayList<PendingAssistExtras>(); 467 468 /** 469 * Process management. 470 */ 471 final ProcessList mProcessList = new ProcessList(); 472 473 /** 474 * All of the applications we currently have running organized by name. 475 * The keys are strings of the application package name (as 476 * returned by the package manager), and the keys are ApplicationRecord 477 * objects. 478 */ 479 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 480 481 /** 482 * Tracking long-term execution of processes to look for abuse and other 483 * bad app behavior. 484 */ 485 final ProcessStatsService mProcessStats; 486 487 /** 488 * The currently running isolated processes. 489 */ 490 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 491 492 /** 493 * Counter for assigning isolated process uids, to avoid frequently reusing the 494 * same ones. 495 */ 496 int mNextIsolatedProcessUid = 0; 497 498 /** 499 * The currently running heavy-weight process, if any. 500 */ 501 ProcessRecord mHeavyWeightProcess = null; 502 503 /** 504 * The last time that various processes have crashed. 505 */ 506 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 507 508 /** 509 * Information about a process that is currently marked as bad. 510 */ 511 static final class BadProcessInfo { 512 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 513 this.time = time; 514 this.shortMsg = shortMsg; 515 this.longMsg = longMsg; 516 this.stack = stack; 517 } 518 519 final long time; 520 final String shortMsg; 521 final String longMsg; 522 final String stack; 523 } 524 525 /** 526 * Set of applications that we consider to be bad, and will reject 527 * incoming broadcasts from (which the user has no control over). 528 * Processes are added to this set when they have crashed twice within 529 * a minimum amount of time; they are removed from it when they are 530 * later restarted (hopefully due to some user action). The value is the 531 * time it was added to the list. 532 */ 533 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 534 535 /** 536 * All of the processes we currently have running organized by pid. 537 * The keys are the pid running the application. 538 * 539 * <p>NOTE: This object is protected by its own lock, NOT the global 540 * activity manager lock! 541 */ 542 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 543 544 /** 545 * All of the processes that have been forced to be foreground. The key 546 * is the pid of the caller who requested it (we hold a death 547 * link on it). 548 */ 549 abstract class ForegroundToken implements IBinder.DeathRecipient { 550 int pid; 551 IBinder token; 552 } 553 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 554 555 /** 556 * List of records for processes that someone had tried to start before the 557 * system was ready. We don't start them at that point, but ensure they 558 * are started by the time booting is complete. 559 */ 560 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 561 562 /** 563 * List of persistent applications that are in the process 564 * of being started. 565 */ 566 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 567 568 /** 569 * Processes that are being forcibly torn down. 570 */ 571 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 572 573 /** 574 * List of running applications, sorted by recent usage. 575 * The first entry in the list is the least recently used. 576 */ 577 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Where in mLruProcesses that the processes hosting activities start. 581 */ 582 int mLruProcessActivityStart = 0; 583 584 /** 585 * Where in mLruProcesses that the processes hosting services start. 586 * This is after (lower index) than mLruProcessesActivityStart. 587 */ 588 int mLruProcessServiceStart = 0; 589 590 /** 591 * List of processes that should gc as soon as things are idle. 592 */ 593 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 594 595 /** 596 * Processes we want to collect PSS data from. 597 */ 598 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 599 600 /** 601 * Last time we requested PSS data of all processes. 602 */ 603 long mLastFullPssTime = SystemClock.uptimeMillis(); 604 605 /** 606 * If set, the next time we collect PSS data we should do a full collection 607 * with data from native processes and the kernel. 608 */ 609 boolean mFullPssPending = false; 610 611 /** 612 * This is the process holding what we currently consider to be 613 * the "home" activity. 614 */ 615 ProcessRecord mHomeProcess; 616 617 /** 618 * This is the process holding the activity the user last visited that 619 * is in a different process from the one they are currently in. 620 */ 621 ProcessRecord mPreviousProcess; 622 623 /** 624 * The time at which the previous process was last visible. 625 */ 626 long mPreviousProcessVisibleTime; 627 628 /** 629 * Which uses have been started, so are allowed to run code. 630 */ 631 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 632 633 /** 634 * LRU list of history of current users. Most recently current is at the end. 635 */ 636 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 637 638 /** 639 * Constant array of the users that are currently started. 640 */ 641 int[] mStartedUserArray = new int[] { 0 }; 642 643 /** 644 * Registered observers of the user switching mechanics. 645 */ 646 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 647 = new RemoteCallbackList<IUserSwitchObserver>(); 648 649 /** 650 * Currently active user switch. 651 */ 652 Object mCurUserSwitchCallback; 653 654 /** 655 * Packages that the user has asked to have run in screen size 656 * compatibility mode instead of filling the screen. 657 */ 658 final CompatModePackages mCompatModePackages; 659 660 /** 661 * Set of IntentSenderRecord objects that are currently active. 662 */ 663 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 664 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 665 666 /** 667 * Fingerprints (hashCode()) of stack traces that we've 668 * already logged DropBox entries for. Guarded by itself. If 669 * something (rogue user app) forces this over 670 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 671 */ 672 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 673 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 674 675 /** 676 * Strict Mode background batched logging state. 677 * 678 * The string buffer is guarded by itself, and its lock is also 679 * used to determine if another batched write is already 680 * in-flight. 681 */ 682 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 683 684 /** 685 * Keeps track of all IIntentReceivers that have been registered for 686 * broadcasts. Hash keys are the receiver IBinder, hash value is 687 * a ReceiverList. 688 */ 689 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 690 new HashMap<IBinder, ReceiverList>(); 691 692 /** 693 * Resolver for broadcast intents to registered receivers. 694 * Holds BroadcastFilter (subclass of IntentFilter). 695 */ 696 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 697 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 698 @Override 699 protected boolean allowFilterResult( 700 BroadcastFilter filter, List<BroadcastFilter> dest) { 701 IBinder target = filter.receiverList.receiver.asBinder(); 702 for (int i=dest.size()-1; i>=0; i--) { 703 if (dest.get(i).receiverList.receiver.asBinder() == target) { 704 return false; 705 } 706 } 707 return true; 708 } 709 710 @Override 711 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 712 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 713 || userId == filter.owningUserId) { 714 return super.newResult(filter, match, userId); 715 } 716 return null; 717 } 718 719 @Override 720 protected BroadcastFilter[] newArray(int size) { 721 return new BroadcastFilter[size]; 722 } 723 724 @Override 725 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 726 return packageName.equals(filter.packageName); 727 } 728 }; 729 730 /** 731 * State of all active sticky broadcasts per user. Keys are the action of the 732 * sticky Intent, values are an ArrayList of all broadcasted intents with 733 * that action (which should usually be one). The SparseArray is keyed 734 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 735 * for stickies that are sent to all users. 736 */ 737 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 738 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 739 740 final ActiveServices mServices; 741 742 /** 743 * Backup/restore process management 744 */ 745 String mBackupAppName = null; 746 BackupRecord mBackupTarget = null; 747 748 final ProviderMap mProviderMap; 749 750 /** 751 * List of content providers who have clients waiting for them. The 752 * application is currently being launched and the provider will be 753 * removed from this list once it is published. 754 */ 755 final ArrayList<ContentProviderRecord> mLaunchingProviders 756 = new ArrayList<ContentProviderRecord>(); 757 758 /** 759 * File storing persisted {@link #mGrantedUriPermissions}. 760 */ 761 private final AtomicFile mGrantFile; 762 763 /** XML constants used in {@link #mGrantFile} */ 764 private static final String TAG_URI_GRANTS = "uri-grants"; 765 private static final String TAG_URI_GRANT = "uri-grant"; 766 private static final String ATTR_USER_HANDLE = "userHandle"; 767 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 768 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 769 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 770 private static final String ATTR_TARGET_PKG = "targetPkg"; 771 private static final String ATTR_URI = "uri"; 772 private static final String ATTR_MODE_FLAGS = "modeFlags"; 773 private static final String ATTR_CREATED_TIME = "createdTime"; 774 private static final String ATTR_PREFIX = "prefix"; 775 776 /** 777 * Global set of specific {@link Uri} permissions that have been granted. 778 * This optimized lookup structure maps from {@link UriPermission#targetUid} 779 * to {@link UriPermission#uri} to {@link UriPermission}. 780 */ 781 @GuardedBy("this") 782 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 783 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 784 785 public static class GrantUri { 786 public final int sourceUserId; 787 public final Uri uri; 788 public boolean prefix; 789 790 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 791 this.sourceUserId = sourceUserId; 792 this.uri = uri; 793 this.prefix = prefix; 794 } 795 796 @Override 797 public int hashCode() { 798 int hashCode = 1; 799 hashCode = 31 * hashCode + sourceUserId; 800 hashCode = 31 * hashCode + uri.hashCode(); 801 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 802 return hashCode; 803 } 804 805 @Override 806 public boolean equals(Object o) { 807 if (o instanceof GrantUri) { 808 GrantUri other = (GrantUri) o; 809 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 810 && prefix == other.prefix; 811 } 812 return false; 813 } 814 815 @Override 816 public String toString() { 817 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 818 if (prefix) result += " [prefix]"; 819 return result; 820 } 821 822 public String toSafeString() { 823 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 824 if (prefix) result += " [prefix]"; 825 return result; 826 } 827 828 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 829 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 830 ContentProvider.getUriWithoutUserId(uri), false); 831 } 832 } 833 834 CoreSettingsObserver mCoreSettingsObserver; 835 836 /** 837 * Thread-local storage used to carry caller permissions over through 838 * indirect content-provider access. 839 */ 840 private class Identity { 841 public final IBinder token; 842 public final int pid; 843 public final int uid; 844 845 Identity(IBinder _token, int _pid, int _uid) { 846 token = _token; 847 pid = _pid; 848 uid = _uid; 849 } 850 } 851 852 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 853 854 /** 855 * All information we have collected about the runtime performance of 856 * any user id that can impact battery performance. 857 */ 858 final BatteryStatsService mBatteryStatsService; 859 860 /** 861 * Information about component usage 862 */ 863 UsageStatsManagerInternal mUsageStatsService; 864 865 /** 866 * Information about and control over application operations 867 */ 868 final AppOpsService mAppOpsService; 869 870 /** 871 * Save recent tasks information across reboots. 872 */ 873 final TaskPersister mTaskPersister; 874 875 /** 876 * Current configuration information. HistoryRecord objects are given 877 * a reference to this object to indicate which configuration they are 878 * currently running in, so this object must be kept immutable. 879 */ 880 Configuration mConfiguration = new Configuration(); 881 882 /** 883 * Current sequencing integer of the configuration, for skipping old 884 * configurations. 885 */ 886 int mConfigurationSeq = 0; 887 888 /** 889 * Hardware-reported OpenGLES version. 890 */ 891 final int GL_ES_VERSION; 892 893 /** 894 * List of initialization arguments to pass to all processes when binding applications to them. 895 * For example, references to the commonly used services. 896 */ 897 HashMap<String, IBinder> mAppBindArgs; 898 899 /** 900 * Temporary to avoid allocations. Protected by main lock. 901 */ 902 final StringBuilder mStringBuilder = new StringBuilder(256); 903 904 /** 905 * Used to control how we initialize the service. 906 */ 907 ComponentName mTopComponent; 908 String mTopAction = Intent.ACTION_MAIN; 909 String mTopData; 910 boolean mProcessesReady = false; 911 boolean mSystemReady = false; 912 boolean mBooting = false; 913 boolean mCallFinishBooting = false; 914 boolean mBootAnimationComplete = false; 915 boolean mWaitingUpdate = false; 916 boolean mDidUpdate = false; 917 boolean mOnBattery = false; 918 boolean mLaunchWarningShown = false; 919 920 Context mContext; 921 922 int mFactoryTest; 923 924 boolean mCheckedForSetup; 925 926 /** 927 * The time at which we will allow normal application switches again, 928 * after a call to {@link #stopAppSwitches()}. 929 */ 930 long mAppSwitchesAllowedTime; 931 932 /** 933 * This is set to true after the first switch after mAppSwitchesAllowedTime 934 * is set; any switches after that will clear the time. 935 */ 936 boolean mDidAppSwitch; 937 938 /** 939 * Last time (in realtime) at which we checked for power usage. 940 */ 941 long mLastPowerCheckRealtime; 942 943 /** 944 * Last time (in uptime) at which we checked for power usage. 945 */ 946 long mLastPowerCheckUptime; 947 948 /** 949 * Set while we are wanting to sleep, to prevent any 950 * activities from being started/resumed. 951 */ 952 private boolean mSleeping = false; 953 954 /** 955 * Set while we are running a voice interaction. This overrides 956 * sleeping while it is active. 957 */ 958 private boolean mRunningVoice = false; 959 960 /** 961 * State of external calls telling us if the device is asleep. 962 */ 963 private boolean mWentToSleep = false; 964 965 static final int LOCK_SCREEN_HIDDEN = 0; 966 static final int LOCK_SCREEN_LEAVING = 1; 967 static final int LOCK_SCREEN_SHOWN = 2; 968 /** 969 * State of external call telling us if the lock screen is shown. 970 */ 971 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 972 973 /** 974 * Set if we are shutting down the system, similar to sleeping. 975 */ 976 boolean mShuttingDown = false; 977 978 /** 979 * Current sequence id for oom_adj computation traversal. 980 */ 981 int mAdjSeq = 0; 982 983 /** 984 * Current sequence id for process LRU updating. 985 */ 986 int mLruSeq = 0; 987 988 /** 989 * Keep track of the non-cached/empty process we last found, to help 990 * determine how to distribute cached/empty processes next time. 991 */ 992 int mNumNonCachedProcs = 0; 993 994 /** 995 * Keep track of the number of cached hidden procs, to balance oom adj 996 * distribution between those and empty procs. 997 */ 998 int mNumCachedHiddenProcs = 0; 999 1000 /** 1001 * Keep track of the number of service processes we last found, to 1002 * determine on the next iteration which should be B services. 1003 */ 1004 int mNumServiceProcs = 0; 1005 int mNewNumAServiceProcs = 0; 1006 int mNewNumServiceProcs = 0; 1007 1008 /** 1009 * Allow the current computed overall memory level of the system to go down? 1010 * This is set to false when we are killing processes for reasons other than 1011 * memory management, so that the now smaller process list will not be taken as 1012 * an indication that memory is tighter. 1013 */ 1014 boolean mAllowLowerMemLevel = false; 1015 1016 /** 1017 * The last computed memory level, for holding when we are in a state that 1018 * processes are going away for other reasons. 1019 */ 1020 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1021 1022 /** 1023 * The last total number of process we have, to determine if changes actually look 1024 * like a shrinking number of process due to lower RAM. 1025 */ 1026 int mLastNumProcesses; 1027 1028 /** 1029 * The uptime of the last time we performed idle maintenance. 1030 */ 1031 long mLastIdleTime = SystemClock.uptimeMillis(); 1032 1033 /** 1034 * Total time spent with RAM that has been added in the past since the last idle time. 1035 */ 1036 long mLowRamTimeSinceLastIdle = 0; 1037 1038 /** 1039 * If RAM is currently low, when that horrible situation started. 1040 */ 1041 long mLowRamStartTime = 0; 1042 1043 /** 1044 * For reporting to battery stats the current top application. 1045 */ 1046 private String mCurResumedPackage = null; 1047 private int mCurResumedUid = -1; 1048 1049 /** 1050 * For reporting to battery stats the apps currently running foreground 1051 * service. The ProcessMap is package/uid tuples; each of these contain 1052 * an array of the currently foreground processes. 1053 */ 1054 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1055 = new ProcessMap<ArrayList<ProcessRecord>>(); 1056 1057 /** 1058 * This is set if we had to do a delayed dexopt of an app before launching 1059 * it, to increase the ANR timeouts in that case. 1060 */ 1061 boolean mDidDexOpt; 1062 1063 /** 1064 * Set if the systemServer made a call to enterSafeMode. 1065 */ 1066 boolean mSafeMode; 1067 1068 String mDebugApp = null; 1069 boolean mWaitForDebugger = false; 1070 boolean mDebugTransient = false; 1071 String mOrigDebugApp = null; 1072 boolean mOrigWaitForDebugger = false; 1073 boolean mAlwaysFinishActivities = false; 1074 IActivityController mController = null; 1075 String mProfileApp = null; 1076 ProcessRecord mProfileProc = null; 1077 String mProfileFile; 1078 ParcelFileDescriptor mProfileFd; 1079 int mSamplingInterval = 0; 1080 boolean mAutoStopProfiler = false; 1081 int mProfileType = 0; 1082 String mOpenGlTraceApp = null; 1083 1084 static class ProcessChangeItem { 1085 static final int CHANGE_ACTIVITIES = 1<<0; 1086 static final int CHANGE_PROCESS_STATE = 1<<1; 1087 int changes; 1088 int uid; 1089 int pid; 1090 int processState; 1091 boolean foregroundActivities; 1092 } 1093 1094 final RemoteCallbackList<IProcessObserver> mProcessObservers 1095 = new RemoteCallbackList<IProcessObserver>(); 1096 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1097 1098 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1099 = new ArrayList<ProcessChangeItem>(); 1100 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1101 = new ArrayList<ProcessChangeItem>(); 1102 1103 /** 1104 * Runtime CPU use collection thread. This object's lock is used to 1105 * perform synchronization with the thread (notifying it to run). 1106 */ 1107 final Thread mProcessCpuThread; 1108 1109 /** 1110 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1111 * Must acquire this object's lock when accessing it. 1112 * NOTE: this lock will be held while doing long operations (trawling 1113 * through all processes in /proc), so it should never be acquired by 1114 * any critical paths such as when holding the main activity manager lock. 1115 */ 1116 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1117 MONITOR_THREAD_CPU_USAGE); 1118 final AtomicLong mLastCpuTime = new AtomicLong(0); 1119 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1120 1121 long mLastWriteTime = 0; 1122 1123 /** 1124 * Used to retain an update lock when the foreground activity is in 1125 * immersive mode. 1126 */ 1127 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1128 1129 /** 1130 * Set to true after the system has finished booting. 1131 */ 1132 boolean mBooted = false; 1133 1134 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1135 int mProcessLimitOverride = -1; 1136 1137 WindowManagerService mWindowManager; 1138 1139 final ActivityThread mSystemThread; 1140 1141 // Holds the current foreground user's id 1142 int mCurrentUserId = 0; 1143 // Holds the target user's id during a user switch 1144 int mTargetUserId = UserHandle.USER_NULL; 1145 // If there are multiple profiles for the current user, their ids are here 1146 // Currently only the primary user can have managed profiles 1147 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1148 1149 /** 1150 * Mapping from each known user ID to the profile group ID it is associated with. 1151 */ 1152 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1153 1154 private UserManagerService mUserManager; 1155 1156 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1157 final ProcessRecord mApp; 1158 final int mPid; 1159 final IApplicationThread mAppThread; 1160 1161 AppDeathRecipient(ProcessRecord app, int pid, 1162 IApplicationThread thread) { 1163 if (localLOGV) Slog.v( 1164 TAG, "New death recipient " + this 1165 + " for thread " + thread.asBinder()); 1166 mApp = app; 1167 mPid = pid; 1168 mAppThread = thread; 1169 } 1170 1171 @Override 1172 public void binderDied() { 1173 if (localLOGV) Slog.v( 1174 TAG, "Death received in " + this 1175 + " for thread " + mAppThread.asBinder()); 1176 synchronized(ActivityManagerService.this) { 1177 appDiedLocked(mApp, mPid, mAppThread); 1178 } 1179 } 1180 } 1181 1182 static final int SHOW_ERROR_MSG = 1; 1183 static final int SHOW_NOT_RESPONDING_MSG = 2; 1184 static final int SHOW_FACTORY_ERROR_MSG = 3; 1185 static final int UPDATE_CONFIGURATION_MSG = 4; 1186 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1187 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1188 static final int SERVICE_TIMEOUT_MSG = 12; 1189 static final int UPDATE_TIME_ZONE = 13; 1190 static final int SHOW_UID_ERROR_MSG = 14; 1191 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1192 static final int PROC_START_TIMEOUT_MSG = 20; 1193 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1194 static final int KILL_APPLICATION_MSG = 22; 1195 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1196 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1197 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1198 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1199 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1200 static final int CLEAR_DNS_CACHE_MSG = 28; 1201 static final int UPDATE_HTTP_PROXY_MSG = 29; 1202 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1203 static final int DISPATCH_PROCESSES_CHANGED = 31; 1204 static final int DISPATCH_PROCESS_DIED = 32; 1205 static final int REPORT_MEM_USAGE_MSG = 33; 1206 static final int REPORT_USER_SWITCH_MSG = 34; 1207 static final int CONTINUE_USER_SWITCH_MSG = 35; 1208 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1209 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1210 static final int PERSIST_URI_GRANTS_MSG = 38; 1211 static final int REQUEST_ALL_PSS_MSG = 39; 1212 static final int START_PROFILES_MSG = 40; 1213 static final int UPDATE_TIME = 41; 1214 static final int SYSTEM_USER_START_MSG = 42; 1215 static final int SYSTEM_USER_CURRENT_MSG = 43; 1216 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1217 static final int FINISH_BOOTING_MSG = 45; 1218 static final int START_USER_SWITCH_MSG = 46; 1219 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1220 static final int DISMISS_DIALOG_MSG = 48; 1221 1222 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1223 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1224 static final int FIRST_COMPAT_MODE_MSG = 300; 1225 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1226 1227 CompatModeDialog mCompatModeDialog; 1228 long mLastMemUsageReportTime = 0; 1229 1230 /** 1231 * Flag whether the current user is a "monkey", i.e. whether 1232 * the UI is driven by a UI automation tool. 1233 */ 1234 private boolean mUserIsMonkey; 1235 1236 /** Flag whether the device has a Recents UI */ 1237 boolean mHasRecents; 1238 1239 /** The dimensions of the thumbnails in the Recents UI. */ 1240 int mThumbnailWidth; 1241 int mThumbnailHeight; 1242 1243 final ServiceThread mHandlerThread; 1244 final MainHandler mHandler; 1245 1246 final class MainHandler extends Handler { 1247 public MainHandler(Looper looper) { 1248 super(looper, null, true); 1249 } 1250 1251 @Override 1252 public void handleMessage(Message msg) { 1253 switch (msg.what) { 1254 case SHOW_ERROR_MSG: { 1255 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1256 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1257 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1258 synchronized (ActivityManagerService.this) { 1259 ProcessRecord proc = (ProcessRecord)data.get("app"); 1260 AppErrorResult res = (AppErrorResult) data.get("result"); 1261 if (proc != null && proc.crashDialog != null) { 1262 Slog.e(TAG, "App already has crash dialog: " + proc); 1263 if (res != null) { 1264 res.set(0); 1265 } 1266 return; 1267 } 1268 boolean isBackground = (UserHandle.getAppId(proc.uid) 1269 >= Process.FIRST_APPLICATION_UID 1270 && proc.pid != MY_PID); 1271 for (int userId : mCurrentProfileIds) { 1272 isBackground &= (proc.userId != userId); 1273 } 1274 if (isBackground && !showBackground) { 1275 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1276 if (res != null) { 1277 res.set(0); 1278 } 1279 return; 1280 } 1281 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1282 Dialog d = new AppErrorDialog(mContext, 1283 ActivityManagerService.this, res, proc); 1284 d.show(); 1285 proc.crashDialog = d; 1286 } else { 1287 // The device is asleep, so just pretend that the user 1288 // saw a crash dialog and hit "force quit". 1289 if (res != null) { 1290 res.set(0); 1291 } 1292 } 1293 } 1294 1295 ensureBootCompleted(); 1296 } break; 1297 case SHOW_NOT_RESPONDING_MSG: { 1298 synchronized (ActivityManagerService.this) { 1299 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1300 ProcessRecord proc = (ProcessRecord)data.get("app"); 1301 if (proc != null && proc.anrDialog != null) { 1302 Slog.e(TAG, "App already has anr dialog: " + proc); 1303 return; 1304 } 1305 1306 Intent intent = new Intent("android.intent.action.ANR"); 1307 if (!mProcessesReady) { 1308 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1309 | Intent.FLAG_RECEIVER_FOREGROUND); 1310 } 1311 broadcastIntentLocked(null, null, intent, 1312 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1313 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1314 1315 if (mShowDialogs) { 1316 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1317 mContext, proc, (ActivityRecord)data.get("activity"), 1318 msg.arg1 != 0); 1319 d.show(); 1320 proc.anrDialog = d; 1321 } else { 1322 // Just kill the app if there is no dialog to be shown. 1323 killAppAtUsersRequest(proc, null); 1324 } 1325 } 1326 1327 ensureBootCompleted(); 1328 } break; 1329 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1330 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1331 synchronized (ActivityManagerService.this) { 1332 ProcessRecord proc = (ProcessRecord) data.get("app"); 1333 if (proc == null) { 1334 Slog.e(TAG, "App not found when showing strict mode dialog."); 1335 break; 1336 } 1337 if (proc.crashDialog != null) { 1338 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1339 return; 1340 } 1341 AppErrorResult res = (AppErrorResult) data.get("result"); 1342 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1343 Dialog d = new StrictModeViolationDialog(mContext, 1344 ActivityManagerService.this, res, proc); 1345 d.show(); 1346 proc.crashDialog = d; 1347 } else { 1348 // The device is asleep, so just pretend that the user 1349 // saw a crash dialog and hit "force quit". 1350 res.set(0); 1351 } 1352 } 1353 ensureBootCompleted(); 1354 } break; 1355 case SHOW_FACTORY_ERROR_MSG: { 1356 Dialog d = new FactoryErrorDialog( 1357 mContext, msg.getData().getCharSequence("msg")); 1358 d.show(); 1359 ensureBootCompleted(); 1360 } break; 1361 case UPDATE_CONFIGURATION_MSG: { 1362 final ContentResolver resolver = mContext.getContentResolver(); 1363 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1364 } break; 1365 case GC_BACKGROUND_PROCESSES_MSG: { 1366 synchronized (ActivityManagerService.this) { 1367 performAppGcsIfAppropriateLocked(); 1368 } 1369 } break; 1370 case WAIT_FOR_DEBUGGER_MSG: { 1371 synchronized (ActivityManagerService.this) { 1372 ProcessRecord app = (ProcessRecord)msg.obj; 1373 if (msg.arg1 != 0) { 1374 if (!app.waitedForDebugger) { 1375 Dialog d = new AppWaitingForDebuggerDialog( 1376 ActivityManagerService.this, 1377 mContext, app); 1378 app.waitDialog = d; 1379 app.waitedForDebugger = true; 1380 d.show(); 1381 } 1382 } else { 1383 if (app.waitDialog != null) { 1384 app.waitDialog.dismiss(); 1385 app.waitDialog = null; 1386 } 1387 } 1388 } 1389 } break; 1390 case SERVICE_TIMEOUT_MSG: { 1391 if (mDidDexOpt) { 1392 mDidDexOpt = false; 1393 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1394 nmsg.obj = msg.obj; 1395 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1396 return; 1397 } 1398 mServices.serviceTimeout((ProcessRecord)msg.obj); 1399 } break; 1400 case UPDATE_TIME_ZONE: { 1401 synchronized (ActivityManagerService.this) { 1402 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1403 ProcessRecord r = mLruProcesses.get(i); 1404 if (r.thread != null) { 1405 try { 1406 r.thread.updateTimeZone(); 1407 } catch (RemoteException ex) { 1408 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1409 } 1410 } 1411 } 1412 } 1413 } break; 1414 case CLEAR_DNS_CACHE_MSG: { 1415 synchronized (ActivityManagerService.this) { 1416 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1417 ProcessRecord r = mLruProcesses.get(i); 1418 if (r.thread != null) { 1419 try { 1420 r.thread.clearDnsCache(); 1421 } catch (RemoteException ex) { 1422 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1423 } 1424 } 1425 } 1426 } 1427 } break; 1428 case UPDATE_HTTP_PROXY_MSG: { 1429 ProxyInfo proxy = (ProxyInfo)msg.obj; 1430 String host = ""; 1431 String port = ""; 1432 String exclList = ""; 1433 Uri pacFileUrl = Uri.EMPTY; 1434 if (proxy != null) { 1435 host = proxy.getHost(); 1436 port = Integer.toString(proxy.getPort()); 1437 exclList = proxy.getExclusionListAsString(); 1438 pacFileUrl = proxy.getPacFileUrl(); 1439 } 1440 synchronized (ActivityManagerService.this) { 1441 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1442 ProcessRecord r = mLruProcesses.get(i); 1443 if (r.thread != null) { 1444 try { 1445 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1446 } catch (RemoteException ex) { 1447 Slog.w(TAG, "Failed to update http proxy for: " + 1448 r.info.processName); 1449 } 1450 } 1451 } 1452 } 1453 } break; 1454 case SHOW_UID_ERROR_MSG: { 1455 if (mShowDialogs) { 1456 AlertDialog d = new BaseErrorDialog(mContext); 1457 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1458 d.setCancelable(false); 1459 d.setTitle(mContext.getText(R.string.android_system_label)); 1460 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1461 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1462 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1463 d.show(); 1464 } 1465 } break; 1466 case SHOW_FINGERPRINT_ERROR_MSG: { 1467 if (mShowDialogs) { 1468 AlertDialog d = new BaseErrorDialog(mContext); 1469 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1470 d.setCancelable(false); 1471 d.setTitle(mContext.getText(R.string.android_system_label)); 1472 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1473 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1474 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1475 d.show(); 1476 } 1477 } break; 1478 case PROC_START_TIMEOUT_MSG: { 1479 if (mDidDexOpt) { 1480 mDidDexOpt = false; 1481 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1482 nmsg.obj = msg.obj; 1483 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1484 return; 1485 } 1486 ProcessRecord app = (ProcessRecord)msg.obj; 1487 synchronized (ActivityManagerService.this) { 1488 processStartTimedOutLocked(app); 1489 } 1490 } break; 1491 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1492 synchronized (ActivityManagerService.this) { 1493 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1494 } 1495 } break; 1496 case KILL_APPLICATION_MSG: { 1497 synchronized (ActivityManagerService.this) { 1498 int appid = msg.arg1; 1499 boolean restart = (msg.arg2 == 1); 1500 Bundle bundle = (Bundle)msg.obj; 1501 String pkg = bundle.getString("pkg"); 1502 String reason = bundle.getString("reason"); 1503 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1504 false, UserHandle.USER_ALL, reason); 1505 } 1506 } break; 1507 case FINALIZE_PENDING_INTENT_MSG: { 1508 ((PendingIntentRecord)msg.obj).completeFinalize(); 1509 } break; 1510 case POST_HEAVY_NOTIFICATION_MSG: { 1511 INotificationManager inm = NotificationManager.getService(); 1512 if (inm == null) { 1513 return; 1514 } 1515 1516 ActivityRecord root = (ActivityRecord)msg.obj; 1517 ProcessRecord process = root.app; 1518 if (process == null) { 1519 return; 1520 } 1521 1522 try { 1523 Context context = mContext.createPackageContext(process.info.packageName, 0); 1524 String text = mContext.getString(R.string.heavy_weight_notification, 1525 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1526 Notification notification = new Notification(); 1527 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1528 notification.when = 0; 1529 notification.flags = Notification.FLAG_ONGOING_EVENT; 1530 notification.tickerText = text; 1531 notification.defaults = 0; // please be quiet 1532 notification.sound = null; 1533 notification.vibrate = null; 1534 notification.color = mContext.getResources().getColor( 1535 com.android.internal.R.color.system_notification_accent_color); 1536 notification.setLatestEventInfo(context, text, 1537 mContext.getText(R.string.heavy_weight_notification_detail), 1538 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1539 PendingIntent.FLAG_CANCEL_CURRENT, null, 1540 new UserHandle(root.userId))); 1541 1542 try { 1543 int[] outId = new int[1]; 1544 inm.enqueueNotificationWithTag("android", "android", null, 1545 R.string.heavy_weight_notification, 1546 notification, outId, root.userId); 1547 } catch (RuntimeException e) { 1548 Slog.w(ActivityManagerService.TAG, 1549 "Error showing notification for heavy-weight app", e); 1550 } catch (RemoteException e) { 1551 } 1552 } catch (NameNotFoundException e) { 1553 Slog.w(TAG, "Unable to create context for heavy notification", e); 1554 } 1555 } break; 1556 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1557 INotificationManager inm = NotificationManager.getService(); 1558 if (inm == null) { 1559 return; 1560 } 1561 try { 1562 inm.cancelNotificationWithTag("android", null, 1563 R.string.heavy_weight_notification, msg.arg1); 1564 } catch (RuntimeException e) { 1565 Slog.w(ActivityManagerService.TAG, 1566 "Error canceling notification for service", e); 1567 } catch (RemoteException e) { 1568 } 1569 } break; 1570 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1571 synchronized (ActivityManagerService.this) { 1572 checkExcessivePowerUsageLocked(true); 1573 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1574 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1575 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1576 } 1577 } break; 1578 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1579 synchronized (ActivityManagerService.this) { 1580 ActivityRecord ar = (ActivityRecord)msg.obj; 1581 if (mCompatModeDialog != null) { 1582 if (mCompatModeDialog.mAppInfo.packageName.equals( 1583 ar.info.applicationInfo.packageName)) { 1584 return; 1585 } 1586 mCompatModeDialog.dismiss(); 1587 mCompatModeDialog = null; 1588 } 1589 if (ar != null && false) { 1590 if (mCompatModePackages.getPackageAskCompatModeLocked( 1591 ar.packageName)) { 1592 int mode = mCompatModePackages.computeCompatModeLocked( 1593 ar.info.applicationInfo); 1594 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1595 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1596 mCompatModeDialog = new CompatModeDialog( 1597 ActivityManagerService.this, mContext, 1598 ar.info.applicationInfo); 1599 mCompatModeDialog.show(); 1600 } 1601 } 1602 } 1603 } 1604 break; 1605 } 1606 case DISPATCH_PROCESSES_CHANGED: { 1607 dispatchProcessesChanged(); 1608 break; 1609 } 1610 case DISPATCH_PROCESS_DIED: { 1611 final int pid = msg.arg1; 1612 final int uid = msg.arg2; 1613 dispatchProcessDied(pid, uid); 1614 break; 1615 } 1616 case REPORT_MEM_USAGE_MSG: { 1617 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1618 Thread thread = new Thread() { 1619 @Override public void run() { 1620 reportMemUsage(memInfos); 1621 } 1622 }; 1623 thread.start(); 1624 break; 1625 } 1626 case START_USER_SWITCH_MSG: { 1627 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1628 break; 1629 } 1630 case REPORT_USER_SWITCH_MSG: { 1631 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1632 break; 1633 } 1634 case CONTINUE_USER_SWITCH_MSG: { 1635 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1636 break; 1637 } 1638 case USER_SWITCH_TIMEOUT_MSG: { 1639 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1640 break; 1641 } 1642 case IMMERSIVE_MODE_LOCK_MSG: { 1643 final boolean nextState = (msg.arg1 != 0); 1644 if (mUpdateLock.isHeld() != nextState) { 1645 if (DEBUG_IMMERSIVE) { 1646 final ActivityRecord r = (ActivityRecord) msg.obj; 1647 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1648 } 1649 if (nextState) { 1650 mUpdateLock.acquire(); 1651 } else { 1652 mUpdateLock.release(); 1653 } 1654 } 1655 break; 1656 } 1657 case PERSIST_URI_GRANTS_MSG: { 1658 writeGrantedUriPermissions(); 1659 break; 1660 } 1661 case REQUEST_ALL_PSS_MSG: { 1662 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1663 break; 1664 } 1665 case START_PROFILES_MSG: { 1666 synchronized (ActivityManagerService.this) { 1667 startProfilesLocked(); 1668 } 1669 break; 1670 } 1671 case UPDATE_TIME: { 1672 synchronized (ActivityManagerService.this) { 1673 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1674 ProcessRecord r = mLruProcesses.get(i); 1675 if (r.thread != null) { 1676 try { 1677 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1678 } catch (RemoteException ex) { 1679 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1680 } 1681 } 1682 } 1683 } 1684 break; 1685 } 1686 case SYSTEM_USER_START_MSG: { 1687 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1688 Integer.toString(msg.arg1), msg.arg1); 1689 mSystemServiceManager.startUser(msg.arg1); 1690 break; 1691 } 1692 case SYSTEM_USER_CURRENT_MSG: { 1693 mBatteryStatsService.noteEvent( 1694 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1695 Integer.toString(msg.arg2), msg.arg2); 1696 mBatteryStatsService.noteEvent( 1697 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1698 Integer.toString(msg.arg1), msg.arg1); 1699 mSystemServiceManager.switchUser(msg.arg1); 1700 break; 1701 } 1702 case ENTER_ANIMATION_COMPLETE_MSG: { 1703 synchronized (ActivityManagerService.this) { 1704 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1705 if (r != null && r.app != null && r.app.thread != null) { 1706 try { 1707 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1708 } catch (RemoteException e) { 1709 } 1710 } 1711 } 1712 break; 1713 } 1714 case FINISH_BOOTING_MSG: { 1715 if (msg.arg1 != 0) { 1716 finishBooting(); 1717 } 1718 if (msg.arg2 != 0) { 1719 enableScreenAfterBoot(); 1720 } 1721 break; 1722 } 1723 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1724 try { 1725 Locale l = (Locale) msg.obj; 1726 IBinder service = ServiceManager.getService("mount"); 1727 IMountService mountService = IMountService.Stub.asInterface(service); 1728 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1729 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1730 } catch (RemoteException e) { 1731 Log.e(TAG, "Error storing locale for decryption UI", e); 1732 } 1733 break; 1734 } 1735 case DISMISS_DIALOG_MSG: { 1736 final Dialog d = (Dialog) msg.obj; 1737 d.dismiss(); 1738 break; 1739 } 1740 } 1741 } 1742 }; 1743 1744 static final int COLLECT_PSS_BG_MSG = 1; 1745 1746 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1747 @Override 1748 public void handleMessage(Message msg) { 1749 switch (msg.what) { 1750 case COLLECT_PSS_BG_MSG: { 1751 long start = SystemClock.uptimeMillis(); 1752 MemInfoReader memInfo = null; 1753 synchronized (ActivityManagerService.this) { 1754 if (mFullPssPending) { 1755 mFullPssPending = false; 1756 memInfo = new MemInfoReader(); 1757 } 1758 } 1759 if (memInfo != null) { 1760 updateCpuStatsNow(); 1761 long nativeTotalPss = 0; 1762 synchronized (mProcessCpuTracker) { 1763 final int N = mProcessCpuTracker.countStats(); 1764 for (int j=0; j<N; j++) { 1765 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1766 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1767 // This is definitely an application process; skip it. 1768 continue; 1769 } 1770 synchronized (mPidsSelfLocked) { 1771 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1772 // This is one of our own processes; skip it. 1773 continue; 1774 } 1775 } 1776 nativeTotalPss += Debug.getPss(st.pid, null); 1777 } 1778 } 1779 memInfo.readMemInfo(); 1780 synchronized (ActivityManagerService.this) { 1781 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1782 + (SystemClock.uptimeMillis()-start) + "ms"); 1783 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1784 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1785 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1786 } 1787 } 1788 1789 int i = 0; 1790 int num = 0; 1791 long[] tmp = new long[1]; 1792 do { 1793 ProcessRecord proc; 1794 int procState; 1795 int pid; 1796 synchronized (ActivityManagerService.this) { 1797 if (i >= mPendingPssProcesses.size()) { 1798 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1799 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1800 mPendingPssProcesses.clear(); 1801 return; 1802 } 1803 proc = mPendingPssProcesses.get(i); 1804 procState = proc.pssProcState; 1805 if (proc.thread != null && procState == proc.setProcState) { 1806 pid = proc.pid; 1807 } else { 1808 proc = null; 1809 pid = 0; 1810 } 1811 i++; 1812 } 1813 if (proc != null) { 1814 long pss = Debug.getPss(pid, tmp); 1815 synchronized (ActivityManagerService.this) { 1816 if (proc.thread != null && proc.setProcState == procState 1817 && proc.pid == pid) { 1818 num++; 1819 proc.lastPssTime = SystemClock.uptimeMillis(); 1820 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1821 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1822 + ": " + pss + " lastPss=" + proc.lastPss 1823 + " state=" + ProcessList.makeProcStateString(procState)); 1824 if (proc.initialIdlePss == 0) { 1825 proc.initialIdlePss = pss; 1826 } 1827 proc.lastPss = pss; 1828 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1829 proc.lastCachedPss = pss; 1830 } 1831 } 1832 } 1833 } 1834 } while (true); 1835 } 1836 } 1837 } 1838 }; 1839 1840 public void setSystemProcess() { 1841 try { 1842 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1843 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1844 ServiceManager.addService("meminfo", new MemBinder(this)); 1845 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1846 ServiceManager.addService("dbinfo", new DbBinder(this)); 1847 if (MONITOR_CPU_USAGE) { 1848 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1849 } 1850 ServiceManager.addService("permission", new PermissionController(this)); 1851 1852 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1853 "android", STOCK_PM_FLAGS); 1854 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1855 1856 synchronized (this) { 1857 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1858 app.persistent = true; 1859 app.pid = MY_PID; 1860 app.maxAdj = ProcessList.SYSTEM_ADJ; 1861 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1862 mProcessNames.put(app.processName, app.uid, app); 1863 synchronized (mPidsSelfLocked) { 1864 mPidsSelfLocked.put(app.pid, app); 1865 } 1866 updateLruProcessLocked(app, false, null); 1867 updateOomAdjLocked(); 1868 } 1869 } catch (PackageManager.NameNotFoundException e) { 1870 throw new RuntimeException( 1871 "Unable to find android system package", e); 1872 } 1873 } 1874 1875 public void setWindowManager(WindowManagerService wm) { 1876 mWindowManager = wm; 1877 mStackSupervisor.setWindowManager(wm); 1878 } 1879 1880 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1881 mUsageStatsService = usageStatsManager; 1882 } 1883 1884 public void startObservingNativeCrashes() { 1885 final NativeCrashListener ncl = new NativeCrashListener(this); 1886 ncl.start(); 1887 } 1888 1889 public IAppOpsService getAppOpsService() { 1890 return mAppOpsService; 1891 } 1892 1893 static class MemBinder extends Binder { 1894 ActivityManagerService mActivityManagerService; 1895 MemBinder(ActivityManagerService activityManagerService) { 1896 mActivityManagerService = activityManagerService; 1897 } 1898 1899 @Override 1900 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1901 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1902 != PackageManager.PERMISSION_GRANTED) { 1903 pw.println("Permission Denial: can't dump meminfo from from pid=" 1904 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1905 + " without permission " + android.Manifest.permission.DUMP); 1906 return; 1907 } 1908 1909 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1910 } 1911 } 1912 1913 static class GraphicsBinder extends Binder { 1914 ActivityManagerService mActivityManagerService; 1915 GraphicsBinder(ActivityManagerService activityManagerService) { 1916 mActivityManagerService = activityManagerService; 1917 } 1918 1919 @Override 1920 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1921 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1922 != PackageManager.PERMISSION_GRANTED) { 1923 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1924 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1925 + " without permission " + android.Manifest.permission.DUMP); 1926 return; 1927 } 1928 1929 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1930 } 1931 } 1932 1933 static class DbBinder extends Binder { 1934 ActivityManagerService mActivityManagerService; 1935 DbBinder(ActivityManagerService activityManagerService) { 1936 mActivityManagerService = activityManagerService; 1937 } 1938 1939 @Override 1940 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1941 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1942 != PackageManager.PERMISSION_GRANTED) { 1943 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1944 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1945 + " without permission " + android.Manifest.permission.DUMP); 1946 return; 1947 } 1948 1949 mActivityManagerService.dumpDbInfo(fd, pw, args); 1950 } 1951 } 1952 1953 static class CpuBinder extends Binder { 1954 ActivityManagerService mActivityManagerService; 1955 CpuBinder(ActivityManagerService activityManagerService) { 1956 mActivityManagerService = activityManagerService; 1957 } 1958 1959 @Override 1960 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1961 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1962 != PackageManager.PERMISSION_GRANTED) { 1963 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1964 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1965 + " without permission " + android.Manifest.permission.DUMP); 1966 return; 1967 } 1968 1969 synchronized (mActivityManagerService.mProcessCpuTracker) { 1970 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1971 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1972 SystemClock.uptimeMillis())); 1973 } 1974 } 1975 } 1976 1977 public static final class Lifecycle extends SystemService { 1978 private final ActivityManagerService mService; 1979 1980 public Lifecycle(Context context) { 1981 super(context); 1982 mService = new ActivityManagerService(context); 1983 } 1984 1985 @Override 1986 public void onStart() { 1987 mService.start(); 1988 } 1989 1990 public ActivityManagerService getService() { 1991 return mService; 1992 } 1993 } 1994 1995 // Note: This method is invoked on the main thread but may need to attach various 1996 // handlers to other threads. So take care to be explicit about the looper. 1997 public ActivityManagerService(Context systemContext) { 1998 mContext = systemContext; 1999 mFactoryTest = FactoryTest.getMode(); 2000 mSystemThread = ActivityThread.currentActivityThread(); 2001 2002 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2003 2004 mHandlerThread = new ServiceThread(TAG, 2005 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2006 mHandlerThread.start(); 2007 mHandler = new MainHandler(mHandlerThread.getLooper()); 2008 2009 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2010 "foreground", BROADCAST_FG_TIMEOUT, false); 2011 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2012 "background", BROADCAST_BG_TIMEOUT, true); 2013 mBroadcastQueues[0] = mFgBroadcastQueue; 2014 mBroadcastQueues[1] = mBgBroadcastQueue; 2015 2016 mServices = new ActiveServices(this); 2017 mProviderMap = new ProviderMap(this); 2018 2019 // TODO: Move creation of battery stats service outside of activity manager service. 2020 File dataDir = Environment.getDataDirectory(); 2021 File systemDir = new File(dataDir, "system"); 2022 systemDir.mkdirs(); 2023 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2024 mBatteryStatsService.getActiveStatistics().readLocked(); 2025 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2026 mOnBattery = DEBUG_POWER ? true 2027 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2028 mBatteryStatsService.getActiveStatistics().setCallback(this); 2029 2030 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2031 2032 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2033 2034 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2035 2036 // User 0 is the first and only user that runs at boot. 2037 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2038 mUserLru.add(Integer.valueOf(0)); 2039 updateStartedUserArrayLocked(); 2040 2041 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2042 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2043 2044 mConfiguration.setToDefaults(); 2045 mConfiguration.setLocale(Locale.getDefault()); 2046 2047 mConfigurationSeq = mConfiguration.seq = 1; 2048 mProcessCpuTracker.init(); 2049 2050 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2051 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2052 mStackSupervisor = new ActivityStackSupervisor(this); 2053 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2054 2055 mProcessCpuThread = new Thread("CpuTracker") { 2056 @Override 2057 public void run() { 2058 while (true) { 2059 try { 2060 try { 2061 synchronized(this) { 2062 final long now = SystemClock.uptimeMillis(); 2063 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2064 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2065 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2066 // + ", write delay=" + nextWriteDelay); 2067 if (nextWriteDelay < nextCpuDelay) { 2068 nextCpuDelay = nextWriteDelay; 2069 } 2070 if (nextCpuDelay > 0) { 2071 mProcessCpuMutexFree.set(true); 2072 this.wait(nextCpuDelay); 2073 } 2074 } 2075 } catch (InterruptedException e) { 2076 } 2077 updateCpuStatsNow(); 2078 } catch (Exception e) { 2079 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2080 } 2081 } 2082 } 2083 }; 2084 2085 Watchdog.getInstance().addMonitor(this); 2086 Watchdog.getInstance().addThread(mHandler); 2087 } 2088 2089 public void setSystemServiceManager(SystemServiceManager mgr) { 2090 mSystemServiceManager = mgr; 2091 } 2092 2093 public void setInstaller(Installer installer) { 2094 mInstaller = installer; 2095 } 2096 2097 private void start() { 2098 Process.removeAllProcessGroups(); 2099 mProcessCpuThread.start(); 2100 2101 mBatteryStatsService.publish(mContext); 2102 mAppOpsService.publish(mContext); 2103 Slog.d("AppOps", "AppOpsService published"); 2104 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2105 } 2106 2107 public void initPowerManagement() { 2108 mStackSupervisor.initPowerManagement(); 2109 mBatteryStatsService.initPowerManagement(); 2110 } 2111 2112 @Override 2113 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2114 throws RemoteException { 2115 if (code == SYSPROPS_TRANSACTION) { 2116 // We need to tell all apps about the system property change. 2117 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2118 synchronized(this) { 2119 final int NP = mProcessNames.getMap().size(); 2120 for (int ip=0; ip<NP; ip++) { 2121 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2122 final int NA = apps.size(); 2123 for (int ia=0; ia<NA; ia++) { 2124 ProcessRecord app = apps.valueAt(ia); 2125 if (app.thread != null) { 2126 procs.add(app.thread.asBinder()); 2127 } 2128 } 2129 } 2130 } 2131 2132 int N = procs.size(); 2133 for (int i=0; i<N; i++) { 2134 Parcel data2 = Parcel.obtain(); 2135 try { 2136 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2137 } catch (RemoteException e) { 2138 } 2139 data2.recycle(); 2140 } 2141 } 2142 try { 2143 return super.onTransact(code, data, reply, flags); 2144 } catch (RuntimeException e) { 2145 // The activity manager only throws security exceptions, so let's 2146 // log all others. 2147 if (!(e instanceof SecurityException)) { 2148 Slog.wtf(TAG, "Activity Manager Crash", e); 2149 } 2150 throw e; 2151 } 2152 } 2153 2154 void updateCpuStats() { 2155 final long now = SystemClock.uptimeMillis(); 2156 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2157 return; 2158 } 2159 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2160 synchronized (mProcessCpuThread) { 2161 mProcessCpuThread.notify(); 2162 } 2163 } 2164 } 2165 2166 void updateCpuStatsNow() { 2167 synchronized (mProcessCpuTracker) { 2168 mProcessCpuMutexFree.set(false); 2169 final long now = SystemClock.uptimeMillis(); 2170 boolean haveNewCpuStats = false; 2171 2172 if (MONITOR_CPU_USAGE && 2173 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2174 mLastCpuTime.set(now); 2175 haveNewCpuStats = true; 2176 mProcessCpuTracker.update(); 2177 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2178 //Slog.i(TAG, "Total CPU usage: " 2179 // + mProcessCpu.getTotalCpuPercent() + "%"); 2180 2181 // Slog the cpu usage if the property is set. 2182 if ("true".equals(SystemProperties.get("events.cpu"))) { 2183 int user = mProcessCpuTracker.getLastUserTime(); 2184 int system = mProcessCpuTracker.getLastSystemTime(); 2185 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2186 int irq = mProcessCpuTracker.getLastIrqTime(); 2187 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2188 int idle = mProcessCpuTracker.getLastIdleTime(); 2189 2190 int total = user + system + iowait + irq + softIrq + idle; 2191 if (total == 0) total = 1; 2192 2193 EventLog.writeEvent(EventLogTags.CPU, 2194 ((user+system+iowait+irq+softIrq) * 100) / total, 2195 (user * 100) / total, 2196 (system * 100) / total, 2197 (iowait * 100) / total, 2198 (irq * 100) / total, 2199 (softIrq * 100) / total); 2200 } 2201 } 2202 2203 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2204 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2205 synchronized(bstats) { 2206 synchronized(mPidsSelfLocked) { 2207 if (haveNewCpuStats) { 2208 if (mOnBattery) { 2209 int perc = bstats.startAddingCpuLocked(); 2210 int totalUTime = 0; 2211 int totalSTime = 0; 2212 final int N = mProcessCpuTracker.countStats(); 2213 for (int i=0; i<N; i++) { 2214 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2215 if (!st.working) { 2216 continue; 2217 } 2218 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2219 int otherUTime = (st.rel_utime*perc)/100; 2220 int otherSTime = (st.rel_stime*perc)/100; 2221 totalUTime += otherUTime; 2222 totalSTime += otherSTime; 2223 if (pr != null) { 2224 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2225 if (ps == null || !ps.isActive()) { 2226 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2227 pr.info.uid, pr.processName); 2228 } 2229 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2230 st.rel_stime-otherSTime); 2231 ps.addSpeedStepTimes(cpuSpeedTimes); 2232 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2233 } else { 2234 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2235 if (ps == null || !ps.isActive()) { 2236 st.batteryStats = ps = bstats.getProcessStatsLocked( 2237 bstats.mapUid(st.uid), st.name); 2238 } 2239 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2240 st.rel_stime-otherSTime); 2241 ps.addSpeedStepTimes(cpuSpeedTimes); 2242 } 2243 } 2244 bstats.finishAddingCpuLocked(perc, totalUTime, 2245 totalSTime, cpuSpeedTimes); 2246 } 2247 } 2248 } 2249 2250 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2251 mLastWriteTime = now; 2252 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2253 } 2254 } 2255 } 2256 } 2257 2258 @Override 2259 public void batteryNeedsCpuUpdate() { 2260 updateCpuStatsNow(); 2261 } 2262 2263 @Override 2264 public void batteryPowerChanged(boolean onBattery) { 2265 // When plugging in, update the CPU stats first before changing 2266 // the plug state. 2267 updateCpuStatsNow(); 2268 synchronized (this) { 2269 synchronized(mPidsSelfLocked) { 2270 mOnBattery = DEBUG_POWER ? true : onBattery; 2271 } 2272 } 2273 } 2274 2275 /** 2276 * Initialize the application bind args. These are passed to each 2277 * process when the bindApplication() IPC is sent to the process. They're 2278 * lazily setup to make sure the services are running when they're asked for. 2279 */ 2280 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2281 if (mAppBindArgs == null) { 2282 mAppBindArgs = new HashMap<>(); 2283 2284 // Isolated processes won't get this optimization, so that we don't 2285 // violate the rules about which services they have access to. 2286 if (!isolated) { 2287 // Setup the application init args 2288 mAppBindArgs.put("package", ServiceManager.getService("package")); 2289 mAppBindArgs.put("window", ServiceManager.getService("window")); 2290 mAppBindArgs.put(Context.ALARM_SERVICE, 2291 ServiceManager.getService(Context.ALARM_SERVICE)); 2292 } 2293 } 2294 return mAppBindArgs; 2295 } 2296 2297 final void setFocusedActivityLocked(ActivityRecord r) { 2298 if (mFocusedActivity != r) { 2299 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2300 mFocusedActivity = r; 2301 if (r.task != null && r.task.voiceInteractor != null) { 2302 startRunningVoiceLocked(); 2303 } else { 2304 finishRunningVoiceLocked(); 2305 } 2306 mStackSupervisor.setFocusedStack(r); 2307 if (r != null) { 2308 mWindowManager.setFocusedApp(r.appToken, true); 2309 } 2310 applyUpdateLockStateLocked(r); 2311 } 2312 } 2313 2314 final void clearFocusedActivity(ActivityRecord r) { 2315 if (mFocusedActivity == r) { 2316 mFocusedActivity = null; 2317 } 2318 } 2319 2320 @Override 2321 public void setFocusedStack(int stackId) { 2322 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2323 synchronized (ActivityManagerService.this) { 2324 ActivityStack stack = mStackSupervisor.getStack(stackId); 2325 if (stack != null) { 2326 ActivityRecord r = stack.topRunningActivityLocked(null); 2327 if (r != null) { 2328 setFocusedActivityLocked(r); 2329 } 2330 } 2331 } 2332 } 2333 2334 @Override 2335 public void notifyActivityDrawn(IBinder token) { 2336 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2337 synchronized (this) { 2338 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2339 if (r != null) { 2340 r.task.stack.notifyActivityDrawnLocked(r); 2341 } 2342 } 2343 } 2344 2345 final void applyUpdateLockStateLocked(ActivityRecord r) { 2346 // Modifications to the UpdateLock state are done on our handler, outside 2347 // the activity manager's locks. The new state is determined based on the 2348 // state *now* of the relevant activity record. The object is passed to 2349 // the handler solely for logging detail, not to be consulted/modified. 2350 final boolean nextState = r != null && r.immersive; 2351 mHandler.sendMessage( 2352 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2353 } 2354 2355 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2356 Message msg = Message.obtain(); 2357 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2358 msg.obj = r.task.askedCompatMode ? null : r; 2359 mHandler.sendMessage(msg); 2360 } 2361 2362 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2363 String what, Object obj, ProcessRecord srcApp) { 2364 app.lastActivityTime = now; 2365 2366 if (app.activities.size() > 0) { 2367 // Don't want to touch dependent processes that are hosting activities. 2368 return index; 2369 } 2370 2371 int lrui = mLruProcesses.lastIndexOf(app); 2372 if (lrui < 0) { 2373 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2374 + what + " " + obj + " from " + srcApp); 2375 return index; 2376 } 2377 2378 if (lrui >= index) { 2379 // Don't want to cause this to move dependent processes *back* in the 2380 // list as if they were less frequently used. 2381 return index; 2382 } 2383 2384 if (lrui >= mLruProcessActivityStart) { 2385 // Don't want to touch dependent processes that are hosting activities. 2386 return index; 2387 } 2388 2389 mLruProcesses.remove(lrui); 2390 if (index > 0) { 2391 index--; 2392 } 2393 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2394 + " in LRU list: " + app); 2395 mLruProcesses.add(index, app); 2396 return index; 2397 } 2398 2399 final void removeLruProcessLocked(ProcessRecord app) { 2400 int lrui = mLruProcesses.lastIndexOf(app); 2401 if (lrui >= 0) { 2402 if (!app.killed) { 2403 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2404 Process.killProcessQuiet(app.pid); 2405 Process.killProcessGroup(app.info.uid, app.pid); 2406 } 2407 if (lrui <= mLruProcessActivityStart) { 2408 mLruProcessActivityStart--; 2409 } 2410 if (lrui <= mLruProcessServiceStart) { 2411 mLruProcessServiceStart--; 2412 } 2413 mLruProcesses.remove(lrui); 2414 } 2415 } 2416 2417 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2418 ProcessRecord client) { 2419 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2420 || app.treatLikeActivity; 2421 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2422 if (!activityChange && hasActivity) { 2423 // The process has activities, so we are only allowing activity-based adjustments 2424 // to move it. It should be kept in the front of the list with other 2425 // processes that have activities, and we don't want those to change their 2426 // order except due to activity operations. 2427 return; 2428 } 2429 2430 mLruSeq++; 2431 final long now = SystemClock.uptimeMillis(); 2432 app.lastActivityTime = now; 2433 2434 // First a quick reject: if the app is already at the position we will 2435 // put it, then there is nothing to do. 2436 if (hasActivity) { 2437 final int N = mLruProcesses.size(); 2438 if (N > 0 && mLruProcesses.get(N-1) == app) { 2439 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2440 return; 2441 } 2442 } else { 2443 if (mLruProcessServiceStart > 0 2444 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2445 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2446 return; 2447 } 2448 } 2449 2450 int lrui = mLruProcesses.lastIndexOf(app); 2451 2452 if (app.persistent && lrui >= 0) { 2453 // We don't care about the position of persistent processes, as long as 2454 // they are in the list. 2455 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2456 return; 2457 } 2458 2459 /* In progress: compute new position first, so we can avoid doing work 2460 if the process is not actually going to move. Not yet working. 2461 int addIndex; 2462 int nextIndex; 2463 boolean inActivity = false, inService = false; 2464 if (hasActivity) { 2465 // Process has activities, put it at the very tipsy-top. 2466 addIndex = mLruProcesses.size(); 2467 nextIndex = mLruProcessServiceStart; 2468 inActivity = true; 2469 } else if (hasService) { 2470 // Process has services, put it at the top of the service list. 2471 addIndex = mLruProcessActivityStart; 2472 nextIndex = mLruProcessServiceStart; 2473 inActivity = true; 2474 inService = true; 2475 } else { 2476 // Process not otherwise of interest, it goes to the top of the non-service area. 2477 addIndex = mLruProcessServiceStart; 2478 if (client != null) { 2479 int clientIndex = mLruProcesses.lastIndexOf(client); 2480 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2481 + app); 2482 if (clientIndex >= 0 && addIndex > clientIndex) { 2483 addIndex = clientIndex; 2484 } 2485 } 2486 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2487 } 2488 2489 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2490 + mLruProcessActivityStart + "): " + app); 2491 */ 2492 2493 if (lrui >= 0) { 2494 if (lrui < mLruProcessActivityStart) { 2495 mLruProcessActivityStart--; 2496 } 2497 if (lrui < mLruProcessServiceStart) { 2498 mLruProcessServiceStart--; 2499 } 2500 /* 2501 if (addIndex > lrui) { 2502 addIndex--; 2503 } 2504 if (nextIndex > lrui) { 2505 nextIndex--; 2506 } 2507 */ 2508 mLruProcesses.remove(lrui); 2509 } 2510 2511 /* 2512 mLruProcesses.add(addIndex, app); 2513 if (inActivity) { 2514 mLruProcessActivityStart++; 2515 } 2516 if (inService) { 2517 mLruProcessActivityStart++; 2518 } 2519 */ 2520 2521 int nextIndex; 2522 if (hasActivity) { 2523 final int N = mLruProcesses.size(); 2524 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2525 // Process doesn't have activities, but has clients with 2526 // activities... move it up, but one below the top (the top 2527 // should always have a real activity). 2528 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2529 mLruProcesses.add(N-1, app); 2530 // To keep it from spamming the LRU list (by making a bunch of clients), 2531 // we will push down any other entries owned by the app. 2532 final int uid = app.info.uid; 2533 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2534 ProcessRecord subProc = mLruProcesses.get(i); 2535 if (subProc.info.uid == uid) { 2536 // We want to push this one down the list. If the process after 2537 // it is for the same uid, however, don't do so, because we don't 2538 // want them internally to be re-ordered. 2539 if (mLruProcesses.get(i-1).info.uid != uid) { 2540 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2541 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2542 ProcessRecord tmp = mLruProcesses.get(i); 2543 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2544 mLruProcesses.set(i-1, tmp); 2545 i--; 2546 } 2547 } else { 2548 // A gap, we can stop here. 2549 break; 2550 } 2551 } 2552 } else { 2553 // Process has activities, put it at the very tipsy-top. 2554 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2555 mLruProcesses.add(app); 2556 } 2557 nextIndex = mLruProcessServiceStart; 2558 } else if (hasService) { 2559 // Process has services, put it at the top of the service list. 2560 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2561 mLruProcesses.add(mLruProcessActivityStart, app); 2562 nextIndex = mLruProcessServiceStart; 2563 mLruProcessActivityStart++; 2564 } else { 2565 // Process not otherwise of interest, it goes to the top of the non-service area. 2566 int index = mLruProcessServiceStart; 2567 if (client != null) { 2568 // If there is a client, don't allow the process to be moved up higher 2569 // in the list than that client. 2570 int clientIndex = mLruProcesses.lastIndexOf(client); 2571 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2572 + " when updating " + app); 2573 if (clientIndex <= lrui) { 2574 // Don't allow the client index restriction to push it down farther in the 2575 // list than it already is. 2576 clientIndex = lrui; 2577 } 2578 if (clientIndex >= 0 && index > clientIndex) { 2579 index = clientIndex; 2580 } 2581 } 2582 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2583 mLruProcesses.add(index, app); 2584 nextIndex = index-1; 2585 mLruProcessActivityStart++; 2586 mLruProcessServiceStart++; 2587 } 2588 2589 // If the app is currently using a content provider or service, 2590 // bump those processes as well. 2591 for (int j=app.connections.size()-1; j>=0; j--) { 2592 ConnectionRecord cr = app.connections.valueAt(j); 2593 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2594 && cr.binding.service.app != null 2595 && cr.binding.service.app.lruSeq != mLruSeq 2596 && !cr.binding.service.app.persistent) { 2597 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2598 "service connection", cr, app); 2599 } 2600 } 2601 for (int j=app.conProviders.size()-1; j>=0; j--) { 2602 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2603 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2604 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2605 "provider reference", cpr, app); 2606 } 2607 } 2608 } 2609 2610 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2611 if (uid == Process.SYSTEM_UID) { 2612 // The system gets to run in any process. If there are multiple 2613 // processes with the same uid, just pick the first (this 2614 // should never happen). 2615 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2616 if (procs == null) return null; 2617 final int N = procs.size(); 2618 for (int i = 0; i < N; i++) { 2619 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2620 } 2621 } 2622 ProcessRecord proc = mProcessNames.get(processName, uid); 2623 if (false && proc != null && !keepIfLarge 2624 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2625 && proc.lastCachedPss >= 4000) { 2626 // Turn this condition on to cause killing to happen regularly, for testing. 2627 if (proc.baseProcessTracker != null) { 2628 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2629 } 2630 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2631 } else if (proc != null && !keepIfLarge 2632 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2633 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2634 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2635 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2636 if (proc.baseProcessTracker != null) { 2637 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2638 } 2639 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2640 } 2641 } 2642 return proc; 2643 } 2644 2645 void ensurePackageDexOpt(String packageName) { 2646 IPackageManager pm = AppGlobals.getPackageManager(); 2647 try { 2648 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2649 mDidDexOpt = true; 2650 } 2651 } catch (RemoteException e) { 2652 } 2653 } 2654 2655 boolean isNextTransitionForward() { 2656 int transit = mWindowManager.getPendingAppTransition(); 2657 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2658 || transit == AppTransition.TRANSIT_TASK_OPEN 2659 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2660 } 2661 2662 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2663 String processName, String abiOverride, int uid, Runnable crashHandler) { 2664 synchronized(this) { 2665 ApplicationInfo info = new ApplicationInfo(); 2666 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2667 // For isolated processes, the former contains the parent's uid and the latter the 2668 // actual uid of the isolated process. 2669 // In the special case introduced by this method (which is, starting an isolated 2670 // process directly from the SystemServer without an actual parent app process) the 2671 // closest thing to a parent's uid is SYSTEM_UID. 2672 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2673 // the |isolated| logic in the ProcessRecord constructor. 2674 info.uid = Process.SYSTEM_UID; 2675 info.processName = processName; 2676 info.className = entryPoint; 2677 info.packageName = "android"; 2678 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2679 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2680 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2681 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2682 crashHandler); 2683 return proc != null ? proc.pid : 0; 2684 } 2685 } 2686 2687 final ProcessRecord startProcessLocked(String processName, 2688 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2689 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2690 boolean isolated, boolean keepIfLarge) { 2691 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2692 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2693 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2694 null /* crashHandler */); 2695 } 2696 2697 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2698 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2699 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2700 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2701 long startTime = SystemClock.elapsedRealtime(); 2702 ProcessRecord app; 2703 if (!isolated) { 2704 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2705 checkTime(startTime, "startProcess: after getProcessRecord"); 2706 } else { 2707 // If this is an isolated process, it can't re-use an existing process. 2708 app = null; 2709 } 2710 // We don't have to do anything more if: 2711 // (1) There is an existing application record; and 2712 // (2) The caller doesn't think it is dead, OR there is no thread 2713 // object attached to it so we know it couldn't have crashed; and 2714 // (3) There is a pid assigned to it, so it is either starting or 2715 // already running. 2716 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2717 + " app=" + app + " knownToBeDead=" + knownToBeDead 2718 + " thread=" + (app != null ? app.thread : null) 2719 + " pid=" + (app != null ? app.pid : -1)); 2720 if (app != null && app.pid > 0) { 2721 if (!knownToBeDead || app.thread == null) { 2722 // We already have the app running, or are waiting for it to 2723 // come up (we have a pid but not yet its thread), so keep it. 2724 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2725 // If this is a new package in the process, add the package to the list 2726 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2727 checkTime(startTime, "startProcess: done, added package to proc"); 2728 return app; 2729 } 2730 2731 // An application record is attached to a previous process, 2732 // clean it up now. 2733 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2734 checkTime(startTime, "startProcess: bad proc running, killing"); 2735 Process.killProcessGroup(app.info.uid, app.pid); 2736 handleAppDiedLocked(app, true, true); 2737 checkTime(startTime, "startProcess: done killing old proc"); 2738 } 2739 2740 String hostingNameStr = hostingName != null 2741 ? hostingName.flattenToShortString() : null; 2742 2743 if (!isolated) { 2744 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2745 // If we are in the background, then check to see if this process 2746 // is bad. If so, we will just silently fail. 2747 if (mBadProcesses.get(info.processName, info.uid) != null) { 2748 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2749 + "/" + info.processName); 2750 return null; 2751 } 2752 } else { 2753 // When the user is explicitly starting a process, then clear its 2754 // crash count so that we won't make it bad until they see at 2755 // least one crash dialog again, and make the process good again 2756 // if it had been bad. 2757 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2758 + "/" + info.processName); 2759 mProcessCrashTimes.remove(info.processName, info.uid); 2760 if (mBadProcesses.get(info.processName, info.uid) != null) { 2761 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2762 UserHandle.getUserId(info.uid), info.uid, 2763 info.processName); 2764 mBadProcesses.remove(info.processName, info.uid); 2765 if (app != null) { 2766 app.bad = false; 2767 } 2768 } 2769 } 2770 } 2771 2772 if (app == null) { 2773 checkTime(startTime, "startProcess: creating new process record"); 2774 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2775 app.crashHandler = crashHandler; 2776 if (app == null) { 2777 Slog.w(TAG, "Failed making new process record for " 2778 + processName + "/" + info.uid + " isolated=" + isolated); 2779 return null; 2780 } 2781 mProcessNames.put(processName, app.uid, app); 2782 if (isolated) { 2783 mIsolatedProcesses.put(app.uid, app); 2784 } 2785 checkTime(startTime, "startProcess: done creating new process record"); 2786 } else { 2787 // If this is a new package in the process, add the package to the list 2788 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2789 checkTime(startTime, "startProcess: added package to existing proc"); 2790 } 2791 2792 // If the system is not ready yet, then hold off on starting this 2793 // process until it is. 2794 if (!mProcessesReady 2795 && !isAllowedWhileBooting(info) 2796 && !allowWhileBooting) { 2797 if (!mProcessesOnHold.contains(app)) { 2798 mProcessesOnHold.add(app); 2799 } 2800 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2801 checkTime(startTime, "startProcess: returning with proc on hold"); 2802 return app; 2803 } 2804 2805 checkTime(startTime, "startProcess: stepping in to startProcess"); 2806 startProcessLocked( 2807 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2808 checkTime(startTime, "startProcess: done starting proc!"); 2809 return (app.pid != 0) ? app : null; 2810 } 2811 2812 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2813 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2814 } 2815 2816 private final void startProcessLocked(ProcessRecord app, 2817 String hostingType, String hostingNameStr) { 2818 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2819 null /* entryPoint */, null /* entryPointArgs */); 2820 } 2821 2822 private final void startProcessLocked(ProcessRecord app, String hostingType, 2823 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2824 long startTime = SystemClock.elapsedRealtime(); 2825 if (app.pid > 0 && app.pid != MY_PID) { 2826 checkTime(startTime, "startProcess: removing from pids map"); 2827 synchronized (mPidsSelfLocked) { 2828 mPidsSelfLocked.remove(app.pid); 2829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2830 } 2831 checkTime(startTime, "startProcess: done removing from pids map"); 2832 app.setPid(0); 2833 } 2834 2835 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2836 "startProcessLocked removing on hold: " + app); 2837 mProcessesOnHold.remove(app); 2838 2839 checkTime(startTime, "startProcess: starting to update cpu stats"); 2840 updateCpuStats(); 2841 checkTime(startTime, "startProcess: done updating cpu stats"); 2842 2843 try { 2844 int uid = app.uid; 2845 2846 int[] gids = null; 2847 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2848 if (!app.isolated) { 2849 int[] permGids = null; 2850 try { 2851 checkTime(startTime, "startProcess: getting gids from package manager"); 2852 final PackageManager pm = mContext.getPackageManager(); 2853 permGids = pm.getPackageGids(app.info.packageName); 2854 2855 if (Environment.isExternalStorageEmulated()) { 2856 checkTime(startTime, "startProcess: checking external storage perm"); 2857 if (pm.checkPermission( 2858 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2859 app.info.packageName) == PERMISSION_GRANTED) { 2860 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2861 } else { 2862 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2863 } 2864 } 2865 } catch (PackageManager.NameNotFoundException e) { 2866 Slog.w(TAG, "Unable to retrieve gids", e); 2867 } 2868 2869 /* 2870 * Add shared application and profile GIDs so applications can share some 2871 * resources like shared libraries and access user-wide resources 2872 */ 2873 if (permGids == null) { 2874 gids = new int[2]; 2875 } else { 2876 gids = new int[permGids.length + 2]; 2877 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2878 } 2879 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2880 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2881 } 2882 checkTime(startTime, "startProcess: building args"); 2883 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2884 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2885 && mTopComponent != null 2886 && app.processName.equals(mTopComponent.getPackageName())) { 2887 uid = 0; 2888 } 2889 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2890 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2891 uid = 0; 2892 } 2893 } 2894 int debugFlags = 0; 2895 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2896 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2897 // Also turn on CheckJNI for debuggable apps. It's quite 2898 // awkward to turn on otherwise. 2899 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2900 } 2901 // Run the app in safe mode if its manifest requests so or the 2902 // system is booted in safe mode. 2903 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2904 mSafeMode == true) { 2905 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2906 } 2907 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2908 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2909 } 2910 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2911 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2912 } 2913 if ("1".equals(SystemProperties.get("debug.assert"))) { 2914 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2915 } 2916 2917 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2918 if (requiredAbi == null) { 2919 requiredAbi = Build.SUPPORTED_ABIS[0]; 2920 } 2921 2922 String instructionSet = null; 2923 if (app.info.primaryCpuAbi != null) { 2924 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2925 } 2926 2927 // Start the process. It will either succeed and return a result containing 2928 // the PID of the new process, or else throw a RuntimeException. 2929 boolean isActivityProcess = (entryPoint == null); 2930 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2931 checkTime(startTime, "startProcess: asking zygote to start proc"); 2932 Process.ProcessStartResult startResult = Process.start(entryPoint, 2933 app.processName, uid, uid, gids, debugFlags, mountExternal, 2934 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2935 app.info.dataDir, entryPointArgs); 2936 checkTime(startTime, "startProcess: returned from zygote!"); 2937 2938 if (app.isolated) { 2939 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2940 } 2941 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2942 checkTime(startTime, "startProcess: done updating battery stats"); 2943 2944 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2945 UserHandle.getUserId(uid), startResult.pid, uid, 2946 app.processName, hostingType, 2947 hostingNameStr != null ? hostingNameStr : ""); 2948 2949 if (app.persistent) { 2950 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2951 } 2952 2953 checkTime(startTime, "startProcess: building log message"); 2954 StringBuilder buf = mStringBuilder; 2955 buf.setLength(0); 2956 buf.append("Start proc "); 2957 buf.append(app.processName); 2958 if (!isActivityProcess) { 2959 buf.append(" ["); 2960 buf.append(entryPoint); 2961 buf.append("]"); 2962 } 2963 buf.append(" for "); 2964 buf.append(hostingType); 2965 if (hostingNameStr != null) { 2966 buf.append(" "); 2967 buf.append(hostingNameStr); 2968 } 2969 buf.append(": pid="); 2970 buf.append(startResult.pid); 2971 buf.append(" uid="); 2972 buf.append(uid); 2973 buf.append(" gids={"); 2974 if (gids != null) { 2975 for (int gi=0; gi<gids.length; gi++) { 2976 if (gi != 0) buf.append(", "); 2977 buf.append(gids[gi]); 2978 2979 } 2980 } 2981 buf.append("}"); 2982 if (requiredAbi != null) { 2983 buf.append(" abi="); 2984 buf.append(requiredAbi); 2985 } 2986 Slog.i(TAG, buf.toString()); 2987 app.setPid(startResult.pid); 2988 app.usingWrapper = startResult.usingWrapper; 2989 app.removed = false; 2990 app.killed = false; 2991 app.killedByAm = false; 2992 checkTime(startTime, "startProcess: starting to update pids map"); 2993 synchronized (mPidsSelfLocked) { 2994 this.mPidsSelfLocked.put(startResult.pid, app); 2995 if (isActivityProcess) { 2996 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2997 msg.obj = app; 2998 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2999 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3000 } 3001 } 3002 checkTime(startTime, "startProcess: done updating pids map"); 3003 } catch (RuntimeException e) { 3004 // XXX do better error recovery. 3005 app.setPid(0); 3006 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3007 if (app.isolated) { 3008 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3009 } 3010 Slog.e(TAG, "Failure starting process " + app.processName, e); 3011 } 3012 } 3013 3014 void updateUsageStats(ActivityRecord component, boolean resumed) { 3015 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3016 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3017 if (resumed) { 3018 if (mUsageStatsService != null) { 3019 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3020 UsageEvents.Event.MOVE_TO_FOREGROUND); 3021 } 3022 synchronized (stats) { 3023 stats.noteActivityResumedLocked(component.app.uid); 3024 } 3025 } else { 3026 if (mUsageStatsService != null) { 3027 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3028 UsageEvents.Event.MOVE_TO_BACKGROUND); 3029 } 3030 synchronized (stats) { 3031 stats.noteActivityPausedLocked(component.app.uid); 3032 } 3033 } 3034 } 3035 3036 Intent getHomeIntent() { 3037 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3038 intent.setComponent(mTopComponent); 3039 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3040 intent.addCategory(Intent.CATEGORY_HOME); 3041 } 3042 return intent; 3043 } 3044 3045 boolean startHomeActivityLocked(int userId) { 3046 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3047 && mTopAction == null) { 3048 // We are running in factory test mode, but unable to find 3049 // the factory test app, so just sit around displaying the 3050 // error message and don't try to start anything. 3051 return false; 3052 } 3053 Intent intent = getHomeIntent(); 3054 ActivityInfo aInfo = 3055 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3056 if (aInfo != null) { 3057 intent.setComponent(new ComponentName( 3058 aInfo.applicationInfo.packageName, aInfo.name)); 3059 // Don't do this if the home app is currently being 3060 // instrumented. 3061 aInfo = new ActivityInfo(aInfo); 3062 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3063 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3064 aInfo.applicationInfo.uid, true); 3065 if (app == null || app.instrumentationClass == null) { 3066 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3067 mStackSupervisor.startHomeActivity(intent, aInfo); 3068 } 3069 } 3070 3071 return true; 3072 } 3073 3074 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3075 ActivityInfo ai = null; 3076 ComponentName comp = intent.getComponent(); 3077 try { 3078 if (comp != null) { 3079 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3080 } else { 3081 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3082 intent, 3083 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3084 flags, userId); 3085 3086 if (info != null) { 3087 ai = info.activityInfo; 3088 } 3089 } 3090 } catch (RemoteException e) { 3091 // ignore 3092 } 3093 3094 return ai; 3095 } 3096 3097 /** 3098 * Starts the "new version setup screen" if appropriate. 3099 */ 3100 void startSetupActivityLocked() { 3101 // Only do this once per boot. 3102 if (mCheckedForSetup) { 3103 return; 3104 } 3105 3106 // We will show this screen if the current one is a different 3107 // version than the last one shown, and we are not running in 3108 // low-level factory test mode. 3109 final ContentResolver resolver = mContext.getContentResolver(); 3110 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3111 Settings.Global.getInt(resolver, 3112 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3113 mCheckedForSetup = true; 3114 3115 // See if we should be showing the platform update setup UI. 3116 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3117 List<ResolveInfo> ris = mContext.getPackageManager() 3118 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3119 3120 // We don't allow third party apps to replace this. 3121 ResolveInfo ri = null; 3122 for (int i=0; ris != null && i<ris.size(); i++) { 3123 if ((ris.get(i).activityInfo.applicationInfo.flags 3124 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3125 ri = ris.get(i); 3126 break; 3127 } 3128 } 3129 3130 if (ri != null) { 3131 String vers = ri.activityInfo.metaData != null 3132 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3133 : null; 3134 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3135 vers = ri.activityInfo.applicationInfo.metaData.getString( 3136 Intent.METADATA_SETUP_VERSION); 3137 } 3138 String lastVers = Settings.Secure.getString( 3139 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3140 if (vers != null && !vers.equals(lastVers)) { 3141 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3142 intent.setComponent(new ComponentName( 3143 ri.activityInfo.packageName, ri.activityInfo.name)); 3144 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3145 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3146 null); 3147 } 3148 } 3149 } 3150 } 3151 3152 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3153 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3154 } 3155 3156 void enforceNotIsolatedCaller(String caller) { 3157 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3158 throw new SecurityException("Isolated process not allowed to call " + caller); 3159 } 3160 } 3161 3162 void enforceShellRestriction(String restriction, int userHandle) { 3163 if (Binder.getCallingUid() == Process.SHELL_UID) { 3164 if (userHandle < 0 3165 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3166 throw new SecurityException("Shell does not have permission to access user " 3167 + userHandle); 3168 } 3169 } 3170 } 3171 3172 @Override 3173 public int getFrontActivityScreenCompatMode() { 3174 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3175 synchronized (this) { 3176 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3177 } 3178 } 3179 3180 @Override 3181 public void setFrontActivityScreenCompatMode(int mode) { 3182 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3183 "setFrontActivityScreenCompatMode"); 3184 synchronized (this) { 3185 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3186 } 3187 } 3188 3189 @Override 3190 public int getPackageScreenCompatMode(String packageName) { 3191 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3192 synchronized (this) { 3193 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3194 } 3195 } 3196 3197 @Override 3198 public void setPackageScreenCompatMode(String packageName, int mode) { 3199 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3200 "setPackageScreenCompatMode"); 3201 synchronized (this) { 3202 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3203 } 3204 } 3205 3206 @Override 3207 public boolean getPackageAskScreenCompat(String packageName) { 3208 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3209 synchronized (this) { 3210 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3211 } 3212 } 3213 3214 @Override 3215 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3216 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3217 "setPackageAskScreenCompat"); 3218 synchronized (this) { 3219 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3220 } 3221 } 3222 3223 private void dispatchProcessesChanged() { 3224 int N; 3225 synchronized (this) { 3226 N = mPendingProcessChanges.size(); 3227 if (mActiveProcessChanges.length < N) { 3228 mActiveProcessChanges = new ProcessChangeItem[N]; 3229 } 3230 mPendingProcessChanges.toArray(mActiveProcessChanges); 3231 mAvailProcessChanges.addAll(mPendingProcessChanges); 3232 mPendingProcessChanges.clear(); 3233 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3234 } 3235 3236 int i = mProcessObservers.beginBroadcast(); 3237 while (i > 0) { 3238 i--; 3239 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3240 if (observer != null) { 3241 try { 3242 for (int j=0; j<N; j++) { 3243 ProcessChangeItem item = mActiveProcessChanges[j]; 3244 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3245 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3246 + item.pid + " uid=" + item.uid + ": " 3247 + item.foregroundActivities); 3248 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3249 item.foregroundActivities); 3250 } 3251 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3252 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3253 + item.pid + " uid=" + item.uid + ": " + item.processState); 3254 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3255 } 3256 } 3257 } catch (RemoteException e) { 3258 } 3259 } 3260 } 3261 mProcessObservers.finishBroadcast(); 3262 } 3263 3264 private void dispatchProcessDied(int pid, int uid) { 3265 int i = mProcessObservers.beginBroadcast(); 3266 while (i > 0) { 3267 i--; 3268 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3269 if (observer != null) { 3270 try { 3271 observer.onProcessDied(pid, uid); 3272 } catch (RemoteException e) { 3273 } 3274 } 3275 } 3276 mProcessObservers.finishBroadcast(); 3277 } 3278 3279 @Override 3280 public final int startActivity(IApplicationThread caller, String callingPackage, 3281 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3282 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3283 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3284 resultWho, requestCode, startFlags, profilerInfo, options, 3285 UserHandle.getCallingUserId()); 3286 } 3287 3288 @Override 3289 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3290 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3291 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3292 enforceNotIsolatedCaller("startActivity"); 3293 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3294 false, ALLOW_FULL_ONLY, "startActivity", null); 3295 // TODO: Switch to user app stacks here. 3296 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3297 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3298 profilerInfo, null, null, options, userId, null, null); 3299 } 3300 3301 @Override 3302 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3303 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3304 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3305 3306 // This is very dangerous -- it allows you to perform a start activity (including 3307 // permission grants) as any app that may launch one of your own activities. So 3308 // we will only allow this to be done from activities that are part of the core framework, 3309 // and then only when they are running as the system. 3310 final ActivityRecord sourceRecord; 3311 final int targetUid; 3312 final String targetPackage; 3313 synchronized (this) { 3314 if (resultTo == null) { 3315 throw new SecurityException("Must be called from an activity"); 3316 } 3317 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3318 if (sourceRecord == null) { 3319 throw new SecurityException("Called with bad activity token: " + resultTo); 3320 } 3321 if (!sourceRecord.info.packageName.equals("android")) { 3322 throw new SecurityException( 3323 "Must be called from an activity that is declared in the android package"); 3324 } 3325 if (sourceRecord.app == null) { 3326 throw new SecurityException("Called without a process attached to activity"); 3327 } 3328 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3329 // This is still okay, as long as this activity is running under the 3330 // uid of the original calling activity. 3331 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3332 throw new SecurityException( 3333 "Calling activity in uid " + sourceRecord.app.uid 3334 + " must be system uid or original calling uid " 3335 + sourceRecord.launchedFromUid); 3336 } 3337 } 3338 targetUid = sourceRecord.launchedFromUid; 3339 targetPackage = sourceRecord.launchedFromPackage; 3340 } 3341 3342 if (userId == UserHandle.USER_NULL) { 3343 userId = UserHandle.getUserId(sourceRecord.app.uid); 3344 } 3345 3346 // TODO: Switch to user app stacks here. 3347 try { 3348 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3349 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3350 null, null, options, userId, null, null); 3351 return ret; 3352 } catch (SecurityException e) { 3353 // XXX need to figure out how to propagate to original app. 3354 // A SecurityException here is generally actually a fault of the original 3355 // calling activity (such as a fairly granting permissions), so propagate it 3356 // back to them. 3357 /* 3358 StringBuilder msg = new StringBuilder(); 3359 msg.append("While launching"); 3360 msg.append(intent.toString()); 3361 msg.append(": "); 3362 msg.append(e.getMessage()); 3363 */ 3364 throw e; 3365 } 3366 } 3367 3368 @Override 3369 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3370 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3371 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3372 enforceNotIsolatedCaller("startActivityAndWait"); 3373 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3374 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3375 WaitResult res = new WaitResult(); 3376 // TODO: Switch to user app stacks here. 3377 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3378 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3379 options, userId, null, null); 3380 return res; 3381 } 3382 3383 @Override 3384 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3385 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3386 int startFlags, Configuration config, Bundle options, int userId) { 3387 enforceNotIsolatedCaller("startActivityWithConfig"); 3388 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3389 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3390 // TODO: Switch to user app stacks here. 3391 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3392 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3393 null, null, config, options, userId, null, null); 3394 return ret; 3395 } 3396 3397 @Override 3398 public int startActivityIntentSender(IApplicationThread caller, 3399 IntentSender intent, Intent fillInIntent, String resolvedType, 3400 IBinder resultTo, String resultWho, int requestCode, 3401 int flagsMask, int flagsValues, Bundle options) { 3402 enforceNotIsolatedCaller("startActivityIntentSender"); 3403 // Refuse possible leaked file descriptors 3404 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3405 throw new IllegalArgumentException("File descriptors passed in Intent"); 3406 } 3407 3408 IIntentSender sender = intent.getTarget(); 3409 if (!(sender instanceof PendingIntentRecord)) { 3410 throw new IllegalArgumentException("Bad PendingIntent object"); 3411 } 3412 3413 PendingIntentRecord pir = (PendingIntentRecord)sender; 3414 3415 synchronized (this) { 3416 // If this is coming from the currently resumed activity, it is 3417 // effectively saying that app switches are allowed at this point. 3418 final ActivityStack stack = getFocusedStack(); 3419 if (stack.mResumedActivity != null && 3420 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3421 mAppSwitchesAllowedTime = 0; 3422 } 3423 } 3424 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3425 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3426 return ret; 3427 } 3428 3429 @Override 3430 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3431 Intent intent, String resolvedType, IVoiceInteractionSession session, 3432 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3433 Bundle options, int userId) { 3434 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3435 != PackageManager.PERMISSION_GRANTED) { 3436 String msg = "Permission Denial: startVoiceActivity() from pid=" 3437 + Binder.getCallingPid() 3438 + ", uid=" + Binder.getCallingUid() 3439 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3440 Slog.w(TAG, msg); 3441 throw new SecurityException(msg); 3442 } 3443 if (session == null || interactor == null) { 3444 throw new NullPointerException("null session or interactor"); 3445 } 3446 userId = handleIncomingUser(callingPid, callingUid, userId, 3447 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3448 // TODO: Switch to user app stacks here. 3449 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3450 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3451 null, options, userId, null, null); 3452 } 3453 3454 @Override 3455 public boolean startNextMatchingActivity(IBinder callingActivity, 3456 Intent intent, Bundle options) { 3457 // Refuse possible leaked file descriptors 3458 if (intent != null && intent.hasFileDescriptors() == true) { 3459 throw new IllegalArgumentException("File descriptors passed in Intent"); 3460 } 3461 3462 synchronized (this) { 3463 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3464 if (r == null) { 3465 ActivityOptions.abort(options); 3466 return false; 3467 } 3468 if (r.app == null || r.app.thread == null) { 3469 // The caller is not running... d'oh! 3470 ActivityOptions.abort(options); 3471 return false; 3472 } 3473 intent = new Intent(intent); 3474 // The caller is not allowed to change the data. 3475 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3476 // And we are resetting to find the next component... 3477 intent.setComponent(null); 3478 3479 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3480 3481 ActivityInfo aInfo = null; 3482 try { 3483 List<ResolveInfo> resolves = 3484 AppGlobals.getPackageManager().queryIntentActivities( 3485 intent, r.resolvedType, 3486 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3487 UserHandle.getCallingUserId()); 3488 3489 // Look for the original activity in the list... 3490 final int N = resolves != null ? resolves.size() : 0; 3491 for (int i=0; i<N; i++) { 3492 ResolveInfo rInfo = resolves.get(i); 3493 if (rInfo.activityInfo.packageName.equals(r.packageName) 3494 && rInfo.activityInfo.name.equals(r.info.name)) { 3495 // We found the current one... the next matching is 3496 // after it. 3497 i++; 3498 if (i<N) { 3499 aInfo = resolves.get(i).activityInfo; 3500 } 3501 if (debug) { 3502 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3503 + "/" + r.info.name); 3504 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3505 + "/" + aInfo.name); 3506 } 3507 break; 3508 } 3509 } 3510 } catch (RemoteException e) { 3511 } 3512 3513 if (aInfo == null) { 3514 // Nobody who is next! 3515 ActivityOptions.abort(options); 3516 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3517 return false; 3518 } 3519 3520 intent.setComponent(new ComponentName( 3521 aInfo.applicationInfo.packageName, aInfo.name)); 3522 intent.setFlags(intent.getFlags()&~( 3523 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3524 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3525 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3526 Intent.FLAG_ACTIVITY_NEW_TASK)); 3527 3528 // Okay now we need to start the new activity, replacing the 3529 // currently running activity. This is a little tricky because 3530 // we want to start the new one as if the current one is finished, 3531 // but not finish the current one first so that there is no flicker. 3532 // And thus... 3533 final boolean wasFinishing = r.finishing; 3534 r.finishing = true; 3535 3536 // Propagate reply information over to the new activity. 3537 final ActivityRecord resultTo = r.resultTo; 3538 final String resultWho = r.resultWho; 3539 final int requestCode = r.requestCode; 3540 r.resultTo = null; 3541 if (resultTo != null) { 3542 resultTo.removeResultsLocked(r, resultWho, requestCode); 3543 } 3544 3545 final long origId = Binder.clearCallingIdentity(); 3546 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3547 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3548 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3549 -1, r.launchedFromUid, 0, options, false, null, null, null); 3550 Binder.restoreCallingIdentity(origId); 3551 3552 r.finishing = wasFinishing; 3553 if (res != ActivityManager.START_SUCCESS) { 3554 return false; 3555 } 3556 return true; 3557 } 3558 } 3559 3560 @Override 3561 public final int startActivityFromRecents(int taskId, Bundle options) { 3562 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3563 String msg = "Permission Denial: startActivityFromRecents called without " + 3564 START_TASKS_FROM_RECENTS; 3565 Slog.w(TAG, msg); 3566 throw new SecurityException(msg); 3567 } 3568 return startActivityFromRecentsInner(taskId, options); 3569 } 3570 3571 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3572 final TaskRecord task; 3573 final int callingUid; 3574 final String callingPackage; 3575 final Intent intent; 3576 final int userId; 3577 synchronized (this) { 3578 task = recentTaskForIdLocked(taskId); 3579 if (task == null) { 3580 throw new IllegalArgumentException("Task " + taskId + " not found."); 3581 } 3582 callingUid = task.mCallingUid; 3583 callingPackage = task.mCallingPackage; 3584 intent = task.intent; 3585 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3586 userId = task.userId; 3587 } 3588 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3589 options, userId, null, task); 3590 } 3591 3592 final int startActivityInPackage(int uid, String callingPackage, 3593 Intent intent, String resolvedType, IBinder resultTo, 3594 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3595 IActivityContainer container, TaskRecord inTask) { 3596 3597 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3598 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3599 3600 // TODO: Switch to user app stacks here. 3601 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3602 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3603 null, null, null, options, userId, container, inTask); 3604 return ret; 3605 } 3606 3607 @Override 3608 public final int startActivities(IApplicationThread caller, String callingPackage, 3609 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3610 int userId) { 3611 enforceNotIsolatedCaller("startActivities"); 3612 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3613 false, ALLOW_FULL_ONLY, "startActivity", null); 3614 // TODO: Switch to user app stacks here. 3615 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3616 resolvedTypes, resultTo, options, userId); 3617 return ret; 3618 } 3619 3620 final int startActivitiesInPackage(int uid, String callingPackage, 3621 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3622 Bundle options, int userId) { 3623 3624 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3625 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3626 // TODO: Switch to user app stacks here. 3627 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3628 resultTo, options, userId); 3629 return ret; 3630 } 3631 3632 //explicitly remove thd old information in mRecentTasks when removing existing user. 3633 private void removeRecentTasksForUserLocked(int userId) { 3634 if(userId <= 0) { 3635 Slog.i(TAG, "Can't remove recent task on user " + userId); 3636 return; 3637 } 3638 3639 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3640 TaskRecord tr = mRecentTasks.get(i); 3641 if (tr.userId == userId) { 3642 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3643 + " when finishing user" + userId); 3644 mRecentTasks.remove(i); 3645 tr.removedFromRecents(mTaskPersister); 3646 } 3647 } 3648 3649 // Remove tasks from persistent storage. 3650 mTaskPersister.wakeup(null, true); 3651 } 3652 3653 // Sort by taskId 3654 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3655 @Override 3656 public int compare(TaskRecord lhs, TaskRecord rhs) { 3657 return rhs.taskId - lhs.taskId; 3658 } 3659 }; 3660 3661 // Extract the affiliates of the chain containing mRecentTasks[start]. 3662 private int processNextAffiliateChain(int start) { 3663 final TaskRecord startTask = mRecentTasks.get(start); 3664 final int affiliateId = startTask.mAffiliatedTaskId; 3665 3666 // Quick identification of isolated tasks. I.e. those not launched behind. 3667 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3668 startTask.mNextAffiliate == null) { 3669 // There is still a slim chance that there are other tasks that point to this task 3670 // and that the chain is so messed up that this task no longer points to them but 3671 // the gain of this optimization outweighs the risk. 3672 startTask.inRecents = true; 3673 return start + 1; 3674 } 3675 3676 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3677 mTmpRecents.clear(); 3678 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3679 final TaskRecord task = mRecentTasks.get(i); 3680 if (task.mAffiliatedTaskId == affiliateId) { 3681 mRecentTasks.remove(i); 3682 mTmpRecents.add(task); 3683 } 3684 } 3685 3686 // Sort them all by taskId. That is the order they were create in and that order will 3687 // always be correct. 3688 Collections.sort(mTmpRecents, mTaskRecordComparator); 3689 3690 // Go through and fix up the linked list. 3691 // The first one is the end of the chain and has no next. 3692 final TaskRecord first = mTmpRecents.get(0); 3693 first.inRecents = true; 3694 if (first.mNextAffiliate != null) { 3695 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3696 first.setNextAffiliate(null); 3697 mTaskPersister.wakeup(first, false); 3698 } 3699 // Everything in the middle is doubly linked from next to prev. 3700 final int tmpSize = mTmpRecents.size(); 3701 for (int i = 0; i < tmpSize - 1; ++i) { 3702 final TaskRecord next = mTmpRecents.get(i); 3703 final TaskRecord prev = mTmpRecents.get(i + 1); 3704 if (next.mPrevAffiliate != prev) { 3705 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3706 " setting prev=" + prev); 3707 next.setPrevAffiliate(prev); 3708 mTaskPersister.wakeup(next, false); 3709 } 3710 if (prev.mNextAffiliate != next) { 3711 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3712 " setting next=" + next); 3713 prev.setNextAffiliate(next); 3714 mTaskPersister.wakeup(prev, false); 3715 } 3716 prev.inRecents = true; 3717 } 3718 // The last one is the beginning of the list and has no prev. 3719 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3720 if (last.mPrevAffiliate != null) { 3721 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3722 last.setPrevAffiliate(null); 3723 mTaskPersister.wakeup(last, false); 3724 } 3725 3726 // Insert the group back into mRecentTasks at start. 3727 mRecentTasks.addAll(start, mTmpRecents); 3728 3729 // Let the caller know where we left off. 3730 return start + tmpSize; 3731 } 3732 3733 /** 3734 * Update the recent tasks lists: make sure tasks should still be here (their 3735 * applications / activities still exist), update their availability, fixup ordering 3736 * of affiliations. 3737 */ 3738 void cleanupRecentTasksLocked(int userId) { 3739 if (mRecentTasks == null) { 3740 // Happens when called from the packagemanager broadcast before boot. 3741 return; 3742 } 3743 3744 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3745 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3746 final IPackageManager pm = AppGlobals.getPackageManager(); 3747 final ActivityInfo dummyAct = new ActivityInfo(); 3748 final ApplicationInfo dummyApp = new ApplicationInfo(); 3749 3750 int N = mRecentTasks.size(); 3751 3752 int[] users = userId == UserHandle.USER_ALL 3753 ? getUsersLocked() : new int[] { userId }; 3754 for (int user : users) { 3755 for (int i = 0; i < N; i++) { 3756 TaskRecord task = mRecentTasks.get(i); 3757 if (task.userId != user) { 3758 // Only look at tasks for the user ID of interest. 3759 continue; 3760 } 3761 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3762 // This situation is broken, and we should just get rid of it now. 3763 mRecentTasks.remove(i); 3764 task.removedFromRecents(mTaskPersister); 3765 i--; 3766 N--; 3767 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3768 continue; 3769 } 3770 // Check whether this activity is currently available. 3771 if (task.realActivity != null) { 3772 ActivityInfo ai = availActCache.get(task.realActivity); 3773 if (ai == null) { 3774 try { 3775 ai = pm.getActivityInfo(task.realActivity, 3776 PackageManager.GET_UNINSTALLED_PACKAGES 3777 | PackageManager.GET_DISABLED_COMPONENTS, user); 3778 } catch (RemoteException e) { 3779 // Will never happen. 3780 continue; 3781 } 3782 if (ai == null) { 3783 ai = dummyAct; 3784 } 3785 availActCache.put(task.realActivity, ai); 3786 } 3787 if (ai == dummyAct) { 3788 // This could be either because the activity no longer exists, or the 3789 // app is temporarily gone. For the former we want to remove the recents 3790 // entry; for the latter we want to mark it as unavailable. 3791 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3792 if (app == null) { 3793 try { 3794 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3795 PackageManager.GET_UNINSTALLED_PACKAGES 3796 | PackageManager.GET_DISABLED_COMPONENTS, user); 3797 } catch (RemoteException e) { 3798 // Will never happen. 3799 continue; 3800 } 3801 if (app == null) { 3802 app = dummyApp; 3803 } 3804 availAppCache.put(task.realActivity.getPackageName(), app); 3805 } 3806 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3807 // Doesn't exist any more! Good-bye. 3808 mRecentTasks.remove(i); 3809 task.removedFromRecents(mTaskPersister); 3810 i--; 3811 N--; 3812 Slog.w(TAG, "Removing no longer valid recent: " + task); 3813 continue; 3814 } else { 3815 // Otherwise just not available for now. 3816 if (task.isAvailable) { 3817 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3818 + task); 3819 } 3820 task.isAvailable = false; 3821 } 3822 } else { 3823 if (!ai.enabled || !ai.applicationInfo.enabled 3824 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3825 if (task.isAvailable) { 3826 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3827 + task + " (enabled=" + ai.enabled + "/" 3828 + ai.applicationInfo.enabled + " flags=" 3829 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3830 } 3831 task.isAvailable = false; 3832 } else { 3833 if (!task.isAvailable) { 3834 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3835 + task); 3836 } 3837 task.isAvailable = true; 3838 } 3839 } 3840 } 3841 } 3842 } 3843 3844 // Verify the affiliate chain for each task. 3845 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3846 } 3847 3848 mTmpRecents.clear(); 3849 // mRecentTasks is now in sorted, affiliated order. 3850 } 3851 3852 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3853 int N = mRecentTasks.size(); 3854 TaskRecord top = task; 3855 int topIndex = taskIndex; 3856 while (top.mNextAffiliate != null && topIndex > 0) { 3857 top = top.mNextAffiliate; 3858 topIndex--; 3859 } 3860 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3861 + topIndex + " from intial " + taskIndex); 3862 // Find the end of the chain, doing a sanity check along the way. 3863 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3864 int endIndex = topIndex; 3865 TaskRecord prev = top; 3866 while (endIndex < N) { 3867 TaskRecord cur = mRecentTasks.get(endIndex); 3868 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3869 + endIndex + " " + cur); 3870 if (cur == top) { 3871 // Verify start of the chain. 3872 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3873 Slog.wtf(TAG, "Bad chain @" + endIndex 3874 + ": first task has next affiliate: " + prev); 3875 sane = false; 3876 break; 3877 } 3878 } else { 3879 // Verify middle of the chain's next points back to the one before. 3880 if (cur.mNextAffiliate != prev 3881 || cur.mNextAffiliateTaskId != prev.taskId) { 3882 Slog.wtf(TAG, "Bad chain @" + endIndex 3883 + ": middle task " + cur + " @" + endIndex 3884 + " has bad next affiliate " 3885 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3886 + ", expected " + prev); 3887 sane = false; 3888 break; 3889 } 3890 } 3891 if (cur.mPrevAffiliateTaskId == -1) { 3892 // Chain ends here. 3893 if (cur.mPrevAffiliate != null) { 3894 Slog.wtf(TAG, "Bad chain @" + endIndex 3895 + ": last task " + cur + " has previous affiliate " 3896 + cur.mPrevAffiliate); 3897 sane = false; 3898 } 3899 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3900 break; 3901 } else { 3902 // Verify middle of the chain's prev points to a valid item. 3903 if (cur.mPrevAffiliate == null) { 3904 Slog.wtf(TAG, "Bad chain @" + endIndex 3905 + ": task " + cur + " has previous affiliate " 3906 + cur.mPrevAffiliate + " but should be id " 3907 + cur.mPrevAffiliate); 3908 sane = false; 3909 break; 3910 } 3911 } 3912 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3913 Slog.wtf(TAG, "Bad chain @" + endIndex 3914 + ": task " + cur + " has affiliated id " 3915 + cur.mAffiliatedTaskId + " but should be " 3916 + task.mAffiliatedTaskId); 3917 sane = false; 3918 break; 3919 } 3920 prev = cur; 3921 endIndex++; 3922 if (endIndex >= N) { 3923 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3924 + ": last task " + prev); 3925 sane = false; 3926 break; 3927 } 3928 } 3929 if (sane) { 3930 if (endIndex < taskIndex) { 3931 Slog.wtf(TAG, "Bad chain @" + endIndex 3932 + ": did not extend to task " + task + " @" + taskIndex); 3933 sane = false; 3934 } 3935 } 3936 if (sane) { 3937 // All looks good, we can just move all of the affiliated tasks 3938 // to the top. 3939 for (int i=topIndex; i<=endIndex; i++) { 3940 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3941 + " from " + i + " to " + (i-topIndex)); 3942 TaskRecord cur = mRecentTasks.remove(i); 3943 mRecentTasks.add(i-topIndex, cur); 3944 } 3945 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3946 + " to " + endIndex); 3947 return true; 3948 } 3949 3950 // Whoops, couldn't do it. 3951 return false; 3952 } 3953 3954 final void addRecentTaskLocked(TaskRecord task) { 3955 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3956 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3957 3958 int N = mRecentTasks.size(); 3959 // Quick case: check if the top-most recent task is the same. 3960 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3961 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 3962 return; 3963 } 3964 // Another quick case: check if this is part of a set of affiliated 3965 // tasks that are at the top. 3966 if (isAffiliated && N > 0 && task.inRecents 3967 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 3968 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 3969 + " at top when adding " + task); 3970 return; 3971 } 3972 // Another quick case: never add voice sessions. 3973 if (task.voiceSession != null) { 3974 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 3975 return; 3976 } 3977 3978 boolean needAffiliationFix = false; 3979 3980 // Slightly less quick case: the task is already in recents, so all we need 3981 // to do is move it. 3982 if (task.inRecents) { 3983 int taskIndex = mRecentTasks.indexOf(task); 3984 if (taskIndex >= 0) { 3985 if (!isAffiliated) { 3986 // Simple case: this is not an affiliated task, so we just move it to the front. 3987 mRecentTasks.remove(taskIndex); 3988 mRecentTasks.add(0, task); 3989 notifyTaskPersisterLocked(task, false); 3990 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 3991 + " from " + taskIndex); 3992 return; 3993 } else { 3994 // More complicated: need to keep all affiliated tasks together. 3995 if (moveAffiliatedTasksToFront(task, taskIndex)) { 3996 // All went well. 3997 return; 3998 } 3999 4000 // Uh oh... something bad in the affiliation chain, try to rebuild 4001 // everything and then go through our general path of adding a new task. 4002 needAffiliationFix = true; 4003 } 4004 } else { 4005 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4006 needAffiliationFix = true; 4007 } 4008 } 4009 4010 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4011 trimRecentsForTask(task, true); 4012 4013 N = mRecentTasks.size(); 4014 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4015 final TaskRecord tr = mRecentTasks.remove(N - 1); 4016 tr.removedFromRecents(mTaskPersister); 4017 N--; 4018 } 4019 task.inRecents = true; 4020 if (!isAffiliated || needAffiliationFix) { 4021 // If this is a simple non-affiliated task, or we had some failure trying to 4022 // handle it as part of an affilated task, then just place it at the top. 4023 mRecentTasks.add(0, task); 4024 } else if (isAffiliated) { 4025 // If this is a new affiliated task, then move all of the affiliated tasks 4026 // to the front and insert this new one. 4027 TaskRecord other = task.mNextAffiliate; 4028 if (other == null) { 4029 other = task.mPrevAffiliate; 4030 } 4031 if (other != null) { 4032 int otherIndex = mRecentTasks.indexOf(other); 4033 if (otherIndex >= 0) { 4034 // Insert new task at appropriate location. 4035 int taskIndex; 4036 if (other == task.mNextAffiliate) { 4037 // We found the index of our next affiliation, which is who is 4038 // before us in the list, so add after that point. 4039 taskIndex = otherIndex+1; 4040 } else { 4041 // We found the index of our previous affiliation, which is who is 4042 // after us in the list, so add at their position. 4043 taskIndex = otherIndex; 4044 } 4045 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4046 + taskIndex + ": " + task); 4047 mRecentTasks.add(taskIndex, task); 4048 4049 // Now move everything to the front. 4050 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4051 // All went well. 4052 return; 4053 } 4054 4055 // Uh oh... something bad in the affiliation chain, try to rebuild 4056 // everything and then go through our general path of adding a new task. 4057 needAffiliationFix = true; 4058 } else { 4059 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4060 + other); 4061 needAffiliationFix = true; 4062 } 4063 } else { 4064 if (DEBUG_RECENTS) Slog.d(TAG, 4065 "addRecent: adding affiliated task without next/prev:" + task); 4066 needAffiliationFix = true; 4067 } 4068 } 4069 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4070 4071 if (needAffiliationFix) { 4072 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4073 cleanupRecentTasksLocked(task.userId); 4074 } 4075 } 4076 4077 /** 4078 * If needed, remove oldest existing entries in recents that are for the same kind 4079 * of task as the given one. 4080 */ 4081 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4082 int N = mRecentTasks.size(); 4083 final Intent intent = task.intent; 4084 final boolean document = intent != null && intent.isDocument(); 4085 4086 int maxRecents = task.maxRecents - 1; 4087 for (int i=0; i<N; i++) { 4088 final TaskRecord tr = mRecentTasks.get(i); 4089 if (task != tr) { 4090 if (task.userId != tr.userId) { 4091 continue; 4092 } 4093 if (i > MAX_RECENT_BITMAPS) { 4094 tr.freeLastThumbnail(); 4095 } 4096 final Intent trIntent = tr.intent; 4097 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4098 (intent == null || !intent.filterEquals(trIntent))) { 4099 continue; 4100 } 4101 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4102 if (document && trIsDocument) { 4103 // These are the same document activity (not necessarily the same doc). 4104 if (maxRecents > 0) { 4105 --maxRecents; 4106 continue; 4107 } 4108 // Hit the maximum number of documents for this task. Fall through 4109 // and remove this document from recents. 4110 } else if (document || trIsDocument) { 4111 // Only one of these is a document. Not the droid we're looking for. 4112 continue; 4113 } 4114 } 4115 4116 if (!doTrim) { 4117 // If the caller is not actually asking for a trim, just tell them we reached 4118 // a point where the trim would happen. 4119 return i; 4120 } 4121 4122 // Either task and tr are the same or, their affinities match or their intents match 4123 // and neither of them is a document, or they are documents using the same activity 4124 // and their maxRecents has been reached. 4125 tr.disposeThumbnail(); 4126 mRecentTasks.remove(i); 4127 if (task != tr) { 4128 tr.removedFromRecents(mTaskPersister); 4129 } 4130 i--; 4131 N--; 4132 if (task.intent == null) { 4133 // If the new recent task we are adding is not fully 4134 // specified, then replace it with the existing recent task. 4135 task = tr; 4136 } 4137 notifyTaskPersisterLocked(tr, false); 4138 } 4139 4140 return -1; 4141 } 4142 4143 @Override 4144 public void reportActivityFullyDrawn(IBinder token) { 4145 synchronized (this) { 4146 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4147 if (r == null) { 4148 return; 4149 } 4150 r.reportFullyDrawnLocked(); 4151 } 4152 } 4153 4154 @Override 4155 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4156 synchronized (this) { 4157 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4158 if (r == null) { 4159 return; 4160 } 4161 final long origId = Binder.clearCallingIdentity(); 4162 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4163 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4164 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4165 if (config != null) { 4166 r.frozenBeforeDestroy = true; 4167 if (!updateConfigurationLocked(config, r, false, false)) { 4168 mStackSupervisor.resumeTopActivitiesLocked(); 4169 } 4170 } 4171 Binder.restoreCallingIdentity(origId); 4172 } 4173 } 4174 4175 @Override 4176 public int getRequestedOrientation(IBinder token) { 4177 synchronized (this) { 4178 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4179 if (r == null) { 4180 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4181 } 4182 return mWindowManager.getAppOrientation(r.appToken); 4183 } 4184 } 4185 4186 /** 4187 * This is the internal entry point for handling Activity.finish(). 4188 * 4189 * @param token The Binder token referencing the Activity we want to finish. 4190 * @param resultCode Result code, if any, from this Activity. 4191 * @param resultData Result data (Intent), if any, from this Activity. 4192 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4193 * the root Activity in the task. 4194 * 4195 * @return Returns true if the activity successfully finished, or false if it is still running. 4196 */ 4197 @Override 4198 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4199 boolean finishTask) { 4200 // Refuse possible leaked file descriptors 4201 if (resultData != null && resultData.hasFileDescriptors() == true) { 4202 throw new IllegalArgumentException("File descriptors passed in Intent"); 4203 } 4204 4205 synchronized(this) { 4206 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4207 if (r == null) { 4208 return true; 4209 } 4210 // Keep track of the root activity of the task before we finish it 4211 TaskRecord tr = r.task; 4212 ActivityRecord rootR = tr.getRootActivity(); 4213 if (rootR == null) { 4214 Slog.w(TAG, "Finishing task with all activities already finished"); 4215 } 4216 // Do not allow task to finish in Lock Task mode. 4217 if (tr == mStackSupervisor.mLockTaskModeTask) { 4218 if (rootR == r) { 4219 Slog.i(TAG, "Not finishing task in lock task mode"); 4220 mStackSupervisor.showLockTaskToast(); 4221 return false; 4222 } 4223 } 4224 if (mController != null) { 4225 // Find the first activity that is not finishing. 4226 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4227 if (next != null) { 4228 // ask watcher if this is allowed 4229 boolean resumeOK = true; 4230 try { 4231 resumeOK = mController.activityResuming(next.packageName); 4232 } catch (RemoteException e) { 4233 mController = null; 4234 Watchdog.getInstance().setActivityController(null); 4235 } 4236 4237 if (!resumeOK) { 4238 Slog.i(TAG, "Not finishing activity because controller resumed"); 4239 return false; 4240 } 4241 } 4242 } 4243 final long origId = Binder.clearCallingIdentity(); 4244 try { 4245 boolean res; 4246 if (finishTask && r == rootR) { 4247 // If requested, remove the task that is associated to this activity only if it 4248 // was the root activity in the task. The result code and data is ignored 4249 // because we don't support returning them across task boundaries. 4250 res = removeTaskByIdLocked(tr.taskId, false); 4251 if (!res) { 4252 Slog.i(TAG, "Removing task failed to finish activity"); 4253 } 4254 } else { 4255 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4256 resultData, "app-request", true); 4257 if (!res) { 4258 Slog.i(TAG, "Failed to finish by app-request"); 4259 } 4260 } 4261 return res; 4262 } finally { 4263 Binder.restoreCallingIdentity(origId); 4264 } 4265 } 4266 } 4267 4268 @Override 4269 public final void finishHeavyWeightApp() { 4270 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4271 != PackageManager.PERMISSION_GRANTED) { 4272 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4273 + Binder.getCallingPid() 4274 + ", uid=" + Binder.getCallingUid() 4275 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4276 Slog.w(TAG, msg); 4277 throw new SecurityException(msg); 4278 } 4279 4280 synchronized(this) { 4281 if (mHeavyWeightProcess == null) { 4282 return; 4283 } 4284 4285 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4286 mHeavyWeightProcess.activities); 4287 for (int i=0; i<activities.size(); i++) { 4288 ActivityRecord r = activities.get(i); 4289 if (!r.finishing) { 4290 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4291 null, "finish-heavy", true); 4292 } 4293 } 4294 4295 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4296 mHeavyWeightProcess.userId, 0)); 4297 mHeavyWeightProcess = null; 4298 } 4299 } 4300 4301 @Override 4302 public void crashApplication(int uid, int initialPid, String packageName, 4303 String message) { 4304 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4305 != PackageManager.PERMISSION_GRANTED) { 4306 String msg = "Permission Denial: crashApplication() from pid=" 4307 + Binder.getCallingPid() 4308 + ", uid=" + Binder.getCallingUid() 4309 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4310 Slog.w(TAG, msg); 4311 throw new SecurityException(msg); 4312 } 4313 4314 synchronized(this) { 4315 ProcessRecord proc = null; 4316 4317 // Figure out which process to kill. We don't trust that initialPid 4318 // still has any relation to current pids, so must scan through the 4319 // list. 4320 synchronized (mPidsSelfLocked) { 4321 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4322 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4323 if (p.uid != uid) { 4324 continue; 4325 } 4326 if (p.pid == initialPid) { 4327 proc = p; 4328 break; 4329 } 4330 if (p.pkgList.containsKey(packageName)) { 4331 proc = p; 4332 } 4333 } 4334 } 4335 4336 if (proc == null) { 4337 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4338 + " initialPid=" + initialPid 4339 + " packageName=" + packageName); 4340 return; 4341 } 4342 4343 if (proc.thread != null) { 4344 if (proc.pid == Process.myPid()) { 4345 Log.w(TAG, "crashApplication: trying to crash self!"); 4346 return; 4347 } 4348 long ident = Binder.clearCallingIdentity(); 4349 try { 4350 proc.thread.scheduleCrash(message); 4351 } catch (RemoteException e) { 4352 } 4353 Binder.restoreCallingIdentity(ident); 4354 } 4355 } 4356 } 4357 4358 @Override 4359 public final void finishSubActivity(IBinder token, String resultWho, 4360 int requestCode) { 4361 synchronized(this) { 4362 final long origId = Binder.clearCallingIdentity(); 4363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4364 if (r != null) { 4365 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4366 } 4367 Binder.restoreCallingIdentity(origId); 4368 } 4369 } 4370 4371 @Override 4372 public boolean finishActivityAffinity(IBinder token) { 4373 synchronized(this) { 4374 final long origId = Binder.clearCallingIdentity(); 4375 try { 4376 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4377 4378 ActivityRecord rootR = r.task.getRootActivity(); 4379 // Do not allow task to finish in Lock Task mode. 4380 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4381 if (rootR == r) { 4382 mStackSupervisor.showLockTaskToast(); 4383 return false; 4384 } 4385 } 4386 boolean res = false; 4387 if (r != null) { 4388 res = r.task.stack.finishActivityAffinityLocked(r); 4389 } 4390 return res; 4391 } finally { 4392 Binder.restoreCallingIdentity(origId); 4393 } 4394 } 4395 } 4396 4397 @Override 4398 public void finishVoiceTask(IVoiceInteractionSession session) { 4399 synchronized(this) { 4400 final long origId = Binder.clearCallingIdentity(); 4401 try { 4402 mStackSupervisor.finishVoiceTask(session); 4403 } finally { 4404 Binder.restoreCallingIdentity(origId); 4405 } 4406 } 4407 4408 } 4409 4410 @Override 4411 public boolean releaseActivityInstance(IBinder token) { 4412 synchronized(this) { 4413 final long origId = Binder.clearCallingIdentity(); 4414 try { 4415 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4416 if (r.task == null || r.task.stack == null) { 4417 return false; 4418 } 4419 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4420 } finally { 4421 Binder.restoreCallingIdentity(origId); 4422 } 4423 } 4424 } 4425 4426 @Override 4427 public void releaseSomeActivities(IApplicationThread appInt) { 4428 synchronized(this) { 4429 final long origId = Binder.clearCallingIdentity(); 4430 try { 4431 ProcessRecord app = getRecordForAppLocked(appInt); 4432 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4433 } finally { 4434 Binder.restoreCallingIdentity(origId); 4435 } 4436 } 4437 } 4438 4439 @Override 4440 public boolean willActivityBeVisible(IBinder token) { 4441 synchronized(this) { 4442 ActivityStack stack = ActivityRecord.getStackLocked(token); 4443 if (stack != null) { 4444 return stack.willActivityBeVisibleLocked(token); 4445 } 4446 return false; 4447 } 4448 } 4449 4450 @Override 4451 public void overridePendingTransition(IBinder token, String packageName, 4452 int enterAnim, int exitAnim) { 4453 synchronized(this) { 4454 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4455 if (self == null) { 4456 return; 4457 } 4458 4459 final long origId = Binder.clearCallingIdentity(); 4460 4461 if (self.state == ActivityState.RESUMED 4462 || self.state == ActivityState.PAUSING) { 4463 mWindowManager.overridePendingAppTransition(packageName, 4464 enterAnim, exitAnim, null); 4465 } 4466 4467 Binder.restoreCallingIdentity(origId); 4468 } 4469 } 4470 4471 /** 4472 * Main function for removing an existing process from the activity manager 4473 * as a result of that process going away. Clears out all connections 4474 * to the process. 4475 */ 4476 private final void handleAppDiedLocked(ProcessRecord app, 4477 boolean restarting, boolean allowRestart) { 4478 int pid = app.pid; 4479 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4480 if (!kept && !restarting) { 4481 removeLruProcessLocked(app); 4482 if (pid > 0) { 4483 ProcessList.remove(pid); 4484 } 4485 } 4486 4487 if (mProfileProc == app) { 4488 clearProfilerLocked(); 4489 } 4490 4491 // Remove this application's activities from active lists. 4492 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4493 4494 app.activities.clear(); 4495 4496 if (app.instrumentationClass != null) { 4497 Slog.w(TAG, "Crash of app " + app.processName 4498 + " running instrumentation " + app.instrumentationClass); 4499 Bundle info = new Bundle(); 4500 info.putString("shortMsg", "Process crashed."); 4501 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4502 } 4503 4504 if (!restarting) { 4505 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4506 // If there was nothing to resume, and we are not already 4507 // restarting this process, but there is a visible activity that 4508 // is hosted by the process... then make sure all visible 4509 // activities are running, taking care of restarting this 4510 // process. 4511 if (hasVisibleActivities) { 4512 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4513 } 4514 } 4515 } 4516 } 4517 4518 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4519 IBinder threadBinder = thread.asBinder(); 4520 // Find the application record. 4521 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4522 ProcessRecord rec = mLruProcesses.get(i); 4523 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4524 return i; 4525 } 4526 } 4527 return -1; 4528 } 4529 4530 final ProcessRecord getRecordForAppLocked( 4531 IApplicationThread thread) { 4532 if (thread == null) { 4533 return null; 4534 } 4535 4536 int appIndex = getLRURecordIndexForAppLocked(thread); 4537 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4538 } 4539 4540 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4541 // If there are no longer any background processes running, 4542 // and the app that died was not running instrumentation, 4543 // then tell everyone we are now low on memory. 4544 boolean haveBg = false; 4545 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4546 ProcessRecord rec = mLruProcesses.get(i); 4547 if (rec.thread != null 4548 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4549 haveBg = true; 4550 break; 4551 } 4552 } 4553 4554 if (!haveBg) { 4555 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4556 if (doReport) { 4557 long now = SystemClock.uptimeMillis(); 4558 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4559 doReport = false; 4560 } else { 4561 mLastMemUsageReportTime = now; 4562 } 4563 } 4564 final ArrayList<ProcessMemInfo> memInfos 4565 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4566 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4567 long now = SystemClock.uptimeMillis(); 4568 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4569 ProcessRecord rec = mLruProcesses.get(i); 4570 if (rec == dyingProc || rec.thread == null) { 4571 continue; 4572 } 4573 if (doReport) { 4574 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4575 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4576 } 4577 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4578 // The low memory report is overriding any current 4579 // state for a GC request. Make sure to do 4580 // heavy/important/visible/foreground processes first. 4581 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4582 rec.lastRequestedGc = 0; 4583 } else { 4584 rec.lastRequestedGc = rec.lastLowMemory; 4585 } 4586 rec.reportLowMemory = true; 4587 rec.lastLowMemory = now; 4588 mProcessesToGc.remove(rec); 4589 addProcessToGcListLocked(rec); 4590 } 4591 } 4592 if (doReport) { 4593 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4594 mHandler.sendMessage(msg); 4595 } 4596 scheduleAppGcsLocked(); 4597 } 4598 } 4599 4600 final void appDiedLocked(ProcessRecord app) { 4601 appDiedLocked(app, app.pid, app.thread); 4602 } 4603 4604 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4605 // First check if this ProcessRecord is actually active for the pid. 4606 synchronized (mPidsSelfLocked) { 4607 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4608 if (curProc != app) { 4609 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4610 return; 4611 } 4612 } 4613 4614 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4615 synchronized (stats) { 4616 stats.noteProcessDiedLocked(app.info.uid, pid); 4617 } 4618 4619 Process.killProcessQuiet(pid); 4620 Process.killProcessGroup(app.info.uid, pid); 4621 app.killed = true; 4622 4623 // Clean up already done if the process has been re-started. 4624 if (app.pid == pid && app.thread != null && 4625 app.thread.asBinder() == thread.asBinder()) { 4626 boolean doLowMem = app.instrumentationClass == null; 4627 boolean doOomAdj = doLowMem; 4628 if (!app.killedByAm) { 4629 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4630 + ") has died"); 4631 mAllowLowerMemLevel = true; 4632 } else { 4633 // Note that we always want to do oom adj to update our state with the 4634 // new number of procs. 4635 mAllowLowerMemLevel = false; 4636 doLowMem = false; 4637 } 4638 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4639 if (DEBUG_CLEANUP) Slog.v( 4640 TAG, "Dying app: " + app + ", pid: " + pid 4641 + ", thread: " + thread.asBinder()); 4642 handleAppDiedLocked(app, false, true); 4643 4644 if (doOomAdj) { 4645 updateOomAdjLocked(); 4646 } 4647 if (doLowMem) { 4648 doLowMemReportIfNeededLocked(app); 4649 } 4650 } else if (app.pid != pid) { 4651 // A new process has already been started. 4652 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4653 + ") has died and restarted (pid " + app.pid + ")."); 4654 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4655 } else if (DEBUG_PROCESSES) { 4656 Slog.d(TAG, "Received spurious death notification for thread " 4657 + thread.asBinder()); 4658 } 4659 } 4660 4661 /** 4662 * If a stack trace dump file is configured, dump process stack traces. 4663 * @param clearTraces causes the dump file to be erased prior to the new 4664 * traces being written, if true; when false, the new traces will be 4665 * appended to any existing file content. 4666 * @param firstPids of dalvik VM processes to dump stack traces for first 4667 * @param lastPids of dalvik VM processes to dump stack traces for last 4668 * @param nativeProcs optional list of native process names to dump stack crawls 4669 * @return file containing stack traces, or null if no dump file is configured 4670 */ 4671 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4672 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4673 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4674 if (tracesPath == null || tracesPath.length() == 0) { 4675 return null; 4676 } 4677 4678 File tracesFile = new File(tracesPath); 4679 try { 4680 File tracesDir = tracesFile.getParentFile(); 4681 if (!tracesDir.exists()) { 4682 tracesDir.mkdirs(); 4683 if (!SELinux.restorecon(tracesDir)) { 4684 return null; 4685 } 4686 } 4687 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4688 4689 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4690 tracesFile.createNewFile(); 4691 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4692 } catch (IOException e) { 4693 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4694 return null; 4695 } 4696 4697 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4698 return tracesFile; 4699 } 4700 4701 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4702 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4703 // Use a FileObserver to detect when traces finish writing. 4704 // The order of traces is considered important to maintain for legibility. 4705 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4706 @Override 4707 public synchronized void onEvent(int event, String path) { notify(); } 4708 }; 4709 4710 try { 4711 observer.startWatching(); 4712 4713 // First collect all of the stacks of the most important pids. 4714 if (firstPids != null) { 4715 try { 4716 int num = firstPids.size(); 4717 for (int i = 0; i < num; i++) { 4718 synchronized (observer) { 4719 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4720 observer.wait(200); // Wait for write-close, give up after 200msec 4721 } 4722 } 4723 } catch (InterruptedException e) { 4724 Slog.wtf(TAG, e); 4725 } 4726 } 4727 4728 // Next collect the stacks of the native pids 4729 if (nativeProcs != null) { 4730 int[] pids = Process.getPidsForCommands(nativeProcs); 4731 if (pids != null) { 4732 for (int pid : pids) { 4733 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4734 } 4735 } 4736 } 4737 4738 // Lastly, measure CPU usage. 4739 if (processCpuTracker != null) { 4740 processCpuTracker.init(); 4741 System.gc(); 4742 processCpuTracker.update(); 4743 try { 4744 synchronized (processCpuTracker) { 4745 processCpuTracker.wait(500); // measure over 1/2 second. 4746 } 4747 } catch (InterruptedException e) { 4748 } 4749 processCpuTracker.update(); 4750 4751 // We'll take the stack crawls of just the top apps using CPU. 4752 final int N = processCpuTracker.countWorkingStats(); 4753 int numProcs = 0; 4754 for (int i=0; i<N && numProcs<5; i++) { 4755 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4756 if (lastPids.indexOfKey(stats.pid) >= 0) { 4757 numProcs++; 4758 try { 4759 synchronized (observer) { 4760 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4761 observer.wait(200); // Wait for write-close, give up after 200msec 4762 } 4763 } catch (InterruptedException e) { 4764 Slog.wtf(TAG, e); 4765 } 4766 4767 } 4768 } 4769 } 4770 } finally { 4771 observer.stopWatching(); 4772 } 4773 } 4774 4775 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4776 if (true || IS_USER_BUILD) { 4777 return; 4778 } 4779 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4780 if (tracesPath == null || tracesPath.length() == 0) { 4781 return; 4782 } 4783 4784 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4785 StrictMode.allowThreadDiskWrites(); 4786 try { 4787 final File tracesFile = new File(tracesPath); 4788 final File tracesDir = tracesFile.getParentFile(); 4789 final File tracesTmp = new File(tracesDir, "__tmp__"); 4790 try { 4791 if (!tracesDir.exists()) { 4792 tracesDir.mkdirs(); 4793 if (!SELinux.restorecon(tracesDir.getPath())) { 4794 return; 4795 } 4796 } 4797 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4798 4799 if (tracesFile.exists()) { 4800 tracesTmp.delete(); 4801 tracesFile.renameTo(tracesTmp); 4802 } 4803 StringBuilder sb = new StringBuilder(); 4804 Time tobj = new Time(); 4805 tobj.set(System.currentTimeMillis()); 4806 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4807 sb.append(": "); 4808 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4809 sb.append(" since "); 4810 sb.append(msg); 4811 FileOutputStream fos = new FileOutputStream(tracesFile); 4812 fos.write(sb.toString().getBytes()); 4813 if (app == null) { 4814 fos.write("\n*** No application process!".getBytes()); 4815 } 4816 fos.close(); 4817 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4818 } catch (IOException e) { 4819 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4820 return; 4821 } 4822 4823 if (app != null) { 4824 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4825 firstPids.add(app.pid); 4826 dumpStackTraces(tracesPath, firstPids, null, null, null); 4827 } 4828 4829 File lastTracesFile = null; 4830 File curTracesFile = null; 4831 for (int i=9; i>=0; i--) { 4832 String name = String.format(Locale.US, "slow%02d.txt", i); 4833 curTracesFile = new File(tracesDir, name); 4834 if (curTracesFile.exists()) { 4835 if (lastTracesFile != null) { 4836 curTracesFile.renameTo(lastTracesFile); 4837 } else { 4838 curTracesFile.delete(); 4839 } 4840 } 4841 lastTracesFile = curTracesFile; 4842 } 4843 tracesFile.renameTo(curTracesFile); 4844 if (tracesTmp.exists()) { 4845 tracesTmp.renameTo(tracesFile); 4846 } 4847 } finally { 4848 StrictMode.setThreadPolicy(oldPolicy); 4849 } 4850 } 4851 4852 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4853 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4854 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4855 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4856 4857 if (mController != null) { 4858 try { 4859 // 0 == continue, -1 = kill process immediately 4860 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4861 if (res < 0 && app.pid != MY_PID) { 4862 app.kill("anr", true); 4863 } 4864 } catch (RemoteException e) { 4865 mController = null; 4866 Watchdog.getInstance().setActivityController(null); 4867 } 4868 } 4869 4870 long anrTime = SystemClock.uptimeMillis(); 4871 if (MONITOR_CPU_USAGE) { 4872 updateCpuStatsNow(); 4873 } 4874 4875 synchronized (this) { 4876 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4877 if (mShuttingDown) { 4878 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4879 return; 4880 } else if (app.notResponding) { 4881 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4882 return; 4883 } else if (app.crashing) { 4884 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4885 return; 4886 } 4887 4888 // In case we come through here for the same app before completing 4889 // this one, mark as anring now so we will bail out. 4890 app.notResponding = true; 4891 4892 // Log the ANR to the event log. 4893 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4894 app.processName, app.info.flags, annotation); 4895 4896 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4897 firstPids.add(app.pid); 4898 4899 int parentPid = app.pid; 4900 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4901 if (parentPid != app.pid) firstPids.add(parentPid); 4902 4903 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4904 4905 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4906 ProcessRecord r = mLruProcesses.get(i); 4907 if (r != null && r.thread != null) { 4908 int pid = r.pid; 4909 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4910 if (r.persistent) { 4911 firstPids.add(pid); 4912 } else { 4913 lastPids.put(pid, Boolean.TRUE); 4914 } 4915 } 4916 } 4917 } 4918 } 4919 4920 // Log the ANR to the main log. 4921 StringBuilder info = new StringBuilder(); 4922 info.setLength(0); 4923 info.append("ANR in ").append(app.processName); 4924 if (activity != null && activity.shortComponentName != null) { 4925 info.append(" (").append(activity.shortComponentName).append(")"); 4926 } 4927 info.append("\n"); 4928 info.append("PID: ").append(app.pid).append("\n"); 4929 if (annotation != null) { 4930 info.append("Reason: ").append(annotation).append("\n"); 4931 } 4932 if (parent != null && parent != activity) { 4933 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4934 } 4935 4936 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4937 4938 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4939 NATIVE_STACKS_OF_INTEREST); 4940 4941 String cpuInfo = null; 4942 if (MONITOR_CPU_USAGE) { 4943 updateCpuStatsNow(); 4944 synchronized (mProcessCpuTracker) { 4945 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4946 } 4947 info.append(processCpuTracker.printCurrentLoad()); 4948 info.append(cpuInfo); 4949 } 4950 4951 info.append(processCpuTracker.printCurrentState(anrTime)); 4952 4953 Slog.e(TAG, info.toString()); 4954 if (tracesFile == null) { 4955 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4956 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4957 } 4958 4959 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4960 cpuInfo, tracesFile, null); 4961 4962 if (mController != null) { 4963 try { 4964 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4965 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4966 if (res != 0) { 4967 if (res < 0 && app.pid != MY_PID) { 4968 app.kill("anr", true); 4969 } else { 4970 synchronized (this) { 4971 mServices.scheduleServiceTimeoutLocked(app); 4972 } 4973 } 4974 return; 4975 } 4976 } catch (RemoteException e) { 4977 mController = null; 4978 Watchdog.getInstance().setActivityController(null); 4979 } 4980 } 4981 4982 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4983 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4984 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4985 4986 synchronized (this) { 4987 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4988 app.kill("bg anr", true); 4989 return; 4990 } 4991 4992 // Set the app's notResponding state, and look up the errorReportReceiver 4993 makeAppNotRespondingLocked(app, 4994 activity != null ? activity.shortComponentName : null, 4995 annotation != null ? "ANR " + annotation : "ANR", 4996 info.toString()); 4997 4998 // Bring up the infamous App Not Responding dialog 4999 Message msg = Message.obtain(); 5000 HashMap<String, Object> map = new HashMap<String, Object>(); 5001 msg.what = SHOW_NOT_RESPONDING_MSG; 5002 msg.obj = map; 5003 msg.arg1 = aboveSystem ? 1 : 0; 5004 map.put("app", app); 5005 if (activity != null) { 5006 map.put("activity", activity); 5007 } 5008 5009 mHandler.sendMessage(msg); 5010 } 5011 } 5012 5013 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5014 if (!mLaunchWarningShown) { 5015 mLaunchWarningShown = true; 5016 mHandler.post(new Runnable() { 5017 @Override 5018 public void run() { 5019 synchronized (ActivityManagerService.this) { 5020 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5021 d.show(); 5022 mHandler.postDelayed(new Runnable() { 5023 @Override 5024 public void run() { 5025 synchronized (ActivityManagerService.this) { 5026 d.dismiss(); 5027 mLaunchWarningShown = false; 5028 } 5029 } 5030 }, 4000); 5031 } 5032 } 5033 }); 5034 } 5035 } 5036 5037 @Override 5038 public boolean clearApplicationUserData(final String packageName, 5039 final IPackageDataObserver observer, int userId) { 5040 enforceNotIsolatedCaller("clearApplicationUserData"); 5041 int uid = Binder.getCallingUid(); 5042 int pid = Binder.getCallingPid(); 5043 userId = handleIncomingUser(pid, uid, 5044 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5045 long callingId = Binder.clearCallingIdentity(); 5046 try { 5047 IPackageManager pm = AppGlobals.getPackageManager(); 5048 int pkgUid = -1; 5049 synchronized(this) { 5050 try { 5051 pkgUid = pm.getPackageUid(packageName, userId); 5052 } catch (RemoteException e) { 5053 } 5054 if (pkgUid == -1) { 5055 Slog.w(TAG, "Invalid packageName: " + packageName); 5056 if (observer != null) { 5057 try { 5058 observer.onRemoveCompleted(packageName, false); 5059 } catch (RemoteException e) { 5060 Slog.i(TAG, "Observer no longer exists."); 5061 } 5062 } 5063 return false; 5064 } 5065 if (uid == pkgUid || checkComponentPermission( 5066 android.Manifest.permission.CLEAR_APP_USER_DATA, 5067 pid, uid, -1, true) 5068 == PackageManager.PERMISSION_GRANTED) { 5069 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5070 } else { 5071 throw new SecurityException("PID " + pid + " does not have permission " 5072 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5073 + " of package " + packageName); 5074 } 5075 5076 // Remove all tasks match the cleared application package and user 5077 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5078 final TaskRecord tr = mRecentTasks.get(i); 5079 final String taskPackageName = 5080 tr.getBaseIntent().getComponent().getPackageName(); 5081 if (tr.userId != userId) continue; 5082 if (!taskPackageName.equals(packageName)) continue; 5083 removeTaskByIdLocked(tr.taskId, false); 5084 } 5085 } 5086 5087 try { 5088 // Clear application user data 5089 pm.clearApplicationUserData(packageName, observer, userId); 5090 5091 synchronized(this) { 5092 // Remove all permissions granted from/to this package 5093 removeUriPermissionsForPackageLocked(packageName, userId, true); 5094 } 5095 5096 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5097 Uri.fromParts("package", packageName, null)); 5098 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5099 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5100 null, null, 0, null, null, null, false, false, userId); 5101 } catch (RemoteException e) { 5102 } 5103 } finally { 5104 Binder.restoreCallingIdentity(callingId); 5105 } 5106 return true; 5107 } 5108 5109 @Override 5110 public void killBackgroundProcesses(final String packageName, int userId) { 5111 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5112 != PackageManager.PERMISSION_GRANTED && 5113 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5114 != PackageManager.PERMISSION_GRANTED) { 5115 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5116 + Binder.getCallingPid() 5117 + ", uid=" + Binder.getCallingUid() 5118 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5119 Slog.w(TAG, msg); 5120 throw new SecurityException(msg); 5121 } 5122 5123 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5124 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5125 long callingId = Binder.clearCallingIdentity(); 5126 try { 5127 IPackageManager pm = AppGlobals.getPackageManager(); 5128 synchronized(this) { 5129 int appId = -1; 5130 try { 5131 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5132 } catch (RemoteException e) { 5133 } 5134 if (appId == -1) { 5135 Slog.w(TAG, "Invalid packageName: " + packageName); 5136 return; 5137 } 5138 killPackageProcessesLocked(packageName, appId, userId, 5139 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5140 } 5141 } finally { 5142 Binder.restoreCallingIdentity(callingId); 5143 } 5144 } 5145 5146 @Override 5147 public void killAllBackgroundProcesses() { 5148 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5149 != PackageManager.PERMISSION_GRANTED) { 5150 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5151 + Binder.getCallingPid() 5152 + ", uid=" + Binder.getCallingUid() 5153 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5154 Slog.w(TAG, msg); 5155 throw new SecurityException(msg); 5156 } 5157 5158 long callingId = Binder.clearCallingIdentity(); 5159 try { 5160 synchronized(this) { 5161 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5162 final int NP = mProcessNames.getMap().size(); 5163 for (int ip=0; ip<NP; ip++) { 5164 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5165 final int NA = apps.size(); 5166 for (int ia=0; ia<NA; ia++) { 5167 ProcessRecord app = apps.valueAt(ia); 5168 if (app.persistent) { 5169 // we don't kill persistent processes 5170 continue; 5171 } 5172 if (app.removed) { 5173 procs.add(app); 5174 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5175 app.removed = true; 5176 procs.add(app); 5177 } 5178 } 5179 } 5180 5181 int N = procs.size(); 5182 for (int i=0; i<N; i++) { 5183 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5184 } 5185 mAllowLowerMemLevel = true; 5186 updateOomAdjLocked(); 5187 doLowMemReportIfNeededLocked(null); 5188 } 5189 } finally { 5190 Binder.restoreCallingIdentity(callingId); 5191 } 5192 } 5193 5194 @Override 5195 public void forceStopPackage(final String packageName, int userId) { 5196 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5197 != PackageManager.PERMISSION_GRANTED) { 5198 String msg = "Permission Denial: forceStopPackage() from pid=" 5199 + Binder.getCallingPid() 5200 + ", uid=" + Binder.getCallingUid() 5201 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5202 Slog.w(TAG, msg); 5203 throw new SecurityException(msg); 5204 } 5205 final int callingPid = Binder.getCallingPid(); 5206 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5207 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5208 long callingId = Binder.clearCallingIdentity(); 5209 try { 5210 IPackageManager pm = AppGlobals.getPackageManager(); 5211 synchronized(this) { 5212 int[] users = userId == UserHandle.USER_ALL 5213 ? getUsersLocked() : new int[] { userId }; 5214 for (int user : users) { 5215 int pkgUid = -1; 5216 try { 5217 pkgUid = pm.getPackageUid(packageName, user); 5218 } catch (RemoteException e) { 5219 } 5220 if (pkgUid == -1) { 5221 Slog.w(TAG, "Invalid packageName: " + packageName); 5222 continue; 5223 } 5224 try { 5225 pm.setPackageStoppedState(packageName, true, user); 5226 } catch (RemoteException e) { 5227 } catch (IllegalArgumentException e) { 5228 Slog.w(TAG, "Failed trying to unstop package " 5229 + packageName + ": " + e); 5230 } 5231 if (isUserRunningLocked(user, false)) { 5232 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5233 } 5234 } 5235 } 5236 } finally { 5237 Binder.restoreCallingIdentity(callingId); 5238 } 5239 } 5240 5241 @Override 5242 public void addPackageDependency(String packageName) { 5243 synchronized (this) { 5244 int callingPid = Binder.getCallingPid(); 5245 if (callingPid == Process.myPid()) { 5246 // Yeah, um, no. 5247 Slog.w(TAG, "Can't addPackageDependency on system process"); 5248 return; 5249 } 5250 ProcessRecord proc; 5251 synchronized (mPidsSelfLocked) { 5252 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5253 } 5254 if (proc != null) { 5255 if (proc.pkgDeps == null) { 5256 proc.pkgDeps = new ArraySet<String>(1); 5257 } 5258 proc.pkgDeps.add(packageName); 5259 } 5260 } 5261 } 5262 5263 /* 5264 * The pkg name and app id have to be specified. 5265 */ 5266 @Override 5267 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5268 if (pkg == null) { 5269 return; 5270 } 5271 // Make sure the uid is valid. 5272 if (appid < 0) { 5273 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5274 return; 5275 } 5276 int callerUid = Binder.getCallingUid(); 5277 // Only the system server can kill an application 5278 if (callerUid == Process.SYSTEM_UID) { 5279 // Post an aysnc message to kill the application 5280 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5281 msg.arg1 = appid; 5282 msg.arg2 = 0; 5283 Bundle bundle = new Bundle(); 5284 bundle.putString("pkg", pkg); 5285 bundle.putString("reason", reason); 5286 msg.obj = bundle; 5287 mHandler.sendMessage(msg); 5288 } else { 5289 throw new SecurityException(callerUid + " cannot kill pkg: " + 5290 pkg); 5291 } 5292 } 5293 5294 @Override 5295 public void closeSystemDialogs(String reason) { 5296 enforceNotIsolatedCaller("closeSystemDialogs"); 5297 5298 final int pid = Binder.getCallingPid(); 5299 final int uid = Binder.getCallingUid(); 5300 final long origId = Binder.clearCallingIdentity(); 5301 try { 5302 synchronized (this) { 5303 // Only allow this from foreground processes, so that background 5304 // applications can't abuse it to prevent system UI from being shown. 5305 if (uid >= Process.FIRST_APPLICATION_UID) { 5306 ProcessRecord proc; 5307 synchronized (mPidsSelfLocked) { 5308 proc = mPidsSelfLocked.get(pid); 5309 } 5310 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5311 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5312 + " from background process " + proc); 5313 return; 5314 } 5315 } 5316 closeSystemDialogsLocked(reason); 5317 } 5318 } finally { 5319 Binder.restoreCallingIdentity(origId); 5320 } 5321 } 5322 5323 void closeSystemDialogsLocked(String reason) { 5324 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5325 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5326 | Intent.FLAG_RECEIVER_FOREGROUND); 5327 if (reason != null) { 5328 intent.putExtra("reason", reason); 5329 } 5330 mWindowManager.closeSystemDialogs(reason); 5331 5332 mStackSupervisor.closeSystemDialogsLocked(); 5333 5334 broadcastIntentLocked(null, null, intent, null, 5335 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5336 Process.SYSTEM_UID, UserHandle.USER_ALL); 5337 } 5338 5339 @Override 5340 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5341 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5342 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5343 for (int i=pids.length-1; i>=0; i--) { 5344 ProcessRecord proc; 5345 int oomAdj; 5346 synchronized (this) { 5347 synchronized (mPidsSelfLocked) { 5348 proc = mPidsSelfLocked.get(pids[i]); 5349 oomAdj = proc != null ? proc.setAdj : 0; 5350 } 5351 } 5352 infos[i] = new Debug.MemoryInfo(); 5353 Debug.getMemoryInfo(pids[i], infos[i]); 5354 if (proc != null) { 5355 synchronized (this) { 5356 if (proc.thread != null && proc.setAdj == oomAdj) { 5357 // Record this for posterity if the process has been stable. 5358 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5359 infos[i].getTotalUss(), false, proc.pkgList); 5360 } 5361 } 5362 } 5363 } 5364 return infos; 5365 } 5366 5367 @Override 5368 public long[] getProcessPss(int[] pids) { 5369 enforceNotIsolatedCaller("getProcessPss"); 5370 long[] pss = new long[pids.length]; 5371 for (int i=pids.length-1; i>=0; i--) { 5372 ProcessRecord proc; 5373 int oomAdj; 5374 synchronized (this) { 5375 synchronized (mPidsSelfLocked) { 5376 proc = mPidsSelfLocked.get(pids[i]); 5377 oomAdj = proc != null ? proc.setAdj : 0; 5378 } 5379 } 5380 long[] tmpUss = new long[1]; 5381 pss[i] = Debug.getPss(pids[i], tmpUss); 5382 if (proc != null) { 5383 synchronized (this) { 5384 if (proc.thread != null && proc.setAdj == oomAdj) { 5385 // Record this for posterity if the process has been stable. 5386 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5387 } 5388 } 5389 } 5390 } 5391 return pss; 5392 } 5393 5394 @Override 5395 public void killApplicationProcess(String processName, int uid) { 5396 if (processName == null) { 5397 return; 5398 } 5399 5400 int callerUid = Binder.getCallingUid(); 5401 // Only the system server can kill an application 5402 if (callerUid == Process.SYSTEM_UID) { 5403 synchronized (this) { 5404 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5405 if (app != null && app.thread != null) { 5406 try { 5407 app.thread.scheduleSuicide(); 5408 } catch (RemoteException e) { 5409 // If the other end already died, then our work here is done. 5410 } 5411 } else { 5412 Slog.w(TAG, "Process/uid not found attempting kill of " 5413 + processName + " / " + uid); 5414 } 5415 } 5416 } else { 5417 throw new SecurityException(callerUid + " cannot kill app process: " + 5418 processName); 5419 } 5420 } 5421 5422 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5423 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5424 false, true, false, false, UserHandle.getUserId(uid), reason); 5425 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5426 Uri.fromParts("package", packageName, null)); 5427 if (!mProcessesReady) { 5428 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5429 | Intent.FLAG_RECEIVER_FOREGROUND); 5430 } 5431 intent.putExtra(Intent.EXTRA_UID, uid); 5432 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5433 broadcastIntentLocked(null, null, intent, 5434 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5435 false, false, 5436 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5437 } 5438 5439 private void forceStopUserLocked(int userId, String reason) { 5440 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5441 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5442 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5443 | Intent.FLAG_RECEIVER_FOREGROUND); 5444 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5445 broadcastIntentLocked(null, null, intent, 5446 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5447 false, false, 5448 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5449 } 5450 5451 private final boolean killPackageProcessesLocked(String packageName, int appId, 5452 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5453 boolean doit, boolean evenPersistent, String reason) { 5454 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5455 5456 // Remove all processes this package may have touched: all with the 5457 // same UID (except for the system or root user), and all whose name 5458 // matches the package name. 5459 final int NP = mProcessNames.getMap().size(); 5460 for (int ip=0; ip<NP; ip++) { 5461 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5462 final int NA = apps.size(); 5463 for (int ia=0; ia<NA; ia++) { 5464 ProcessRecord app = apps.valueAt(ia); 5465 if (app.persistent && !evenPersistent) { 5466 // we don't kill persistent processes 5467 continue; 5468 } 5469 if (app.removed) { 5470 if (doit) { 5471 procs.add(app); 5472 } 5473 continue; 5474 } 5475 5476 // Skip process if it doesn't meet our oom adj requirement. 5477 if (app.setAdj < minOomAdj) { 5478 continue; 5479 } 5480 5481 // If no package is specified, we call all processes under the 5482 // give user id. 5483 if (packageName == null) { 5484 if (app.userId != userId) { 5485 continue; 5486 } 5487 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5488 continue; 5489 } 5490 // Package has been specified, we want to hit all processes 5491 // that match it. We need to qualify this by the processes 5492 // that are running under the specified app and user ID. 5493 } else { 5494 final boolean isDep = app.pkgDeps != null 5495 && app.pkgDeps.contains(packageName); 5496 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5497 continue; 5498 } 5499 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5500 continue; 5501 } 5502 if (!app.pkgList.containsKey(packageName) && !isDep) { 5503 continue; 5504 } 5505 } 5506 5507 // Process has passed all conditions, kill it! 5508 if (!doit) { 5509 return true; 5510 } 5511 app.removed = true; 5512 procs.add(app); 5513 } 5514 } 5515 5516 int N = procs.size(); 5517 for (int i=0; i<N; i++) { 5518 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5519 } 5520 updateOomAdjLocked(); 5521 return N > 0; 5522 } 5523 5524 private final boolean forceStopPackageLocked(String name, int appId, 5525 boolean callerWillRestart, boolean purgeCache, boolean doit, 5526 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5527 int i; 5528 int N; 5529 5530 if (userId == UserHandle.USER_ALL && name == null) { 5531 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5532 } 5533 5534 if (appId < 0 && name != null) { 5535 try { 5536 appId = UserHandle.getAppId( 5537 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5538 } catch (RemoteException e) { 5539 } 5540 } 5541 5542 if (doit) { 5543 if (name != null) { 5544 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5545 + " user=" + userId + ": " + reason); 5546 } else { 5547 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5548 } 5549 5550 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5551 for (int ip=pmap.size()-1; ip>=0; ip--) { 5552 SparseArray<Long> ba = pmap.valueAt(ip); 5553 for (i=ba.size()-1; i>=0; i--) { 5554 boolean remove = false; 5555 final int entUid = ba.keyAt(i); 5556 if (name != null) { 5557 if (userId == UserHandle.USER_ALL) { 5558 if (UserHandle.getAppId(entUid) == appId) { 5559 remove = true; 5560 } 5561 } else { 5562 if (entUid == UserHandle.getUid(userId, appId)) { 5563 remove = true; 5564 } 5565 } 5566 } else if (UserHandle.getUserId(entUid) == userId) { 5567 remove = true; 5568 } 5569 if (remove) { 5570 ba.removeAt(i); 5571 } 5572 } 5573 if (ba.size() == 0) { 5574 pmap.removeAt(ip); 5575 } 5576 } 5577 } 5578 5579 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5580 -100, callerWillRestart, true, doit, evenPersistent, 5581 name == null ? ("stop user " + userId) : ("stop " + name)); 5582 5583 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5584 if (!doit) { 5585 return true; 5586 } 5587 didSomething = true; 5588 } 5589 5590 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5591 if (!doit) { 5592 return true; 5593 } 5594 didSomething = true; 5595 } 5596 5597 if (name == null) { 5598 // Remove all sticky broadcasts from this user. 5599 mStickyBroadcasts.remove(userId); 5600 } 5601 5602 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5603 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5604 userId, providers)) { 5605 if (!doit) { 5606 return true; 5607 } 5608 didSomething = true; 5609 } 5610 N = providers.size(); 5611 for (i=0; i<N; i++) { 5612 removeDyingProviderLocked(null, providers.get(i), true); 5613 } 5614 5615 // Remove transient permissions granted from/to this package/user 5616 removeUriPermissionsForPackageLocked(name, userId, false); 5617 5618 if (name == null || uninstalling) { 5619 // Remove pending intents. For now we only do this when force 5620 // stopping users, because we have some problems when doing this 5621 // for packages -- app widgets are not currently cleaned up for 5622 // such packages, so they can be left with bad pending intents. 5623 if (mIntentSenderRecords.size() > 0) { 5624 Iterator<WeakReference<PendingIntentRecord>> it 5625 = mIntentSenderRecords.values().iterator(); 5626 while (it.hasNext()) { 5627 WeakReference<PendingIntentRecord> wpir = it.next(); 5628 if (wpir == null) { 5629 it.remove(); 5630 continue; 5631 } 5632 PendingIntentRecord pir = wpir.get(); 5633 if (pir == null) { 5634 it.remove(); 5635 continue; 5636 } 5637 if (name == null) { 5638 // Stopping user, remove all objects for the user. 5639 if (pir.key.userId != userId) { 5640 // Not the same user, skip it. 5641 continue; 5642 } 5643 } else { 5644 if (UserHandle.getAppId(pir.uid) != appId) { 5645 // Different app id, skip it. 5646 continue; 5647 } 5648 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5649 // Different user, skip it. 5650 continue; 5651 } 5652 if (!pir.key.packageName.equals(name)) { 5653 // Different package, skip it. 5654 continue; 5655 } 5656 } 5657 if (!doit) { 5658 return true; 5659 } 5660 didSomething = true; 5661 it.remove(); 5662 pir.canceled = true; 5663 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5664 pir.key.activity.pendingResults.remove(pir.ref); 5665 } 5666 } 5667 } 5668 } 5669 5670 if (doit) { 5671 if (purgeCache && name != null) { 5672 AttributeCache ac = AttributeCache.instance(); 5673 if (ac != null) { 5674 ac.removePackage(name); 5675 } 5676 } 5677 if (mBooted) { 5678 mStackSupervisor.resumeTopActivitiesLocked(); 5679 mStackSupervisor.scheduleIdleLocked(); 5680 } 5681 } 5682 5683 return didSomething; 5684 } 5685 5686 private final boolean removeProcessLocked(ProcessRecord app, 5687 boolean callerWillRestart, boolean allowRestart, String reason) { 5688 final String name = app.processName; 5689 final int uid = app.uid; 5690 if (DEBUG_PROCESSES) Slog.d( 5691 TAG, "Force removing proc " + app.toShortString() + " (" + name 5692 + "/" + uid + ")"); 5693 5694 mProcessNames.remove(name, uid); 5695 mIsolatedProcesses.remove(app.uid); 5696 if (mHeavyWeightProcess == app) { 5697 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5698 mHeavyWeightProcess.userId, 0)); 5699 mHeavyWeightProcess = null; 5700 } 5701 boolean needRestart = false; 5702 if (app.pid > 0 && app.pid != MY_PID) { 5703 int pid = app.pid; 5704 synchronized (mPidsSelfLocked) { 5705 mPidsSelfLocked.remove(pid); 5706 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5707 } 5708 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5709 if (app.isolated) { 5710 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5711 } 5712 app.kill(reason, true); 5713 handleAppDiedLocked(app, true, allowRestart); 5714 removeLruProcessLocked(app); 5715 5716 if (app.persistent && !app.isolated) { 5717 if (!callerWillRestart) { 5718 addAppLocked(app.info, false, null /* ABI override */); 5719 } else { 5720 needRestart = true; 5721 } 5722 } 5723 } else { 5724 mRemovedProcesses.add(app); 5725 } 5726 5727 return needRestart; 5728 } 5729 5730 private final void processStartTimedOutLocked(ProcessRecord app) { 5731 final int pid = app.pid; 5732 boolean gone = false; 5733 synchronized (mPidsSelfLocked) { 5734 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5735 if (knownApp != null && knownApp.thread == null) { 5736 mPidsSelfLocked.remove(pid); 5737 gone = true; 5738 } 5739 } 5740 5741 if (gone) { 5742 Slog.w(TAG, "Process " + app + " failed to attach"); 5743 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5744 pid, app.uid, app.processName); 5745 mProcessNames.remove(app.processName, app.uid); 5746 mIsolatedProcesses.remove(app.uid); 5747 if (mHeavyWeightProcess == app) { 5748 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5749 mHeavyWeightProcess.userId, 0)); 5750 mHeavyWeightProcess = null; 5751 } 5752 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5753 if (app.isolated) { 5754 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5755 } 5756 // Take care of any launching providers waiting for this process. 5757 checkAppInLaunchingProvidersLocked(app, true); 5758 // Take care of any services that are waiting for the process. 5759 mServices.processStartTimedOutLocked(app); 5760 app.kill("start timeout", true); 5761 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5762 Slog.w(TAG, "Unattached app died before backup, skipping"); 5763 try { 5764 IBackupManager bm = IBackupManager.Stub.asInterface( 5765 ServiceManager.getService(Context.BACKUP_SERVICE)); 5766 bm.agentDisconnected(app.info.packageName); 5767 } catch (RemoteException e) { 5768 // Can't happen; the backup manager is local 5769 } 5770 } 5771 if (isPendingBroadcastProcessLocked(pid)) { 5772 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5773 skipPendingBroadcastLocked(pid); 5774 } 5775 } else { 5776 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5777 } 5778 } 5779 5780 private final boolean attachApplicationLocked(IApplicationThread thread, 5781 int pid) { 5782 5783 // Find the application record that is being attached... either via 5784 // the pid if we are running in multiple processes, or just pull the 5785 // next app record if we are emulating process with anonymous threads. 5786 ProcessRecord app; 5787 if (pid != MY_PID && pid >= 0) { 5788 synchronized (mPidsSelfLocked) { 5789 app = mPidsSelfLocked.get(pid); 5790 } 5791 } else { 5792 app = null; 5793 } 5794 5795 if (app == null) { 5796 Slog.w(TAG, "No pending application record for pid " + pid 5797 + " (IApplicationThread " + thread + "); dropping process"); 5798 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5799 if (pid > 0 && pid != MY_PID) { 5800 Process.killProcessQuiet(pid); 5801 //TODO: Process.killProcessGroup(app.info.uid, pid); 5802 } else { 5803 try { 5804 thread.scheduleExit(); 5805 } catch (Exception e) { 5806 // Ignore exceptions. 5807 } 5808 } 5809 return false; 5810 } 5811 5812 // If this application record is still attached to a previous 5813 // process, clean it up now. 5814 if (app.thread != null) { 5815 handleAppDiedLocked(app, true, true); 5816 } 5817 5818 // Tell the process all about itself. 5819 5820 if (localLOGV) Slog.v( 5821 TAG, "Binding process pid " + pid + " to record " + app); 5822 5823 final String processName = app.processName; 5824 try { 5825 AppDeathRecipient adr = new AppDeathRecipient( 5826 app, pid, thread); 5827 thread.asBinder().linkToDeath(adr, 0); 5828 app.deathRecipient = adr; 5829 } catch (RemoteException e) { 5830 app.resetPackageList(mProcessStats); 5831 startProcessLocked(app, "link fail", processName); 5832 return false; 5833 } 5834 5835 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5836 5837 app.makeActive(thread, mProcessStats); 5838 app.curAdj = app.setAdj = -100; 5839 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5840 app.forcingToForeground = null; 5841 updateProcessForegroundLocked(app, false, false); 5842 app.hasShownUi = false; 5843 app.debugging = false; 5844 app.cached = false; 5845 5846 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5847 5848 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5849 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5850 5851 if (!normalMode) { 5852 Slog.i(TAG, "Launching preboot mode app: " + app); 5853 } 5854 5855 if (localLOGV) Slog.v( 5856 TAG, "New app record " + app 5857 + " thread=" + thread.asBinder() + " pid=" + pid); 5858 try { 5859 int testMode = IApplicationThread.DEBUG_OFF; 5860 if (mDebugApp != null && mDebugApp.equals(processName)) { 5861 testMode = mWaitForDebugger 5862 ? IApplicationThread.DEBUG_WAIT 5863 : IApplicationThread.DEBUG_ON; 5864 app.debugging = true; 5865 if (mDebugTransient) { 5866 mDebugApp = mOrigDebugApp; 5867 mWaitForDebugger = mOrigWaitForDebugger; 5868 } 5869 } 5870 String profileFile = app.instrumentationProfileFile; 5871 ParcelFileDescriptor profileFd = null; 5872 int samplingInterval = 0; 5873 boolean profileAutoStop = false; 5874 if (mProfileApp != null && mProfileApp.equals(processName)) { 5875 mProfileProc = app; 5876 profileFile = mProfileFile; 5877 profileFd = mProfileFd; 5878 samplingInterval = mSamplingInterval; 5879 profileAutoStop = mAutoStopProfiler; 5880 } 5881 boolean enableOpenGlTrace = false; 5882 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5883 enableOpenGlTrace = true; 5884 mOpenGlTraceApp = null; 5885 } 5886 5887 // If the app is being launched for restore or full backup, set it up specially 5888 boolean isRestrictedBackupMode = false; 5889 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5890 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5891 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5892 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5893 } 5894 5895 ensurePackageDexOpt(app.instrumentationInfo != null 5896 ? app.instrumentationInfo.packageName 5897 : app.info.packageName); 5898 if (app.instrumentationClass != null) { 5899 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5900 } 5901 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5902 + processName + " with config " + mConfiguration); 5903 ApplicationInfo appInfo = app.instrumentationInfo != null 5904 ? app.instrumentationInfo : app.info; 5905 app.compat = compatibilityInfoForPackageLocked(appInfo); 5906 if (profileFd != null) { 5907 profileFd = profileFd.dup(); 5908 } 5909 ProfilerInfo profilerInfo = profileFile == null ? null 5910 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5911 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5912 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5913 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5914 isRestrictedBackupMode || !normalMode, app.persistent, 5915 new Configuration(mConfiguration), app.compat, 5916 getCommonServicesLocked(app.isolated), 5917 mCoreSettingsObserver.getCoreSettingsLocked()); 5918 updateLruProcessLocked(app, false, null); 5919 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5920 } catch (Exception e) { 5921 // todo: Yikes! What should we do? For now we will try to 5922 // start another process, but that could easily get us in 5923 // an infinite loop of restarting processes... 5924 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5925 5926 app.resetPackageList(mProcessStats); 5927 app.unlinkDeathRecipient(); 5928 startProcessLocked(app, "bind fail", processName); 5929 return false; 5930 } 5931 5932 // Remove this record from the list of starting applications. 5933 mPersistentStartingProcesses.remove(app); 5934 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5935 "Attach application locked removing on hold: " + app); 5936 mProcessesOnHold.remove(app); 5937 5938 boolean badApp = false; 5939 boolean didSomething = false; 5940 5941 // See if the top visible activity is waiting to run in this process... 5942 if (normalMode) { 5943 try { 5944 if (mStackSupervisor.attachApplicationLocked(app)) { 5945 didSomething = true; 5946 } 5947 } catch (Exception e) { 5948 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5949 badApp = true; 5950 } 5951 } 5952 5953 // Find any services that should be running in this process... 5954 if (!badApp) { 5955 try { 5956 didSomething |= mServices.attachApplicationLocked(app, processName); 5957 } catch (Exception e) { 5958 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5959 badApp = true; 5960 } 5961 } 5962 5963 // Check if a next-broadcast receiver is in this process... 5964 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5965 try { 5966 didSomething |= sendPendingBroadcastsLocked(app); 5967 } catch (Exception e) { 5968 // If the app died trying to launch the receiver we declare it 'bad' 5969 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 5970 badApp = true; 5971 } 5972 } 5973 5974 // Check whether the next backup agent is in this process... 5975 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5976 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5977 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5978 try { 5979 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5980 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5981 mBackupTarget.backupMode); 5982 } catch (Exception e) { 5983 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 5984 badApp = true; 5985 } 5986 } 5987 5988 if (badApp) { 5989 app.kill("error during init", true); 5990 handleAppDiedLocked(app, false, true); 5991 return false; 5992 } 5993 5994 if (!didSomething) { 5995 updateOomAdjLocked(); 5996 } 5997 5998 return true; 5999 } 6000 6001 @Override 6002 public final void attachApplication(IApplicationThread thread) { 6003 synchronized (this) { 6004 int callingPid = Binder.getCallingPid(); 6005 final long origId = Binder.clearCallingIdentity(); 6006 attachApplicationLocked(thread, callingPid); 6007 Binder.restoreCallingIdentity(origId); 6008 } 6009 } 6010 6011 @Override 6012 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6013 final long origId = Binder.clearCallingIdentity(); 6014 synchronized (this) { 6015 ActivityStack stack = ActivityRecord.getStackLocked(token); 6016 if (stack != null) { 6017 ActivityRecord r = 6018 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6019 if (stopProfiling) { 6020 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6021 try { 6022 mProfileFd.close(); 6023 } catch (IOException e) { 6024 } 6025 clearProfilerLocked(); 6026 } 6027 } 6028 } 6029 } 6030 Binder.restoreCallingIdentity(origId); 6031 } 6032 6033 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6034 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6035 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6036 } 6037 6038 void enableScreenAfterBoot() { 6039 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6040 SystemClock.uptimeMillis()); 6041 mWindowManager.enableScreenAfterBoot(); 6042 6043 synchronized (this) { 6044 updateEventDispatchingLocked(); 6045 } 6046 } 6047 6048 @Override 6049 public void showBootMessage(final CharSequence msg, final boolean always) { 6050 enforceNotIsolatedCaller("showBootMessage"); 6051 mWindowManager.showBootMessage(msg, always); 6052 } 6053 6054 @Override 6055 public void keyguardWaitingForActivityDrawn() { 6056 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6057 final long token = Binder.clearCallingIdentity(); 6058 try { 6059 synchronized (this) { 6060 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6061 mWindowManager.keyguardWaitingForActivityDrawn(); 6062 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6063 mLockScreenShown = LOCK_SCREEN_LEAVING; 6064 } 6065 } 6066 } finally { 6067 Binder.restoreCallingIdentity(token); 6068 } 6069 } 6070 6071 final void finishBooting() { 6072 synchronized (this) { 6073 if (!mBootAnimationComplete) { 6074 mCallFinishBooting = true; 6075 return; 6076 } 6077 mCallFinishBooting = false; 6078 } 6079 6080 ArraySet<String> completedIsas = new ArraySet<String>(); 6081 for (String abi : Build.SUPPORTED_ABIS) { 6082 Process.establishZygoteConnectionForAbi(abi); 6083 final String instructionSet = VMRuntime.getInstructionSet(abi); 6084 if (!completedIsas.contains(instructionSet)) { 6085 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6086 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6087 } 6088 completedIsas.add(instructionSet); 6089 } 6090 } 6091 6092 IntentFilter pkgFilter = new IntentFilter(); 6093 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6094 pkgFilter.addDataScheme("package"); 6095 mContext.registerReceiver(new BroadcastReceiver() { 6096 @Override 6097 public void onReceive(Context context, Intent intent) { 6098 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6099 if (pkgs != null) { 6100 for (String pkg : pkgs) { 6101 synchronized (ActivityManagerService.this) { 6102 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6103 0, "finished booting")) { 6104 setResultCode(Activity.RESULT_OK); 6105 return; 6106 } 6107 } 6108 } 6109 } 6110 } 6111 }, pkgFilter); 6112 6113 // Let system services know. 6114 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6115 6116 synchronized (this) { 6117 // Ensure that any processes we had put on hold are now started 6118 // up. 6119 final int NP = mProcessesOnHold.size(); 6120 if (NP > 0) { 6121 ArrayList<ProcessRecord> procs = 6122 new ArrayList<ProcessRecord>(mProcessesOnHold); 6123 for (int ip=0; ip<NP; ip++) { 6124 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6125 + procs.get(ip)); 6126 startProcessLocked(procs.get(ip), "on-hold", null); 6127 } 6128 } 6129 6130 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6131 // Start looking for apps that are abusing wake locks. 6132 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6133 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6134 // Tell anyone interested that we are done booting! 6135 SystemProperties.set("sys.boot_completed", "1"); 6136 6137 // And trigger dev.bootcomplete if we are not showing encryption progress 6138 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6139 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6140 SystemProperties.set("dev.bootcomplete", "1"); 6141 } 6142 for (int i=0; i<mStartedUsers.size(); i++) { 6143 UserStartedState uss = mStartedUsers.valueAt(i); 6144 if (uss.mState == UserStartedState.STATE_BOOTING) { 6145 uss.mState = UserStartedState.STATE_RUNNING; 6146 final int userId = mStartedUsers.keyAt(i); 6147 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6148 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6149 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6150 broadcastIntentLocked(null, null, intent, null, 6151 new IIntentReceiver.Stub() { 6152 @Override 6153 public void performReceive(Intent intent, int resultCode, 6154 String data, Bundle extras, boolean ordered, 6155 boolean sticky, int sendingUser) { 6156 synchronized (ActivityManagerService.this) { 6157 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6158 true, false); 6159 } 6160 } 6161 }, 6162 0, null, null, 6163 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6164 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6165 userId); 6166 } 6167 } 6168 scheduleStartProfilesLocked(); 6169 } 6170 } 6171 } 6172 6173 @Override 6174 public void bootAnimationComplete() { 6175 final boolean callFinishBooting; 6176 synchronized (this) { 6177 callFinishBooting = mCallFinishBooting; 6178 mBootAnimationComplete = true; 6179 } 6180 if (callFinishBooting) { 6181 finishBooting(); 6182 } 6183 } 6184 6185 final void ensureBootCompleted() { 6186 boolean booting; 6187 boolean enableScreen; 6188 synchronized (this) { 6189 booting = mBooting; 6190 mBooting = false; 6191 enableScreen = !mBooted; 6192 mBooted = true; 6193 } 6194 6195 if (booting) { 6196 finishBooting(); 6197 } 6198 6199 if (enableScreen) { 6200 enableScreenAfterBoot(); 6201 } 6202 } 6203 6204 @Override 6205 public final void activityResumed(IBinder token) { 6206 final long origId = Binder.clearCallingIdentity(); 6207 synchronized(this) { 6208 ActivityStack stack = ActivityRecord.getStackLocked(token); 6209 if (stack != null) { 6210 ActivityRecord.activityResumedLocked(token); 6211 } 6212 } 6213 Binder.restoreCallingIdentity(origId); 6214 } 6215 6216 @Override 6217 public final void activityPaused(IBinder token) { 6218 final long origId = Binder.clearCallingIdentity(); 6219 synchronized(this) { 6220 ActivityStack stack = ActivityRecord.getStackLocked(token); 6221 if (stack != null) { 6222 stack.activityPausedLocked(token, false); 6223 } 6224 } 6225 Binder.restoreCallingIdentity(origId); 6226 } 6227 6228 @Override 6229 public final void activityStopped(IBinder token, Bundle icicle, 6230 PersistableBundle persistentState, CharSequence description) { 6231 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6232 6233 // Refuse possible leaked file descriptors 6234 if (icicle != null && icicle.hasFileDescriptors()) { 6235 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6236 } 6237 6238 final long origId = Binder.clearCallingIdentity(); 6239 6240 synchronized (this) { 6241 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6242 if (r != null) { 6243 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6244 } 6245 } 6246 6247 trimApplications(); 6248 6249 Binder.restoreCallingIdentity(origId); 6250 } 6251 6252 @Override 6253 public final void activityDestroyed(IBinder token) { 6254 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6255 synchronized (this) { 6256 ActivityStack stack = ActivityRecord.getStackLocked(token); 6257 if (stack != null) { 6258 stack.activityDestroyedLocked(token); 6259 } 6260 } 6261 } 6262 6263 @Override 6264 public final void backgroundResourcesReleased(IBinder token) { 6265 final long origId = Binder.clearCallingIdentity(); 6266 try { 6267 synchronized (this) { 6268 ActivityStack stack = ActivityRecord.getStackLocked(token); 6269 if (stack != null) { 6270 stack.backgroundResourcesReleased(); 6271 } 6272 } 6273 } finally { 6274 Binder.restoreCallingIdentity(origId); 6275 } 6276 } 6277 6278 @Override 6279 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6280 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6281 } 6282 6283 @Override 6284 public final void notifyEnterAnimationComplete(IBinder token) { 6285 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6286 } 6287 6288 @Override 6289 public String getCallingPackage(IBinder token) { 6290 synchronized (this) { 6291 ActivityRecord r = getCallingRecordLocked(token); 6292 return r != null ? r.info.packageName : null; 6293 } 6294 } 6295 6296 @Override 6297 public ComponentName getCallingActivity(IBinder token) { 6298 synchronized (this) { 6299 ActivityRecord r = getCallingRecordLocked(token); 6300 return r != null ? r.intent.getComponent() : null; 6301 } 6302 } 6303 6304 private ActivityRecord getCallingRecordLocked(IBinder token) { 6305 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6306 if (r == null) { 6307 return null; 6308 } 6309 return r.resultTo; 6310 } 6311 6312 @Override 6313 public ComponentName getActivityClassForToken(IBinder token) { 6314 synchronized(this) { 6315 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6316 if (r == null) { 6317 return null; 6318 } 6319 return r.intent.getComponent(); 6320 } 6321 } 6322 6323 @Override 6324 public String getPackageForToken(IBinder token) { 6325 synchronized(this) { 6326 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6327 if (r == null) { 6328 return null; 6329 } 6330 return r.packageName; 6331 } 6332 } 6333 6334 @Override 6335 public IIntentSender getIntentSender(int type, 6336 String packageName, IBinder token, String resultWho, 6337 int requestCode, Intent[] intents, String[] resolvedTypes, 6338 int flags, Bundle options, int userId) { 6339 enforceNotIsolatedCaller("getIntentSender"); 6340 // Refuse possible leaked file descriptors 6341 if (intents != null) { 6342 if (intents.length < 1) { 6343 throw new IllegalArgumentException("Intents array length must be >= 1"); 6344 } 6345 for (int i=0; i<intents.length; i++) { 6346 Intent intent = intents[i]; 6347 if (intent != null) { 6348 if (intent.hasFileDescriptors()) { 6349 throw new IllegalArgumentException("File descriptors passed in Intent"); 6350 } 6351 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6352 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6353 throw new IllegalArgumentException( 6354 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6355 } 6356 intents[i] = new Intent(intent); 6357 } 6358 } 6359 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6360 throw new IllegalArgumentException( 6361 "Intent array length does not match resolvedTypes length"); 6362 } 6363 } 6364 if (options != null) { 6365 if (options.hasFileDescriptors()) { 6366 throw new IllegalArgumentException("File descriptors passed in options"); 6367 } 6368 } 6369 6370 synchronized(this) { 6371 int callingUid = Binder.getCallingUid(); 6372 int origUserId = userId; 6373 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6374 type == ActivityManager.INTENT_SENDER_BROADCAST, 6375 ALLOW_NON_FULL, "getIntentSender", null); 6376 if (origUserId == UserHandle.USER_CURRENT) { 6377 // We don't want to evaluate this until the pending intent is 6378 // actually executed. However, we do want to always do the 6379 // security checking for it above. 6380 userId = UserHandle.USER_CURRENT; 6381 } 6382 try { 6383 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6384 int uid = AppGlobals.getPackageManager() 6385 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6386 if (!UserHandle.isSameApp(callingUid, uid)) { 6387 String msg = "Permission Denial: getIntentSender() from pid=" 6388 + Binder.getCallingPid() 6389 + ", uid=" + Binder.getCallingUid() 6390 + ", (need uid=" + uid + ")" 6391 + " is not allowed to send as package " + packageName; 6392 Slog.w(TAG, msg); 6393 throw new SecurityException(msg); 6394 } 6395 } 6396 6397 return getIntentSenderLocked(type, packageName, callingUid, userId, 6398 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6399 6400 } catch (RemoteException e) { 6401 throw new SecurityException(e); 6402 } 6403 } 6404 } 6405 6406 IIntentSender getIntentSenderLocked(int type, String packageName, 6407 int callingUid, int userId, IBinder token, String resultWho, 6408 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6409 Bundle options) { 6410 if (DEBUG_MU) 6411 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6412 ActivityRecord activity = null; 6413 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6414 activity = ActivityRecord.isInStackLocked(token); 6415 if (activity == null) { 6416 return null; 6417 } 6418 if (activity.finishing) { 6419 return null; 6420 } 6421 } 6422 6423 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6424 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6425 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6426 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6427 |PendingIntent.FLAG_UPDATE_CURRENT); 6428 6429 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6430 type, packageName, activity, resultWho, 6431 requestCode, intents, resolvedTypes, flags, options, userId); 6432 WeakReference<PendingIntentRecord> ref; 6433 ref = mIntentSenderRecords.get(key); 6434 PendingIntentRecord rec = ref != null ? ref.get() : null; 6435 if (rec != null) { 6436 if (!cancelCurrent) { 6437 if (updateCurrent) { 6438 if (rec.key.requestIntent != null) { 6439 rec.key.requestIntent.replaceExtras(intents != null ? 6440 intents[intents.length - 1] : null); 6441 } 6442 if (intents != null) { 6443 intents[intents.length-1] = rec.key.requestIntent; 6444 rec.key.allIntents = intents; 6445 rec.key.allResolvedTypes = resolvedTypes; 6446 } else { 6447 rec.key.allIntents = null; 6448 rec.key.allResolvedTypes = null; 6449 } 6450 } 6451 return rec; 6452 } 6453 rec.canceled = true; 6454 mIntentSenderRecords.remove(key); 6455 } 6456 if (noCreate) { 6457 return rec; 6458 } 6459 rec = new PendingIntentRecord(this, key, callingUid); 6460 mIntentSenderRecords.put(key, rec.ref); 6461 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6462 if (activity.pendingResults == null) { 6463 activity.pendingResults 6464 = new HashSet<WeakReference<PendingIntentRecord>>(); 6465 } 6466 activity.pendingResults.add(rec.ref); 6467 } 6468 return rec; 6469 } 6470 6471 @Override 6472 public void cancelIntentSender(IIntentSender sender) { 6473 if (!(sender instanceof PendingIntentRecord)) { 6474 return; 6475 } 6476 synchronized(this) { 6477 PendingIntentRecord rec = (PendingIntentRecord)sender; 6478 try { 6479 int uid = AppGlobals.getPackageManager() 6480 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6481 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6482 String msg = "Permission Denial: cancelIntentSender() from pid=" 6483 + Binder.getCallingPid() 6484 + ", uid=" + Binder.getCallingUid() 6485 + " is not allowed to cancel packges " 6486 + rec.key.packageName; 6487 Slog.w(TAG, msg); 6488 throw new SecurityException(msg); 6489 } 6490 } catch (RemoteException e) { 6491 throw new SecurityException(e); 6492 } 6493 cancelIntentSenderLocked(rec, true); 6494 } 6495 } 6496 6497 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6498 rec.canceled = true; 6499 mIntentSenderRecords.remove(rec.key); 6500 if (cleanActivity && rec.key.activity != null) { 6501 rec.key.activity.pendingResults.remove(rec.ref); 6502 } 6503 } 6504 6505 @Override 6506 public String getPackageForIntentSender(IIntentSender pendingResult) { 6507 if (!(pendingResult instanceof PendingIntentRecord)) { 6508 return null; 6509 } 6510 try { 6511 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6512 return res.key.packageName; 6513 } catch (ClassCastException e) { 6514 } 6515 return null; 6516 } 6517 6518 @Override 6519 public int getUidForIntentSender(IIntentSender sender) { 6520 if (sender instanceof PendingIntentRecord) { 6521 try { 6522 PendingIntentRecord res = (PendingIntentRecord)sender; 6523 return res.uid; 6524 } catch (ClassCastException e) { 6525 } 6526 } 6527 return -1; 6528 } 6529 6530 @Override 6531 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6532 if (!(pendingResult instanceof PendingIntentRecord)) { 6533 return false; 6534 } 6535 try { 6536 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6537 if (res.key.allIntents == null) { 6538 return false; 6539 } 6540 for (int i=0; i<res.key.allIntents.length; i++) { 6541 Intent intent = res.key.allIntents[i]; 6542 if (intent.getPackage() != null && intent.getComponent() != null) { 6543 return false; 6544 } 6545 } 6546 return true; 6547 } catch (ClassCastException e) { 6548 } 6549 return false; 6550 } 6551 6552 @Override 6553 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6554 if (!(pendingResult instanceof PendingIntentRecord)) { 6555 return false; 6556 } 6557 try { 6558 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6559 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6560 return true; 6561 } 6562 return false; 6563 } catch (ClassCastException e) { 6564 } 6565 return false; 6566 } 6567 6568 @Override 6569 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6570 if (!(pendingResult instanceof PendingIntentRecord)) { 6571 return null; 6572 } 6573 try { 6574 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6575 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6576 } catch (ClassCastException e) { 6577 } 6578 return null; 6579 } 6580 6581 @Override 6582 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6583 if (!(pendingResult instanceof PendingIntentRecord)) { 6584 return null; 6585 } 6586 try { 6587 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6588 Intent intent = res.key.requestIntent; 6589 if (intent != null) { 6590 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6591 || res.lastTagPrefix.equals(prefix))) { 6592 return res.lastTag; 6593 } 6594 res.lastTagPrefix = prefix; 6595 StringBuilder sb = new StringBuilder(128); 6596 if (prefix != null) { 6597 sb.append(prefix); 6598 } 6599 if (intent.getAction() != null) { 6600 sb.append(intent.getAction()); 6601 } else if (intent.getComponent() != null) { 6602 intent.getComponent().appendShortString(sb); 6603 } else { 6604 sb.append("?"); 6605 } 6606 return res.lastTag = sb.toString(); 6607 } 6608 } catch (ClassCastException e) { 6609 } 6610 return null; 6611 } 6612 6613 @Override 6614 public void setProcessLimit(int max) { 6615 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6616 "setProcessLimit()"); 6617 synchronized (this) { 6618 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6619 mProcessLimitOverride = max; 6620 } 6621 trimApplications(); 6622 } 6623 6624 @Override 6625 public int getProcessLimit() { 6626 synchronized (this) { 6627 return mProcessLimitOverride; 6628 } 6629 } 6630 6631 void foregroundTokenDied(ForegroundToken token) { 6632 synchronized (ActivityManagerService.this) { 6633 synchronized (mPidsSelfLocked) { 6634 ForegroundToken cur 6635 = mForegroundProcesses.get(token.pid); 6636 if (cur != token) { 6637 return; 6638 } 6639 mForegroundProcesses.remove(token.pid); 6640 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6641 if (pr == null) { 6642 return; 6643 } 6644 pr.forcingToForeground = null; 6645 updateProcessForegroundLocked(pr, false, false); 6646 } 6647 updateOomAdjLocked(); 6648 } 6649 } 6650 6651 @Override 6652 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6653 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6654 "setProcessForeground()"); 6655 synchronized(this) { 6656 boolean changed = false; 6657 6658 synchronized (mPidsSelfLocked) { 6659 ProcessRecord pr = mPidsSelfLocked.get(pid); 6660 if (pr == null && isForeground) { 6661 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6662 return; 6663 } 6664 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6665 if (oldToken != null) { 6666 oldToken.token.unlinkToDeath(oldToken, 0); 6667 mForegroundProcesses.remove(pid); 6668 if (pr != null) { 6669 pr.forcingToForeground = null; 6670 } 6671 changed = true; 6672 } 6673 if (isForeground && token != null) { 6674 ForegroundToken newToken = new ForegroundToken() { 6675 @Override 6676 public void binderDied() { 6677 foregroundTokenDied(this); 6678 } 6679 }; 6680 newToken.pid = pid; 6681 newToken.token = token; 6682 try { 6683 token.linkToDeath(newToken, 0); 6684 mForegroundProcesses.put(pid, newToken); 6685 pr.forcingToForeground = token; 6686 changed = true; 6687 } catch (RemoteException e) { 6688 // If the process died while doing this, we will later 6689 // do the cleanup with the process death link. 6690 } 6691 } 6692 } 6693 6694 if (changed) { 6695 updateOomAdjLocked(); 6696 } 6697 } 6698 } 6699 6700 // ========================================================= 6701 // PERMISSIONS 6702 // ========================================================= 6703 6704 static class PermissionController extends IPermissionController.Stub { 6705 ActivityManagerService mActivityManagerService; 6706 PermissionController(ActivityManagerService activityManagerService) { 6707 mActivityManagerService = activityManagerService; 6708 } 6709 6710 @Override 6711 public boolean checkPermission(String permission, int pid, int uid) { 6712 return mActivityManagerService.checkPermission(permission, pid, 6713 uid) == PackageManager.PERMISSION_GRANTED; 6714 } 6715 } 6716 6717 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6718 @Override 6719 public int checkComponentPermission(String permission, int pid, int uid, 6720 int owningUid, boolean exported) { 6721 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6722 owningUid, exported); 6723 } 6724 6725 @Override 6726 public Object getAMSLock() { 6727 return ActivityManagerService.this; 6728 } 6729 } 6730 6731 /** 6732 * This can be called with or without the global lock held. 6733 */ 6734 int checkComponentPermission(String permission, int pid, int uid, 6735 int owningUid, boolean exported) { 6736 if (pid == MY_PID) { 6737 return PackageManager.PERMISSION_GRANTED; 6738 } 6739 return ActivityManager.checkComponentPermission(permission, uid, 6740 owningUid, exported); 6741 } 6742 6743 /** 6744 * As the only public entry point for permissions checking, this method 6745 * can enforce the semantic that requesting a check on a null global 6746 * permission is automatically denied. (Internally a null permission 6747 * string is used when calling {@link #checkComponentPermission} in cases 6748 * when only uid-based security is needed.) 6749 * 6750 * This can be called with or without the global lock held. 6751 */ 6752 @Override 6753 public int checkPermission(String permission, int pid, int uid) { 6754 if (permission == null) { 6755 return PackageManager.PERMISSION_DENIED; 6756 } 6757 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6758 } 6759 6760 @Override 6761 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6762 if (permission == null) { 6763 return PackageManager.PERMISSION_DENIED; 6764 } 6765 6766 // We might be performing an operation on behalf of an indirect binder 6767 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6768 // client identity accordingly before proceeding. 6769 Identity tlsIdentity = sCallerIdentity.get(); 6770 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6771 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6772 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6773 uid = tlsIdentity.uid; 6774 pid = tlsIdentity.pid; 6775 } 6776 6777 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6778 } 6779 6780 /** 6781 * Binder IPC calls go through the public entry point. 6782 * This can be called with or without the global lock held. 6783 */ 6784 int checkCallingPermission(String permission) { 6785 return checkPermission(permission, 6786 Binder.getCallingPid(), 6787 UserHandle.getAppId(Binder.getCallingUid())); 6788 } 6789 6790 /** 6791 * This can be called with or without the global lock held. 6792 */ 6793 void enforceCallingPermission(String permission, String func) { 6794 if (checkCallingPermission(permission) 6795 == PackageManager.PERMISSION_GRANTED) { 6796 return; 6797 } 6798 6799 String msg = "Permission Denial: " + func + " from pid=" 6800 + Binder.getCallingPid() 6801 + ", uid=" + Binder.getCallingUid() 6802 + " requires " + permission; 6803 Slog.w(TAG, msg); 6804 throw new SecurityException(msg); 6805 } 6806 6807 /** 6808 * Determine if UID is holding permissions required to access {@link Uri} in 6809 * the given {@link ProviderInfo}. Final permission checking is always done 6810 * in {@link ContentProvider}. 6811 */ 6812 private final boolean checkHoldingPermissionsLocked( 6813 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6814 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6815 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6816 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6817 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6818 != PERMISSION_GRANTED) { 6819 return false; 6820 } 6821 } 6822 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6823 } 6824 6825 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6826 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6827 if (pi.applicationInfo.uid == uid) { 6828 return true; 6829 } else if (!pi.exported) { 6830 return false; 6831 } 6832 6833 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6834 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6835 try { 6836 // check if target holds top-level <provider> permissions 6837 if (!readMet && pi.readPermission != null && considerUidPermissions 6838 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6839 readMet = true; 6840 } 6841 if (!writeMet && pi.writePermission != null && considerUidPermissions 6842 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6843 writeMet = true; 6844 } 6845 6846 // track if unprotected read/write is allowed; any denied 6847 // <path-permission> below removes this ability 6848 boolean allowDefaultRead = pi.readPermission == null; 6849 boolean allowDefaultWrite = pi.writePermission == null; 6850 6851 // check if target holds any <path-permission> that match uri 6852 final PathPermission[] pps = pi.pathPermissions; 6853 if (pps != null) { 6854 final String path = grantUri.uri.getPath(); 6855 int i = pps.length; 6856 while (i > 0 && (!readMet || !writeMet)) { 6857 i--; 6858 PathPermission pp = pps[i]; 6859 if (pp.match(path)) { 6860 if (!readMet) { 6861 final String pprperm = pp.getReadPermission(); 6862 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6863 + pprperm + " for " + pp.getPath() 6864 + ": match=" + pp.match(path) 6865 + " check=" + pm.checkUidPermission(pprperm, uid)); 6866 if (pprperm != null) { 6867 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6868 == PERMISSION_GRANTED) { 6869 readMet = true; 6870 } else { 6871 allowDefaultRead = false; 6872 } 6873 } 6874 } 6875 if (!writeMet) { 6876 final String ppwperm = pp.getWritePermission(); 6877 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6878 + ppwperm + " for " + pp.getPath() 6879 + ": match=" + pp.match(path) 6880 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6881 if (ppwperm != null) { 6882 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6883 == PERMISSION_GRANTED) { 6884 writeMet = true; 6885 } else { 6886 allowDefaultWrite = false; 6887 } 6888 } 6889 } 6890 } 6891 } 6892 } 6893 6894 // grant unprotected <provider> read/write, if not blocked by 6895 // <path-permission> above 6896 if (allowDefaultRead) readMet = true; 6897 if (allowDefaultWrite) writeMet = true; 6898 6899 } catch (RemoteException e) { 6900 return false; 6901 } 6902 6903 return readMet && writeMet; 6904 } 6905 6906 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6907 ProviderInfo pi = null; 6908 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6909 if (cpr != null) { 6910 pi = cpr.info; 6911 } else { 6912 try { 6913 pi = AppGlobals.getPackageManager().resolveContentProvider( 6914 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6915 } catch (RemoteException ex) { 6916 } 6917 } 6918 return pi; 6919 } 6920 6921 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6922 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6923 if (targetUris != null) { 6924 return targetUris.get(grantUri); 6925 } 6926 return null; 6927 } 6928 6929 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6930 String targetPkg, int targetUid, GrantUri grantUri) { 6931 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6932 if (targetUris == null) { 6933 targetUris = Maps.newArrayMap(); 6934 mGrantedUriPermissions.put(targetUid, targetUris); 6935 } 6936 6937 UriPermission perm = targetUris.get(grantUri); 6938 if (perm == null) { 6939 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6940 targetUris.put(grantUri, perm); 6941 } 6942 6943 return perm; 6944 } 6945 6946 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6947 final int modeFlags) { 6948 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6949 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6950 : UriPermission.STRENGTH_OWNED; 6951 6952 // Root gets to do everything. 6953 if (uid == 0) { 6954 return true; 6955 } 6956 6957 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6958 if (perms == null) return false; 6959 6960 // First look for exact match 6961 final UriPermission exactPerm = perms.get(grantUri); 6962 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6963 return true; 6964 } 6965 6966 // No exact match, look for prefixes 6967 final int N = perms.size(); 6968 for (int i = 0; i < N; i++) { 6969 final UriPermission perm = perms.valueAt(i); 6970 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6971 && perm.getStrength(modeFlags) >= minStrength) { 6972 return true; 6973 } 6974 } 6975 6976 return false; 6977 } 6978 6979 /** 6980 * @param uri This uri must NOT contain an embedded userId. 6981 * @param userId The userId in which the uri is to be resolved. 6982 */ 6983 @Override 6984 public int checkUriPermission(Uri uri, int pid, int uid, 6985 final int modeFlags, int userId, IBinder callerToken) { 6986 enforceNotIsolatedCaller("checkUriPermission"); 6987 6988 // Another redirected-binder-call permissions check as in 6989 // {@link checkPermissionWithToken}. 6990 Identity tlsIdentity = sCallerIdentity.get(); 6991 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6992 uid = tlsIdentity.uid; 6993 pid = tlsIdentity.pid; 6994 } 6995 6996 // Our own process gets to do everything. 6997 if (pid == MY_PID) { 6998 return PackageManager.PERMISSION_GRANTED; 6999 } 7000 synchronized (this) { 7001 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7002 ? PackageManager.PERMISSION_GRANTED 7003 : PackageManager.PERMISSION_DENIED; 7004 } 7005 } 7006 7007 /** 7008 * Check if the targetPkg can be granted permission to access uri by 7009 * the callingUid using the given modeFlags. Throws a security exception 7010 * if callingUid is not allowed to do this. Returns the uid of the target 7011 * if the URI permission grant should be performed; returns -1 if it is not 7012 * needed (for example targetPkg already has permission to access the URI). 7013 * If you already know the uid of the target, you can supply it in 7014 * lastTargetUid else set that to -1. 7015 */ 7016 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7017 final int modeFlags, int lastTargetUid) { 7018 if (!Intent.isAccessUriMode(modeFlags)) { 7019 return -1; 7020 } 7021 7022 if (targetPkg != null) { 7023 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7024 "Checking grant " + targetPkg + " permission to " + grantUri); 7025 } 7026 7027 final IPackageManager pm = AppGlobals.getPackageManager(); 7028 7029 // If this is not a content: uri, we can't do anything with it. 7030 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7031 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7032 "Can't grant URI permission for non-content URI: " + grantUri); 7033 return -1; 7034 } 7035 7036 final String authority = grantUri.uri.getAuthority(); 7037 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7038 if (pi == null) { 7039 Slog.w(TAG, "No content provider found for permission check: " + 7040 grantUri.uri.toSafeString()); 7041 return -1; 7042 } 7043 7044 int targetUid = lastTargetUid; 7045 if (targetUid < 0 && targetPkg != null) { 7046 try { 7047 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7048 if (targetUid < 0) { 7049 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7050 "Can't grant URI permission no uid for: " + targetPkg); 7051 return -1; 7052 } 7053 } catch (RemoteException ex) { 7054 return -1; 7055 } 7056 } 7057 7058 if (targetUid >= 0) { 7059 // First... does the target actually need this permission? 7060 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7061 // No need to grant the target this permission. 7062 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7063 "Target " + targetPkg + " already has full permission to " + grantUri); 7064 return -1; 7065 } 7066 } else { 7067 // First... there is no target package, so can anyone access it? 7068 boolean allowed = pi.exported; 7069 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7070 if (pi.readPermission != null) { 7071 allowed = false; 7072 } 7073 } 7074 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7075 if (pi.writePermission != null) { 7076 allowed = false; 7077 } 7078 } 7079 if (allowed) { 7080 return -1; 7081 } 7082 } 7083 7084 /* There is a special cross user grant if: 7085 * - The target is on another user. 7086 * - Apps on the current user can access the uri without any uid permissions. 7087 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7088 * grant uri permissions. 7089 */ 7090 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7091 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7092 modeFlags, false /*without considering the uid permissions*/); 7093 7094 // Second... is the provider allowing granting of URI permissions? 7095 if (!specialCrossUserGrant) { 7096 if (!pi.grantUriPermissions) { 7097 throw new SecurityException("Provider " + pi.packageName 7098 + "/" + pi.name 7099 + " does not allow granting of Uri permissions (uri " 7100 + grantUri + ")"); 7101 } 7102 if (pi.uriPermissionPatterns != null) { 7103 final int N = pi.uriPermissionPatterns.length; 7104 boolean allowed = false; 7105 for (int i=0; i<N; i++) { 7106 if (pi.uriPermissionPatterns[i] != null 7107 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7108 allowed = true; 7109 break; 7110 } 7111 } 7112 if (!allowed) { 7113 throw new SecurityException("Provider " + pi.packageName 7114 + "/" + pi.name 7115 + " does not allow granting of permission to path of Uri " 7116 + grantUri); 7117 } 7118 } 7119 } 7120 7121 // Third... does the caller itself have permission to access 7122 // this uri? 7123 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7124 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7125 // Require they hold a strong enough Uri permission 7126 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7127 throw new SecurityException("Uid " + callingUid 7128 + " does not have permission to uri " + grantUri); 7129 } 7130 } 7131 } 7132 return targetUid; 7133 } 7134 7135 /** 7136 * @param uri This uri must NOT contain an embedded userId. 7137 * @param userId The userId in which the uri is to be resolved. 7138 */ 7139 @Override 7140 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7141 final int modeFlags, int userId) { 7142 enforceNotIsolatedCaller("checkGrantUriPermission"); 7143 synchronized(this) { 7144 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7145 new GrantUri(userId, uri, false), modeFlags, -1); 7146 } 7147 } 7148 7149 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7150 final int modeFlags, UriPermissionOwner owner) { 7151 if (!Intent.isAccessUriMode(modeFlags)) { 7152 return; 7153 } 7154 7155 // So here we are: the caller has the assumed permission 7156 // to the uri, and the target doesn't. Let's now give this to 7157 // the target. 7158 7159 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7160 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7161 7162 final String authority = grantUri.uri.getAuthority(); 7163 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7164 if (pi == null) { 7165 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7166 return; 7167 } 7168 7169 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7170 grantUri.prefix = true; 7171 } 7172 final UriPermission perm = findOrCreateUriPermissionLocked( 7173 pi.packageName, targetPkg, targetUid, grantUri); 7174 perm.grantModes(modeFlags, owner); 7175 } 7176 7177 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7178 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7179 if (targetPkg == null) { 7180 throw new NullPointerException("targetPkg"); 7181 } 7182 int targetUid; 7183 final IPackageManager pm = AppGlobals.getPackageManager(); 7184 try { 7185 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7186 } catch (RemoteException ex) { 7187 return; 7188 } 7189 7190 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7191 targetUid); 7192 if (targetUid < 0) { 7193 return; 7194 } 7195 7196 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7197 owner); 7198 } 7199 7200 static class NeededUriGrants extends ArrayList<GrantUri> { 7201 final String targetPkg; 7202 final int targetUid; 7203 final int flags; 7204 7205 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7206 this.targetPkg = targetPkg; 7207 this.targetUid = targetUid; 7208 this.flags = flags; 7209 } 7210 } 7211 7212 /** 7213 * Like checkGrantUriPermissionLocked, but takes an Intent. 7214 */ 7215 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7216 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7217 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7218 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7219 + " clip=" + (intent != null ? intent.getClipData() : null) 7220 + " from " + intent + "; flags=0x" 7221 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7222 7223 if (targetPkg == null) { 7224 throw new NullPointerException("targetPkg"); 7225 } 7226 7227 if (intent == null) { 7228 return null; 7229 } 7230 Uri data = intent.getData(); 7231 ClipData clip = intent.getClipData(); 7232 if (data == null && clip == null) { 7233 return null; 7234 } 7235 // Default userId for uris in the intent (if they don't specify it themselves) 7236 int contentUserHint = intent.getContentUserHint(); 7237 if (contentUserHint == UserHandle.USER_CURRENT) { 7238 contentUserHint = UserHandle.getUserId(callingUid); 7239 } 7240 final IPackageManager pm = AppGlobals.getPackageManager(); 7241 int targetUid; 7242 if (needed != null) { 7243 targetUid = needed.targetUid; 7244 } else { 7245 try { 7246 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7247 } catch (RemoteException ex) { 7248 return null; 7249 } 7250 if (targetUid < 0) { 7251 if (DEBUG_URI_PERMISSION) { 7252 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7253 + " on user " + targetUserId); 7254 } 7255 return null; 7256 } 7257 } 7258 if (data != null) { 7259 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7260 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7261 targetUid); 7262 if (targetUid > 0) { 7263 if (needed == null) { 7264 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7265 } 7266 needed.add(grantUri); 7267 } 7268 } 7269 if (clip != null) { 7270 for (int i=0; i<clip.getItemCount(); i++) { 7271 Uri uri = clip.getItemAt(i).getUri(); 7272 if (uri != null) { 7273 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7274 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7275 targetUid); 7276 if (targetUid > 0) { 7277 if (needed == null) { 7278 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7279 } 7280 needed.add(grantUri); 7281 } 7282 } else { 7283 Intent clipIntent = clip.getItemAt(i).getIntent(); 7284 if (clipIntent != null) { 7285 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7286 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7287 if (newNeeded != null) { 7288 needed = newNeeded; 7289 } 7290 } 7291 } 7292 } 7293 } 7294 7295 return needed; 7296 } 7297 7298 /** 7299 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7300 */ 7301 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7302 UriPermissionOwner owner) { 7303 if (needed != null) { 7304 for (int i=0; i<needed.size(); i++) { 7305 GrantUri grantUri = needed.get(i); 7306 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7307 grantUri, needed.flags, owner); 7308 } 7309 } 7310 } 7311 7312 void grantUriPermissionFromIntentLocked(int callingUid, 7313 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7314 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7315 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7316 if (needed == null) { 7317 return; 7318 } 7319 7320 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7321 } 7322 7323 /** 7324 * @param uri This uri must NOT contain an embedded userId. 7325 * @param userId The userId in which the uri is to be resolved. 7326 */ 7327 @Override 7328 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7329 final int modeFlags, int userId) { 7330 enforceNotIsolatedCaller("grantUriPermission"); 7331 GrantUri grantUri = new GrantUri(userId, uri, false); 7332 synchronized(this) { 7333 final ProcessRecord r = getRecordForAppLocked(caller); 7334 if (r == null) { 7335 throw new SecurityException("Unable to find app for caller " 7336 + caller 7337 + " when granting permission to uri " + grantUri); 7338 } 7339 if (targetPkg == null) { 7340 throw new IllegalArgumentException("null target"); 7341 } 7342 if (grantUri == null) { 7343 throw new IllegalArgumentException("null uri"); 7344 } 7345 7346 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7347 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7348 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7349 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7350 7351 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7352 UserHandle.getUserId(r.uid)); 7353 } 7354 } 7355 7356 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7357 if (perm.modeFlags == 0) { 7358 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7359 perm.targetUid); 7360 if (perms != null) { 7361 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7362 "Removing " + perm.targetUid + " permission to " + perm.uri); 7363 7364 perms.remove(perm.uri); 7365 if (perms.isEmpty()) { 7366 mGrantedUriPermissions.remove(perm.targetUid); 7367 } 7368 } 7369 } 7370 } 7371 7372 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7373 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7374 7375 final IPackageManager pm = AppGlobals.getPackageManager(); 7376 final String authority = grantUri.uri.getAuthority(); 7377 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7378 if (pi == null) { 7379 Slog.w(TAG, "No content provider found for permission revoke: " 7380 + grantUri.toSafeString()); 7381 return; 7382 } 7383 7384 // Does the caller have this permission on the URI? 7385 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7386 // If they don't have direct access to the URI, then revoke any 7387 // ownerless URI permissions that have been granted to them. 7388 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7389 if (perms != null) { 7390 boolean persistChanged = false; 7391 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7392 final UriPermission perm = it.next(); 7393 if (perm.uri.sourceUserId == grantUri.sourceUserId 7394 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7395 if (DEBUG_URI_PERMISSION) 7396 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7397 " permission to " + perm.uri); 7398 persistChanged |= perm.revokeModes( 7399 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7400 if (perm.modeFlags == 0) { 7401 it.remove(); 7402 } 7403 } 7404 } 7405 if (perms.isEmpty()) { 7406 mGrantedUriPermissions.remove(callingUid); 7407 } 7408 if (persistChanged) { 7409 schedulePersistUriGrants(); 7410 } 7411 } 7412 return; 7413 } 7414 7415 boolean persistChanged = false; 7416 7417 // Go through all of the permissions and remove any that match. 7418 int N = mGrantedUriPermissions.size(); 7419 for (int i = 0; i < N; i++) { 7420 final int targetUid = mGrantedUriPermissions.keyAt(i); 7421 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7422 7423 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7424 final UriPermission perm = it.next(); 7425 if (perm.uri.sourceUserId == grantUri.sourceUserId 7426 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7427 if (DEBUG_URI_PERMISSION) 7428 Slog.v(TAG, 7429 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7430 persistChanged |= perm.revokeModes( 7431 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7432 if (perm.modeFlags == 0) { 7433 it.remove(); 7434 } 7435 } 7436 } 7437 7438 if (perms.isEmpty()) { 7439 mGrantedUriPermissions.remove(targetUid); 7440 N--; 7441 i--; 7442 } 7443 } 7444 7445 if (persistChanged) { 7446 schedulePersistUriGrants(); 7447 } 7448 } 7449 7450 /** 7451 * @param uri This uri must NOT contain an embedded userId. 7452 * @param userId The userId in which the uri is to be resolved. 7453 */ 7454 @Override 7455 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7456 int userId) { 7457 enforceNotIsolatedCaller("revokeUriPermission"); 7458 synchronized(this) { 7459 final ProcessRecord r = getRecordForAppLocked(caller); 7460 if (r == null) { 7461 throw new SecurityException("Unable to find app for caller " 7462 + caller 7463 + " when revoking permission to uri " + uri); 7464 } 7465 if (uri == null) { 7466 Slog.w(TAG, "revokeUriPermission: null uri"); 7467 return; 7468 } 7469 7470 if (!Intent.isAccessUriMode(modeFlags)) { 7471 return; 7472 } 7473 7474 final IPackageManager pm = AppGlobals.getPackageManager(); 7475 final String authority = uri.getAuthority(); 7476 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7477 if (pi == null) { 7478 Slog.w(TAG, "No content provider found for permission revoke: " 7479 + uri.toSafeString()); 7480 return; 7481 } 7482 7483 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7484 } 7485 } 7486 7487 /** 7488 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7489 * given package. 7490 * 7491 * @param packageName Package name to match, or {@code null} to apply to all 7492 * packages. 7493 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7494 * to all users. 7495 * @param persistable If persistable grants should be removed. 7496 */ 7497 private void removeUriPermissionsForPackageLocked( 7498 String packageName, int userHandle, boolean persistable) { 7499 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7500 throw new IllegalArgumentException("Must narrow by either package or user"); 7501 } 7502 7503 boolean persistChanged = false; 7504 7505 int N = mGrantedUriPermissions.size(); 7506 for (int i = 0; i < N; i++) { 7507 final int targetUid = mGrantedUriPermissions.keyAt(i); 7508 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7509 7510 // Only inspect grants matching user 7511 if (userHandle == UserHandle.USER_ALL 7512 || userHandle == UserHandle.getUserId(targetUid)) { 7513 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7514 final UriPermission perm = it.next(); 7515 7516 // Only inspect grants matching package 7517 if (packageName == null || perm.sourcePkg.equals(packageName) 7518 || perm.targetPkg.equals(packageName)) { 7519 persistChanged |= perm.revokeModes(persistable 7520 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7521 7522 // Only remove when no modes remain; any persisted grants 7523 // will keep this alive. 7524 if (perm.modeFlags == 0) { 7525 it.remove(); 7526 } 7527 } 7528 } 7529 7530 if (perms.isEmpty()) { 7531 mGrantedUriPermissions.remove(targetUid); 7532 N--; 7533 i--; 7534 } 7535 } 7536 } 7537 7538 if (persistChanged) { 7539 schedulePersistUriGrants(); 7540 } 7541 } 7542 7543 @Override 7544 public IBinder newUriPermissionOwner(String name) { 7545 enforceNotIsolatedCaller("newUriPermissionOwner"); 7546 synchronized(this) { 7547 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7548 return owner.getExternalTokenLocked(); 7549 } 7550 } 7551 7552 /** 7553 * @param uri This uri must NOT contain an embedded userId. 7554 * @param sourceUserId The userId in which the uri is to be resolved. 7555 * @param targetUserId The userId of the app that receives the grant. 7556 */ 7557 @Override 7558 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7559 final int modeFlags, int sourceUserId, int targetUserId) { 7560 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7561 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7562 synchronized(this) { 7563 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7564 if (owner == null) { 7565 throw new IllegalArgumentException("Unknown owner: " + token); 7566 } 7567 if (fromUid != Binder.getCallingUid()) { 7568 if (Binder.getCallingUid() != Process.myUid()) { 7569 // Only system code can grant URI permissions on behalf 7570 // of other users. 7571 throw new SecurityException("nice try"); 7572 } 7573 } 7574 if (targetPkg == null) { 7575 throw new IllegalArgumentException("null target"); 7576 } 7577 if (uri == null) { 7578 throw new IllegalArgumentException("null uri"); 7579 } 7580 7581 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7582 modeFlags, owner, targetUserId); 7583 } 7584 } 7585 7586 /** 7587 * @param uri This uri must NOT contain an embedded userId. 7588 * @param userId The userId in which the uri is to be resolved. 7589 */ 7590 @Override 7591 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7592 synchronized(this) { 7593 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7594 if (owner == null) { 7595 throw new IllegalArgumentException("Unknown owner: " + token); 7596 } 7597 7598 if (uri == null) { 7599 owner.removeUriPermissionsLocked(mode); 7600 } else { 7601 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7602 } 7603 } 7604 } 7605 7606 private void schedulePersistUriGrants() { 7607 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7608 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7609 10 * DateUtils.SECOND_IN_MILLIS); 7610 } 7611 } 7612 7613 private void writeGrantedUriPermissions() { 7614 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7615 7616 // Snapshot permissions so we can persist without lock 7617 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7618 synchronized (this) { 7619 final int size = mGrantedUriPermissions.size(); 7620 for (int i = 0; i < size; i++) { 7621 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7622 for (UriPermission perm : perms.values()) { 7623 if (perm.persistedModeFlags != 0) { 7624 persist.add(perm.snapshot()); 7625 } 7626 } 7627 } 7628 } 7629 7630 FileOutputStream fos = null; 7631 try { 7632 fos = mGrantFile.startWrite(); 7633 7634 XmlSerializer out = new FastXmlSerializer(); 7635 out.setOutput(fos, "utf-8"); 7636 out.startDocument(null, true); 7637 out.startTag(null, TAG_URI_GRANTS); 7638 for (UriPermission.Snapshot perm : persist) { 7639 out.startTag(null, TAG_URI_GRANT); 7640 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7641 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7642 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7643 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7644 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7645 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7646 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7647 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7648 out.endTag(null, TAG_URI_GRANT); 7649 } 7650 out.endTag(null, TAG_URI_GRANTS); 7651 out.endDocument(); 7652 7653 mGrantFile.finishWrite(fos); 7654 } catch (IOException e) { 7655 if (fos != null) { 7656 mGrantFile.failWrite(fos); 7657 } 7658 } 7659 } 7660 7661 private void readGrantedUriPermissionsLocked() { 7662 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7663 7664 final long now = System.currentTimeMillis(); 7665 7666 FileInputStream fis = null; 7667 try { 7668 fis = mGrantFile.openRead(); 7669 final XmlPullParser in = Xml.newPullParser(); 7670 in.setInput(fis, null); 7671 7672 int type; 7673 while ((type = in.next()) != END_DOCUMENT) { 7674 final String tag = in.getName(); 7675 if (type == START_TAG) { 7676 if (TAG_URI_GRANT.equals(tag)) { 7677 final int sourceUserId; 7678 final int targetUserId; 7679 final int userHandle = readIntAttribute(in, 7680 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7681 if (userHandle != UserHandle.USER_NULL) { 7682 // For backwards compatibility. 7683 sourceUserId = userHandle; 7684 targetUserId = userHandle; 7685 } else { 7686 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7687 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7688 } 7689 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7690 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7691 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7692 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7693 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7694 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7695 7696 // Sanity check that provider still belongs to source package 7697 final ProviderInfo pi = getProviderInfoLocked( 7698 uri.getAuthority(), sourceUserId); 7699 if (pi != null && sourcePkg.equals(pi.packageName)) { 7700 int targetUid = -1; 7701 try { 7702 targetUid = AppGlobals.getPackageManager() 7703 .getPackageUid(targetPkg, targetUserId); 7704 } catch (RemoteException e) { 7705 } 7706 if (targetUid != -1) { 7707 final UriPermission perm = findOrCreateUriPermissionLocked( 7708 sourcePkg, targetPkg, targetUid, 7709 new GrantUri(sourceUserId, uri, prefix)); 7710 perm.initPersistedModes(modeFlags, createdTime); 7711 } 7712 } else { 7713 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7714 + " but instead found " + pi); 7715 } 7716 } 7717 } 7718 } 7719 } catch (FileNotFoundException e) { 7720 // Missing grants is okay 7721 } catch (IOException e) { 7722 Slog.wtf(TAG, "Failed reading Uri grants", e); 7723 } catch (XmlPullParserException e) { 7724 Slog.wtf(TAG, "Failed reading Uri grants", e); 7725 } finally { 7726 IoUtils.closeQuietly(fis); 7727 } 7728 } 7729 7730 /** 7731 * @param uri This uri must NOT contain an embedded userId. 7732 * @param userId The userId in which the uri is to be resolved. 7733 */ 7734 @Override 7735 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7736 enforceNotIsolatedCaller("takePersistableUriPermission"); 7737 7738 Preconditions.checkFlagsArgument(modeFlags, 7739 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7740 7741 synchronized (this) { 7742 final int callingUid = Binder.getCallingUid(); 7743 boolean persistChanged = false; 7744 GrantUri grantUri = new GrantUri(userId, uri, false); 7745 7746 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7747 new GrantUri(userId, uri, false)); 7748 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7749 new GrantUri(userId, uri, true)); 7750 7751 final boolean exactValid = (exactPerm != null) 7752 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7753 final boolean prefixValid = (prefixPerm != null) 7754 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7755 7756 if (!(exactValid || prefixValid)) { 7757 throw new SecurityException("No persistable permission grants found for UID " 7758 + callingUid + " and Uri " + grantUri.toSafeString()); 7759 } 7760 7761 if (exactValid) { 7762 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7763 } 7764 if (prefixValid) { 7765 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7766 } 7767 7768 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7769 7770 if (persistChanged) { 7771 schedulePersistUriGrants(); 7772 } 7773 } 7774 } 7775 7776 /** 7777 * @param uri This uri must NOT contain an embedded userId. 7778 * @param userId The userId in which the uri is to be resolved. 7779 */ 7780 @Override 7781 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7782 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7783 7784 Preconditions.checkFlagsArgument(modeFlags, 7785 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7786 7787 synchronized (this) { 7788 final int callingUid = Binder.getCallingUid(); 7789 boolean persistChanged = false; 7790 7791 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7792 new GrantUri(userId, uri, false)); 7793 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7794 new GrantUri(userId, uri, true)); 7795 if (exactPerm == null && prefixPerm == null) { 7796 throw new SecurityException("No permission grants found for UID " + callingUid 7797 + " and Uri " + uri.toSafeString()); 7798 } 7799 7800 if (exactPerm != null) { 7801 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7802 removeUriPermissionIfNeededLocked(exactPerm); 7803 } 7804 if (prefixPerm != null) { 7805 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7806 removeUriPermissionIfNeededLocked(prefixPerm); 7807 } 7808 7809 if (persistChanged) { 7810 schedulePersistUriGrants(); 7811 } 7812 } 7813 } 7814 7815 /** 7816 * Prune any older {@link UriPermission} for the given UID until outstanding 7817 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7818 * 7819 * @return if any mutations occured that require persisting. 7820 */ 7821 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7822 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7823 if (perms == null) return false; 7824 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7825 7826 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7827 for (UriPermission perm : perms.values()) { 7828 if (perm.persistedModeFlags != 0) { 7829 persisted.add(perm); 7830 } 7831 } 7832 7833 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7834 if (trimCount <= 0) return false; 7835 7836 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7837 for (int i = 0; i < trimCount; i++) { 7838 final UriPermission perm = persisted.get(i); 7839 7840 if (DEBUG_URI_PERMISSION) { 7841 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7842 } 7843 7844 perm.releasePersistableModes(~0); 7845 removeUriPermissionIfNeededLocked(perm); 7846 } 7847 7848 return true; 7849 } 7850 7851 @Override 7852 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7853 String packageName, boolean incoming) { 7854 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7855 Preconditions.checkNotNull(packageName, "packageName"); 7856 7857 final int callingUid = Binder.getCallingUid(); 7858 final IPackageManager pm = AppGlobals.getPackageManager(); 7859 try { 7860 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7861 if (packageUid != callingUid) { 7862 throw new SecurityException( 7863 "Package " + packageName + " does not belong to calling UID " + callingUid); 7864 } 7865 } catch (RemoteException e) { 7866 throw new SecurityException("Failed to verify package name ownership"); 7867 } 7868 7869 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7870 synchronized (this) { 7871 if (incoming) { 7872 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7873 callingUid); 7874 if (perms == null) { 7875 Slog.w(TAG, "No permission grants found for " + packageName); 7876 } else { 7877 for (UriPermission perm : perms.values()) { 7878 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7879 result.add(perm.buildPersistedPublicApiObject()); 7880 } 7881 } 7882 } 7883 } else { 7884 final int size = mGrantedUriPermissions.size(); 7885 for (int i = 0; i < size; i++) { 7886 final ArrayMap<GrantUri, UriPermission> perms = 7887 mGrantedUriPermissions.valueAt(i); 7888 for (UriPermission perm : perms.values()) { 7889 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7890 result.add(perm.buildPersistedPublicApiObject()); 7891 } 7892 } 7893 } 7894 } 7895 } 7896 return new ParceledListSlice<android.content.UriPermission>(result); 7897 } 7898 7899 @Override 7900 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7901 synchronized (this) { 7902 ProcessRecord app = 7903 who != null ? getRecordForAppLocked(who) : null; 7904 if (app == null) return; 7905 7906 Message msg = Message.obtain(); 7907 msg.what = WAIT_FOR_DEBUGGER_MSG; 7908 msg.obj = app; 7909 msg.arg1 = waiting ? 1 : 0; 7910 mHandler.sendMessage(msg); 7911 } 7912 } 7913 7914 @Override 7915 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7916 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7917 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7918 outInfo.availMem = Process.getFreeMemory(); 7919 outInfo.totalMem = Process.getTotalMemory(); 7920 outInfo.threshold = homeAppMem; 7921 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7922 outInfo.hiddenAppThreshold = cachedAppMem; 7923 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7924 ProcessList.SERVICE_ADJ); 7925 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7926 ProcessList.VISIBLE_APP_ADJ); 7927 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7928 ProcessList.FOREGROUND_APP_ADJ); 7929 } 7930 7931 // ========================================================= 7932 // TASK MANAGEMENT 7933 // ========================================================= 7934 7935 @Override 7936 public List<IAppTask> getAppTasks(String callingPackage) { 7937 int callingUid = Binder.getCallingUid(); 7938 long ident = Binder.clearCallingIdentity(); 7939 7940 synchronized(this) { 7941 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7942 try { 7943 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7944 7945 final int N = mRecentTasks.size(); 7946 for (int i = 0; i < N; i++) { 7947 TaskRecord tr = mRecentTasks.get(i); 7948 // Skip tasks that do not match the caller. We don't need to verify 7949 // callingPackage, because we are also limiting to callingUid and know 7950 // that will limit to the correct security sandbox. 7951 if (tr.effectiveUid != callingUid) { 7952 continue; 7953 } 7954 Intent intent = tr.getBaseIntent(); 7955 if (intent == null || 7956 !callingPackage.equals(intent.getComponent().getPackageName())) { 7957 continue; 7958 } 7959 ActivityManager.RecentTaskInfo taskInfo = 7960 createRecentTaskInfoFromTaskRecord(tr); 7961 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7962 list.add(taskImpl); 7963 } 7964 } finally { 7965 Binder.restoreCallingIdentity(ident); 7966 } 7967 return list; 7968 } 7969 } 7970 7971 @Override 7972 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7973 final int callingUid = Binder.getCallingUid(); 7974 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7975 7976 synchronized(this) { 7977 if (localLOGV) Slog.v( 7978 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7979 7980 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 7981 callingUid); 7982 7983 // TODO: Improve with MRU list from all ActivityStacks. 7984 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7985 } 7986 7987 return list; 7988 } 7989 7990 TaskRecord getMostRecentTask() { 7991 return mRecentTasks.get(0); 7992 } 7993 7994 /** 7995 * Creates a new RecentTaskInfo from a TaskRecord. 7996 */ 7997 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7998 // Update the task description to reflect any changes in the task stack 7999 tr.updateTaskDescription(); 8000 8001 // Compose the recent task info 8002 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8003 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8004 rti.persistentId = tr.taskId; 8005 rti.baseIntent = new Intent(tr.getBaseIntent()); 8006 rti.origActivity = tr.origActivity; 8007 rti.description = tr.lastDescription; 8008 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8009 rti.userId = tr.userId; 8010 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8011 rti.firstActiveTime = tr.firstActiveTime; 8012 rti.lastActiveTime = tr.lastActiveTime; 8013 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8014 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8015 return rti; 8016 } 8017 8018 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8019 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8020 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8021 if (!allowed) { 8022 if (checkPermission(android.Manifest.permission.GET_TASKS, 8023 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8024 // Temporary compatibility: some existing apps on the system image may 8025 // still be requesting the old permission and not switched to the new 8026 // one; if so, we'll still allow them full access. This means we need 8027 // to see if they are holding the old permission and are a system app. 8028 try { 8029 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8030 allowed = true; 8031 Slog.w(TAG, caller + ": caller " + callingUid 8032 + " is using old GET_TASKS but privileged; allowing"); 8033 } 8034 } catch (RemoteException e) { 8035 } 8036 } 8037 } 8038 if (!allowed) { 8039 Slog.w(TAG, caller + ": caller " + callingUid 8040 + " does not hold GET_TASKS; limiting output"); 8041 } 8042 return allowed; 8043 } 8044 8045 @Override 8046 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8047 final int callingUid = Binder.getCallingUid(); 8048 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8049 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8050 8051 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8052 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8053 synchronized (this) { 8054 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8055 callingUid); 8056 final boolean detailed = checkCallingPermission( 8057 android.Manifest.permission.GET_DETAILED_TASKS) 8058 == PackageManager.PERMISSION_GRANTED; 8059 8060 final int N = mRecentTasks.size(); 8061 ArrayList<ActivityManager.RecentTaskInfo> res 8062 = new ArrayList<ActivityManager.RecentTaskInfo>( 8063 maxNum < N ? maxNum : N); 8064 8065 final Set<Integer> includedUsers; 8066 if (includeProfiles) { 8067 includedUsers = getProfileIdsLocked(userId); 8068 } else { 8069 includedUsers = new HashSet<Integer>(); 8070 } 8071 includedUsers.add(Integer.valueOf(userId)); 8072 8073 for (int i=0; i<N && maxNum > 0; i++) { 8074 TaskRecord tr = mRecentTasks.get(i); 8075 // Only add calling user or related users recent tasks 8076 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8077 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8078 continue; 8079 } 8080 8081 // Return the entry if desired by the caller. We always return 8082 // the first entry, because callers always expect this to be the 8083 // foreground app. We may filter others if the caller has 8084 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8085 // we should exclude the entry. 8086 8087 if (i == 0 8088 || withExcluded 8089 || (tr.intent == null) 8090 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8091 == 0)) { 8092 if (!allowed) { 8093 // If the caller doesn't have the GET_TASKS permission, then only 8094 // allow them to see a small subset of tasks -- their own and home. 8095 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8096 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8097 continue; 8098 } 8099 } 8100 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8101 if (tr.stack != null && tr.stack.isHomeStack()) { 8102 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8103 continue; 8104 } 8105 } 8106 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8107 // Don't include auto remove tasks that are finished or finishing. 8108 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8109 + tr); 8110 continue; 8111 } 8112 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8113 && !tr.isAvailable) { 8114 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8115 continue; 8116 } 8117 8118 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8119 if (!detailed) { 8120 rti.baseIntent.replaceExtras((Bundle)null); 8121 } 8122 8123 res.add(rti); 8124 maxNum--; 8125 } 8126 } 8127 return res; 8128 } 8129 } 8130 8131 private TaskRecord taskForIdLocked(int id) { 8132 final TaskRecord task = recentTaskForIdLocked(id); 8133 if (task != null) { 8134 return task; 8135 } 8136 8137 // Don't give up. Sometimes it just hasn't made it to recents yet. 8138 return mStackSupervisor.anyTaskForIdLocked(id); 8139 } 8140 8141 private TaskRecord recentTaskForIdLocked(int id) { 8142 final int N = mRecentTasks.size(); 8143 for (int i=0; i<N; i++) { 8144 TaskRecord tr = mRecentTasks.get(i); 8145 if (tr.taskId == id) { 8146 return tr; 8147 } 8148 } 8149 return null; 8150 } 8151 8152 @Override 8153 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8154 synchronized (this) { 8155 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8156 "getTaskThumbnail()"); 8157 TaskRecord tr = recentTaskForIdLocked(id); 8158 if (tr != null) { 8159 return tr.getTaskThumbnailLocked(); 8160 } 8161 } 8162 return null; 8163 } 8164 8165 @Override 8166 public int addAppTask(IBinder activityToken, Intent intent, 8167 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8168 final int callingUid = Binder.getCallingUid(); 8169 final long callingIdent = Binder.clearCallingIdentity(); 8170 8171 try { 8172 synchronized (this) { 8173 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8174 if (r == null) { 8175 throw new IllegalArgumentException("Activity does not exist; token=" 8176 + activityToken); 8177 } 8178 ComponentName comp = intent.getComponent(); 8179 if (comp == null) { 8180 throw new IllegalArgumentException("Intent " + intent 8181 + " must specify explicit component"); 8182 } 8183 if (thumbnail.getWidth() != mThumbnailWidth 8184 || thumbnail.getHeight() != mThumbnailHeight) { 8185 throw new IllegalArgumentException("Bad thumbnail size: got " 8186 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8187 + mThumbnailWidth + "x" + mThumbnailHeight); 8188 } 8189 if (intent.getSelector() != null) { 8190 intent.setSelector(null); 8191 } 8192 if (intent.getSourceBounds() != null) { 8193 intent.setSourceBounds(null); 8194 } 8195 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8196 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8197 // The caller has added this as an auto-remove task... that makes no 8198 // sense, so turn off auto-remove. 8199 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8200 } 8201 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8202 // Must be a new task. 8203 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8204 } 8205 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8206 mLastAddedTaskActivity = null; 8207 } 8208 ActivityInfo ainfo = mLastAddedTaskActivity; 8209 if (ainfo == null) { 8210 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8211 comp, 0, UserHandle.getUserId(callingUid)); 8212 if (ainfo.applicationInfo.uid != callingUid) { 8213 throw new SecurityException( 8214 "Can't add task for another application: target uid=" 8215 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8216 } 8217 } 8218 8219 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8220 intent, description); 8221 8222 int trimIdx = trimRecentsForTask(task, false); 8223 if (trimIdx >= 0) { 8224 // If this would have caused a trim, then we'll abort because that 8225 // means it would be added at the end of the list but then just removed. 8226 return -1; 8227 } 8228 8229 final int N = mRecentTasks.size(); 8230 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8231 final TaskRecord tr = mRecentTasks.remove(N - 1); 8232 tr.removedFromRecents(mTaskPersister); 8233 } 8234 8235 task.inRecents = true; 8236 mRecentTasks.add(task); 8237 r.task.stack.addTask(task, false, false); 8238 8239 task.setLastThumbnail(thumbnail); 8240 task.freeLastThumbnail(); 8241 8242 return task.taskId; 8243 } 8244 } finally { 8245 Binder.restoreCallingIdentity(callingIdent); 8246 } 8247 } 8248 8249 @Override 8250 public Point getAppTaskThumbnailSize() { 8251 synchronized (this) { 8252 return new Point(mThumbnailWidth, mThumbnailHeight); 8253 } 8254 } 8255 8256 @Override 8257 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8258 synchronized (this) { 8259 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8260 if (r != null) { 8261 r.setTaskDescription(td); 8262 r.task.updateTaskDescription(); 8263 } 8264 } 8265 } 8266 8267 @Override 8268 public Bitmap getTaskDescriptionIcon(String filename) { 8269 if (!FileUtils.isValidExtFilename(filename) 8270 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8271 throw new IllegalArgumentException("Bad filename: " + filename); 8272 } 8273 return mTaskPersister.getTaskDescriptionIcon(filename); 8274 } 8275 8276 @Override 8277 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8278 throws RemoteException { 8279 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8280 opts.getCustomInPlaceResId() == 0) { 8281 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8282 "with valid animation"); 8283 } 8284 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8285 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8286 opts.getCustomInPlaceResId()); 8287 mWindowManager.executeAppTransition(); 8288 } 8289 8290 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8291 mRecentTasks.remove(tr); 8292 tr.removedFromRecents(mTaskPersister); 8293 ComponentName component = tr.getBaseIntent().getComponent(); 8294 if (component == null) { 8295 Slog.w(TAG, "No component for base intent of task: " + tr); 8296 return; 8297 } 8298 8299 if (!killProcess) { 8300 return; 8301 } 8302 8303 // Determine if the process(es) for this task should be killed. 8304 final String pkg = component.getPackageName(); 8305 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8306 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8307 for (int i = 0; i < pmap.size(); i++) { 8308 8309 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8310 for (int j = 0; j < uids.size(); j++) { 8311 ProcessRecord proc = uids.valueAt(j); 8312 if (proc.userId != tr.userId) { 8313 // Don't kill process for a different user. 8314 continue; 8315 } 8316 if (proc == mHomeProcess) { 8317 // Don't kill the home process along with tasks from the same package. 8318 continue; 8319 } 8320 if (!proc.pkgList.containsKey(pkg)) { 8321 // Don't kill process that is not associated with this task. 8322 continue; 8323 } 8324 8325 for (int k = 0; k < proc.activities.size(); k++) { 8326 TaskRecord otherTask = proc.activities.get(k).task; 8327 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8328 // Don't kill process(es) that has an activity in a different task that is 8329 // also in recents. 8330 return; 8331 } 8332 } 8333 8334 // Add process to kill list. 8335 procsToKill.add(proc); 8336 } 8337 } 8338 8339 // Find any running services associated with this app and stop if needed. 8340 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8341 8342 // Kill the running processes. 8343 for (int i = 0; i < procsToKill.size(); i++) { 8344 ProcessRecord pr = procsToKill.get(i); 8345 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8346 pr.kill("remove task", true); 8347 } else { 8348 pr.waitingToKill = "remove task"; 8349 } 8350 } 8351 } 8352 8353 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8354 // Remove all tasks with activities in the specified package from the list of recent tasks 8355 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8356 TaskRecord tr = mRecentTasks.get(i); 8357 if (tr.userId != userId) continue; 8358 8359 ComponentName cn = tr.intent.getComponent(); 8360 if (cn != null && cn.getPackageName().equals(packageName)) { 8361 // If the package name matches, remove the task. 8362 removeTaskByIdLocked(tr.taskId, true); 8363 } 8364 } 8365 } 8366 8367 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8368 final IPackageManager pm = AppGlobals.getPackageManager(); 8369 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8370 8371 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8372 TaskRecord tr = mRecentTasks.get(i); 8373 if (tr.userId != userId) continue; 8374 8375 ComponentName cn = tr.intent.getComponent(); 8376 if (cn != null && cn.getPackageName().equals(packageName)) { 8377 // Skip if component still exists in the package. 8378 if (componentsKnownToExist.contains(cn)) continue; 8379 8380 try { 8381 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8382 if (info != null) { 8383 componentsKnownToExist.add(cn); 8384 } else { 8385 removeTaskByIdLocked(tr.taskId, false); 8386 } 8387 } catch (RemoteException e) { 8388 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8389 } 8390 } 8391 } 8392 } 8393 8394 /** 8395 * Removes the task with the specified task id. 8396 * 8397 * @param taskId Identifier of the task to be removed. 8398 * @param killProcess Kill any process associated with the task if possible. 8399 * @return Returns true if the given task was found and removed. 8400 */ 8401 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8402 TaskRecord tr = taskForIdLocked(taskId); 8403 if (tr != null) { 8404 tr.removeTaskActivitiesLocked(); 8405 cleanUpRemovedTaskLocked(tr, killProcess); 8406 if (tr.isPersistable) { 8407 notifyTaskPersisterLocked(null, true); 8408 } 8409 return true; 8410 } 8411 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8412 return false; 8413 } 8414 8415 @Override 8416 public boolean removeTask(int taskId) { 8417 synchronized (this) { 8418 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8419 "removeTask()"); 8420 long ident = Binder.clearCallingIdentity(); 8421 try { 8422 return removeTaskByIdLocked(taskId, true); 8423 } finally { 8424 Binder.restoreCallingIdentity(ident); 8425 } 8426 } 8427 } 8428 8429 /** 8430 * TODO: Add mController hook 8431 */ 8432 @Override 8433 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8434 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8435 "moveTaskToFront()"); 8436 8437 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8438 synchronized(this) { 8439 moveTaskToFrontLocked(taskId, flags, options); 8440 } 8441 } 8442 8443 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8444 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8445 Binder.getCallingUid(), -1, -1, "Task to front")) { 8446 ActivityOptions.abort(options); 8447 return; 8448 } 8449 final long origId = Binder.clearCallingIdentity(); 8450 try { 8451 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8452 if (task == null) { 8453 Slog.d(TAG, "Could not find task for id: "+ taskId); 8454 return; 8455 } 8456 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8457 mStackSupervisor.showLockTaskToast(); 8458 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8459 return; 8460 } 8461 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8462 if (prev != null && prev.isRecentsActivity()) { 8463 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8464 } 8465 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8466 } finally { 8467 Binder.restoreCallingIdentity(origId); 8468 } 8469 ActivityOptions.abort(options); 8470 } 8471 8472 @Override 8473 public void moveTaskToBack(int taskId) { 8474 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8475 "moveTaskToBack()"); 8476 8477 synchronized(this) { 8478 TaskRecord tr = taskForIdLocked(taskId); 8479 if (tr != null) { 8480 if (tr == mStackSupervisor.mLockTaskModeTask) { 8481 mStackSupervisor.showLockTaskToast(); 8482 return; 8483 } 8484 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8485 ActivityStack stack = tr.stack; 8486 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8487 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8488 Binder.getCallingUid(), -1, -1, "Task to back")) { 8489 return; 8490 } 8491 } 8492 final long origId = Binder.clearCallingIdentity(); 8493 try { 8494 stack.moveTaskToBackLocked(taskId, null); 8495 } finally { 8496 Binder.restoreCallingIdentity(origId); 8497 } 8498 } 8499 } 8500 } 8501 8502 /** 8503 * Moves an activity, and all of the other activities within the same task, to the bottom 8504 * of the history stack. The activity's order within the task is unchanged. 8505 * 8506 * @param token A reference to the activity we wish to move 8507 * @param nonRoot If false then this only works if the activity is the root 8508 * of a task; if true it will work for any activity in a task. 8509 * @return Returns true if the move completed, false if not. 8510 */ 8511 @Override 8512 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8513 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8514 synchronized(this) { 8515 final long origId = Binder.clearCallingIdentity(); 8516 try { 8517 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8518 if (taskId >= 0) { 8519 if ((mStackSupervisor.mLockTaskModeTask != null) 8520 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8521 mStackSupervisor.showLockTaskToast(); 8522 return false; 8523 } 8524 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8525 } 8526 } finally { 8527 Binder.restoreCallingIdentity(origId); 8528 } 8529 } 8530 return false; 8531 } 8532 8533 @Override 8534 public void moveTaskBackwards(int task) { 8535 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8536 "moveTaskBackwards()"); 8537 8538 synchronized(this) { 8539 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8540 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8541 return; 8542 } 8543 final long origId = Binder.clearCallingIdentity(); 8544 moveTaskBackwardsLocked(task); 8545 Binder.restoreCallingIdentity(origId); 8546 } 8547 } 8548 8549 private final void moveTaskBackwardsLocked(int task) { 8550 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8551 } 8552 8553 @Override 8554 public IBinder getHomeActivityToken() throws RemoteException { 8555 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8556 "getHomeActivityToken()"); 8557 synchronized (this) { 8558 return mStackSupervisor.getHomeActivityToken(); 8559 } 8560 } 8561 8562 @Override 8563 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8564 IActivityContainerCallback callback) throws RemoteException { 8565 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8566 "createActivityContainer()"); 8567 synchronized (this) { 8568 if (parentActivityToken == null) { 8569 throw new IllegalArgumentException("parent token must not be null"); 8570 } 8571 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8572 if (r == null) { 8573 return null; 8574 } 8575 if (callback == null) { 8576 throw new IllegalArgumentException("callback must not be null"); 8577 } 8578 return mStackSupervisor.createActivityContainer(r, callback); 8579 } 8580 } 8581 8582 @Override 8583 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8584 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8585 "deleteActivityContainer()"); 8586 synchronized (this) { 8587 mStackSupervisor.deleteActivityContainer(container); 8588 } 8589 } 8590 8591 @Override 8592 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8593 throws RemoteException { 8594 synchronized (this) { 8595 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8596 if (stack != null) { 8597 return stack.mActivityContainer; 8598 } 8599 return null; 8600 } 8601 } 8602 8603 @Override 8604 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8605 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8606 "moveTaskToStack()"); 8607 if (stackId == HOME_STACK_ID) { 8608 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8609 new RuntimeException("here").fillInStackTrace()); 8610 } 8611 synchronized (this) { 8612 long ident = Binder.clearCallingIdentity(); 8613 try { 8614 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8615 + stackId + " toTop=" + toTop); 8616 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8617 } finally { 8618 Binder.restoreCallingIdentity(ident); 8619 } 8620 } 8621 } 8622 8623 @Override 8624 public void resizeStack(int stackBoxId, Rect bounds) { 8625 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8626 "resizeStackBox()"); 8627 long ident = Binder.clearCallingIdentity(); 8628 try { 8629 mWindowManager.resizeStack(stackBoxId, bounds); 8630 } finally { 8631 Binder.restoreCallingIdentity(ident); 8632 } 8633 } 8634 8635 @Override 8636 public List<StackInfo> getAllStackInfos() { 8637 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8638 "getAllStackInfos()"); 8639 long ident = Binder.clearCallingIdentity(); 8640 try { 8641 synchronized (this) { 8642 return mStackSupervisor.getAllStackInfosLocked(); 8643 } 8644 } finally { 8645 Binder.restoreCallingIdentity(ident); 8646 } 8647 } 8648 8649 @Override 8650 public StackInfo getStackInfo(int stackId) { 8651 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8652 "getStackInfo()"); 8653 long ident = Binder.clearCallingIdentity(); 8654 try { 8655 synchronized (this) { 8656 return mStackSupervisor.getStackInfoLocked(stackId); 8657 } 8658 } finally { 8659 Binder.restoreCallingIdentity(ident); 8660 } 8661 } 8662 8663 @Override 8664 public boolean isInHomeStack(int taskId) { 8665 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8666 "getStackInfo()"); 8667 long ident = Binder.clearCallingIdentity(); 8668 try { 8669 synchronized (this) { 8670 TaskRecord tr = taskForIdLocked(taskId); 8671 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8672 } 8673 } finally { 8674 Binder.restoreCallingIdentity(ident); 8675 } 8676 } 8677 8678 @Override 8679 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8680 synchronized(this) { 8681 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8682 } 8683 } 8684 8685 private boolean isLockTaskAuthorized(String pkg) { 8686 final DevicePolicyManager dpm = (DevicePolicyManager) 8687 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8688 try { 8689 int uid = mContext.getPackageManager().getPackageUid(pkg, 8690 Binder.getCallingUserHandle().getIdentifier()); 8691 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8692 } catch (NameNotFoundException e) { 8693 return false; 8694 } 8695 } 8696 8697 void startLockTaskMode(TaskRecord task) { 8698 final String pkg; 8699 synchronized (this) { 8700 pkg = task.intent.getComponent().getPackageName(); 8701 } 8702 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8703 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8704 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8705 StatusBarManagerInternal.class); 8706 if (statusBarManager != null) { 8707 statusBarManager.showScreenPinningRequest(); 8708 } 8709 return; 8710 } 8711 long ident = Binder.clearCallingIdentity(); 8712 try { 8713 synchronized (this) { 8714 // Since we lost lock on task, make sure it is still there. 8715 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8716 if (task != null) { 8717 if (!isSystemInitiated 8718 && ((mStackSupervisor.getFocusedStack() == null) 8719 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8720 throw new IllegalArgumentException("Invalid task, not in foreground"); 8721 } 8722 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8723 } 8724 } 8725 } finally { 8726 Binder.restoreCallingIdentity(ident); 8727 } 8728 } 8729 8730 @Override 8731 public void startLockTaskMode(int taskId) { 8732 final TaskRecord task; 8733 long ident = Binder.clearCallingIdentity(); 8734 try { 8735 synchronized (this) { 8736 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8737 } 8738 } finally { 8739 Binder.restoreCallingIdentity(ident); 8740 } 8741 if (task != null) { 8742 startLockTaskMode(task); 8743 } 8744 } 8745 8746 @Override 8747 public void startLockTaskMode(IBinder token) { 8748 final TaskRecord task; 8749 long ident = Binder.clearCallingIdentity(); 8750 try { 8751 synchronized (this) { 8752 final ActivityRecord r = ActivityRecord.forToken(token); 8753 if (r == null) { 8754 return; 8755 } 8756 task = r.task; 8757 } 8758 } finally { 8759 Binder.restoreCallingIdentity(ident); 8760 } 8761 if (task != null) { 8762 startLockTaskMode(task); 8763 } 8764 } 8765 8766 @Override 8767 public void startLockTaskModeOnCurrent() throws RemoteException { 8768 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8769 "startLockTaskModeOnCurrent"); 8770 long ident = Binder.clearCallingIdentity(); 8771 try { 8772 ActivityRecord r = null; 8773 synchronized (this) { 8774 r = mStackSupervisor.topRunningActivityLocked(); 8775 } 8776 startLockTaskMode(r.task); 8777 } finally { 8778 Binder.restoreCallingIdentity(ident); 8779 } 8780 } 8781 8782 @Override 8783 public void stopLockTaskMode() { 8784 // Verify that the user matches the package of the intent for the TaskRecord 8785 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8786 // and stopLockTaskMode. 8787 final int callingUid = Binder.getCallingUid(); 8788 if (callingUid != Process.SYSTEM_UID) { 8789 try { 8790 String pkg = 8791 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8792 int uid = mContext.getPackageManager().getPackageUid(pkg, 8793 Binder.getCallingUserHandle().getIdentifier()); 8794 if (uid != callingUid) { 8795 throw new SecurityException("Invalid uid, expected " + uid); 8796 } 8797 } catch (NameNotFoundException e) { 8798 Log.d(TAG, "stopLockTaskMode " + e); 8799 return; 8800 } 8801 } 8802 long ident = Binder.clearCallingIdentity(); 8803 try { 8804 Log.d(TAG, "stopLockTaskMode"); 8805 // Stop lock task 8806 synchronized (this) { 8807 mStackSupervisor.setLockTaskModeLocked(null, false); 8808 } 8809 } finally { 8810 Binder.restoreCallingIdentity(ident); 8811 } 8812 } 8813 8814 @Override 8815 public void stopLockTaskModeOnCurrent() throws RemoteException { 8816 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8817 "stopLockTaskModeOnCurrent"); 8818 long ident = Binder.clearCallingIdentity(); 8819 try { 8820 stopLockTaskMode(); 8821 } finally { 8822 Binder.restoreCallingIdentity(ident); 8823 } 8824 } 8825 8826 @Override 8827 public boolean isInLockTaskMode() { 8828 synchronized (this) { 8829 return mStackSupervisor.isInLockTaskMode(); 8830 } 8831 } 8832 8833 // ========================================================= 8834 // CONTENT PROVIDERS 8835 // ========================================================= 8836 8837 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8838 List<ProviderInfo> providers = null; 8839 try { 8840 providers = AppGlobals.getPackageManager(). 8841 queryContentProviders(app.processName, app.uid, 8842 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8843 } catch (RemoteException ex) { 8844 } 8845 if (DEBUG_MU) 8846 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8847 int userId = app.userId; 8848 if (providers != null) { 8849 int N = providers.size(); 8850 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8851 for (int i=0; i<N; i++) { 8852 ProviderInfo cpi = 8853 (ProviderInfo)providers.get(i); 8854 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8855 cpi.name, cpi.flags); 8856 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8857 // This is a singleton provider, but a user besides the 8858 // default user is asking to initialize a process it runs 8859 // in... well, no, it doesn't actually run in this process, 8860 // it runs in the process of the default user. Get rid of it. 8861 providers.remove(i); 8862 N--; 8863 i--; 8864 continue; 8865 } 8866 8867 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8868 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8869 if (cpr == null) { 8870 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8871 mProviderMap.putProviderByClass(comp, cpr); 8872 } 8873 if (DEBUG_MU) 8874 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8875 app.pubProviders.put(cpi.name, cpr); 8876 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8877 // Don't add this if it is a platform component that is marked 8878 // to run in multiple processes, because this is actually 8879 // part of the framework so doesn't make sense to track as a 8880 // separate apk in the process. 8881 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8882 mProcessStats); 8883 } 8884 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8885 } 8886 } 8887 return providers; 8888 } 8889 8890 /** 8891 * Check if {@link ProcessRecord} has a possible chance at accessing the 8892 * given {@link ProviderInfo}. Final permission checking is always done 8893 * in {@link ContentProvider}. 8894 */ 8895 private final String checkContentProviderPermissionLocked( 8896 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8897 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8898 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8899 boolean checkedGrants = false; 8900 if (checkUser) { 8901 // Looking for cross-user grants before enforcing the typical cross-users permissions 8902 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8903 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8904 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8905 return null; 8906 } 8907 checkedGrants = true; 8908 } 8909 userId = handleIncomingUser(callingPid, callingUid, userId, 8910 false, ALLOW_NON_FULL, 8911 "checkContentProviderPermissionLocked " + cpi.authority, null); 8912 if (userId != tmpTargetUserId) { 8913 // When we actually went to determine the final targer user ID, this ended 8914 // up different than our initial check for the authority. This is because 8915 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8916 // SELF. So we need to re-check the grants again. 8917 checkedGrants = false; 8918 } 8919 } 8920 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8921 cpi.applicationInfo.uid, cpi.exported) 8922 == PackageManager.PERMISSION_GRANTED) { 8923 return null; 8924 } 8925 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8926 cpi.applicationInfo.uid, cpi.exported) 8927 == PackageManager.PERMISSION_GRANTED) { 8928 return null; 8929 } 8930 8931 PathPermission[] pps = cpi.pathPermissions; 8932 if (pps != null) { 8933 int i = pps.length; 8934 while (i > 0) { 8935 i--; 8936 PathPermission pp = pps[i]; 8937 String pprperm = pp.getReadPermission(); 8938 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8939 cpi.applicationInfo.uid, cpi.exported) 8940 == PackageManager.PERMISSION_GRANTED) { 8941 return null; 8942 } 8943 String ppwperm = pp.getWritePermission(); 8944 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8945 cpi.applicationInfo.uid, cpi.exported) 8946 == PackageManager.PERMISSION_GRANTED) { 8947 return null; 8948 } 8949 } 8950 } 8951 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8952 return null; 8953 } 8954 8955 String msg; 8956 if (!cpi.exported) { 8957 msg = "Permission Denial: opening provider " + cpi.name 8958 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8959 + ", uid=" + callingUid + ") that is not exported from uid " 8960 + cpi.applicationInfo.uid; 8961 } else { 8962 msg = "Permission Denial: opening provider " + cpi.name 8963 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8964 + ", uid=" + callingUid + ") requires " 8965 + cpi.readPermission + " or " + cpi.writePermission; 8966 } 8967 Slog.w(TAG, msg); 8968 return msg; 8969 } 8970 8971 /** 8972 * Returns if the ContentProvider has granted a uri to callingUid 8973 */ 8974 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8975 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8976 if (perms != null) { 8977 for (int i=perms.size()-1; i>=0; i--) { 8978 GrantUri grantUri = perms.keyAt(i); 8979 if (grantUri.sourceUserId == userId || !checkUser) { 8980 if (matchesProvider(grantUri.uri, cpi)) { 8981 return true; 8982 } 8983 } 8984 } 8985 } 8986 return false; 8987 } 8988 8989 /** 8990 * Returns true if the uri authority is one of the authorities specified in the provider. 8991 */ 8992 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8993 String uriAuth = uri.getAuthority(); 8994 String cpiAuth = cpi.authority; 8995 if (cpiAuth.indexOf(';') == -1) { 8996 return cpiAuth.equals(uriAuth); 8997 } 8998 String[] cpiAuths = cpiAuth.split(";"); 8999 int length = cpiAuths.length; 9000 for (int i = 0; i < length; i++) { 9001 if (cpiAuths[i].equals(uriAuth)) return true; 9002 } 9003 return false; 9004 } 9005 9006 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9007 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9008 if (r != null) { 9009 for (int i=0; i<r.conProviders.size(); i++) { 9010 ContentProviderConnection conn = r.conProviders.get(i); 9011 if (conn.provider == cpr) { 9012 if (DEBUG_PROVIDER) Slog.v(TAG, 9013 "Adding provider requested by " 9014 + r.processName + " from process " 9015 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9016 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9017 if (stable) { 9018 conn.stableCount++; 9019 conn.numStableIncs++; 9020 } else { 9021 conn.unstableCount++; 9022 conn.numUnstableIncs++; 9023 } 9024 return conn; 9025 } 9026 } 9027 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9028 if (stable) { 9029 conn.stableCount = 1; 9030 conn.numStableIncs = 1; 9031 } else { 9032 conn.unstableCount = 1; 9033 conn.numUnstableIncs = 1; 9034 } 9035 cpr.connections.add(conn); 9036 r.conProviders.add(conn); 9037 return conn; 9038 } 9039 cpr.addExternalProcessHandleLocked(externalProcessToken); 9040 return null; 9041 } 9042 9043 boolean decProviderCountLocked(ContentProviderConnection conn, 9044 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9045 if (conn != null) { 9046 cpr = conn.provider; 9047 if (DEBUG_PROVIDER) Slog.v(TAG, 9048 "Removing provider requested by " 9049 + conn.client.processName + " from process " 9050 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9051 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9052 if (stable) { 9053 conn.stableCount--; 9054 } else { 9055 conn.unstableCount--; 9056 } 9057 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9058 cpr.connections.remove(conn); 9059 conn.client.conProviders.remove(conn); 9060 return true; 9061 } 9062 return false; 9063 } 9064 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9065 return false; 9066 } 9067 9068 private void checkTime(long startTime, String where) { 9069 long now = SystemClock.elapsedRealtime(); 9070 if ((now-startTime) > 1000) { 9071 // If we are taking more than a second, log about it. 9072 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9073 } 9074 } 9075 9076 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9077 String name, IBinder token, boolean stable, int userId) { 9078 ContentProviderRecord cpr; 9079 ContentProviderConnection conn = null; 9080 ProviderInfo cpi = null; 9081 9082 synchronized(this) { 9083 long startTime = SystemClock.elapsedRealtime(); 9084 9085 ProcessRecord r = null; 9086 if (caller != null) { 9087 r = getRecordForAppLocked(caller); 9088 if (r == null) { 9089 throw new SecurityException( 9090 "Unable to find app for caller " + caller 9091 + " (pid=" + Binder.getCallingPid() 9092 + ") when getting content provider " + name); 9093 } 9094 } 9095 9096 boolean checkCrossUser = true; 9097 9098 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9099 9100 // First check if this content provider has been published... 9101 cpr = mProviderMap.getProviderByName(name, userId); 9102 // If that didn't work, check if it exists for user 0 and then 9103 // verify that it's a singleton provider before using it. 9104 if (cpr == null && userId != UserHandle.USER_OWNER) { 9105 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9106 if (cpr != null) { 9107 cpi = cpr.info; 9108 if (isSingleton(cpi.processName, cpi.applicationInfo, 9109 cpi.name, cpi.flags) 9110 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9111 userId = UserHandle.USER_OWNER; 9112 checkCrossUser = false; 9113 } else { 9114 cpr = null; 9115 cpi = null; 9116 } 9117 } 9118 } 9119 9120 boolean providerRunning = cpr != null; 9121 if (providerRunning) { 9122 cpi = cpr.info; 9123 String msg; 9124 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9125 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9126 != null) { 9127 throw new SecurityException(msg); 9128 } 9129 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9130 9131 if (r != null && cpr.canRunHere(r)) { 9132 // This provider has been published or is in the process 9133 // of being published... but it is also allowed to run 9134 // in the caller's process, so don't make a connection 9135 // and just let the caller instantiate its own instance. 9136 ContentProviderHolder holder = cpr.newHolder(null); 9137 // don't give caller the provider object, it needs 9138 // to make its own. 9139 holder.provider = null; 9140 return holder; 9141 } 9142 9143 final long origId = Binder.clearCallingIdentity(); 9144 9145 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9146 9147 // In this case the provider instance already exists, so we can 9148 // return it right away. 9149 conn = incProviderCountLocked(r, cpr, token, stable); 9150 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9151 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9152 // If this is a perceptible app accessing the provider, 9153 // make sure to count it as being accessed and thus 9154 // back up on the LRU list. This is good because 9155 // content providers are often expensive to start. 9156 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9157 updateLruProcessLocked(cpr.proc, false, null); 9158 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9159 } 9160 } 9161 9162 if (cpr.proc != null) { 9163 if (false) { 9164 if (cpr.name.flattenToShortString().equals( 9165 "com.android.providers.calendar/.CalendarProvider2")) { 9166 Slog.v(TAG, "****************** KILLING " 9167 + cpr.name.flattenToShortString()); 9168 Process.killProcess(cpr.proc.pid); 9169 } 9170 } 9171 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9172 boolean success = updateOomAdjLocked(cpr.proc); 9173 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9174 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9175 // NOTE: there is still a race here where a signal could be 9176 // pending on the process even though we managed to update its 9177 // adj level. Not sure what to do about this, but at least 9178 // the race is now smaller. 9179 if (!success) { 9180 // Uh oh... it looks like the provider's process 9181 // has been killed on us. We need to wait for a new 9182 // process to be started, and make sure its death 9183 // doesn't kill our process. 9184 Slog.i(TAG, 9185 "Existing provider " + cpr.name.flattenToShortString() 9186 + " is crashing; detaching " + r); 9187 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9188 checkTime(startTime, "getContentProviderImpl: before appDied"); 9189 appDiedLocked(cpr.proc); 9190 checkTime(startTime, "getContentProviderImpl: after appDied"); 9191 if (!lastRef) { 9192 // This wasn't the last ref our process had on 9193 // the provider... we have now been killed, bail. 9194 return null; 9195 } 9196 providerRunning = false; 9197 conn = null; 9198 } 9199 } 9200 9201 Binder.restoreCallingIdentity(origId); 9202 } 9203 9204 boolean singleton; 9205 if (!providerRunning) { 9206 try { 9207 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9208 cpi = AppGlobals.getPackageManager(). 9209 resolveContentProvider(name, 9210 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9211 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9212 } catch (RemoteException ex) { 9213 } 9214 if (cpi == null) { 9215 return null; 9216 } 9217 // If the provider is a singleton AND 9218 // (it's a call within the same user || the provider is a 9219 // privileged app) 9220 // Then allow connecting to the singleton provider 9221 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9222 cpi.name, cpi.flags) 9223 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9224 if (singleton) { 9225 userId = UserHandle.USER_OWNER; 9226 } 9227 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9228 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9229 9230 String msg; 9231 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9232 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9233 != null) { 9234 throw new SecurityException(msg); 9235 } 9236 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9237 9238 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9239 && !cpi.processName.equals("system")) { 9240 // If this content provider does not run in the system 9241 // process, and the system is not yet ready to run other 9242 // processes, then fail fast instead of hanging. 9243 throw new IllegalArgumentException( 9244 "Attempt to launch content provider before system ready"); 9245 } 9246 9247 // Make sure that the user who owns this provider is started. If not, 9248 // we don't want to allow it to run. 9249 if (mStartedUsers.get(userId) == null) { 9250 Slog.w(TAG, "Unable to launch app " 9251 + cpi.applicationInfo.packageName + "/" 9252 + cpi.applicationInfo.uid + " for provider " 9253 + name + ": user " + userId + " is stopped"); 9254 return null; 9255 } 9256 9257 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9258 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9259 cpr = mProviderMap.getProviderByClass(comp, userId); 9260 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9261 final boolean firstClass = cpr == null; 9262 if (firstClass) { 9263 final long ident = Binder.clearCallingIdentity(); 9264 try { 9265 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9266 ApplicationInfo ai = 9267 AppGlobals.getPackageManager(). 9268 getApplicationInfo( 9269 cpi.applicationInfo.packageName, 9270 STOCK_PM_FLAGS, userId); 9271 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9272 if (ai == null) { 9273 Slog.w(TAG, "No package info for content provider " 9274 + cpi.name); 9275 return null; 9276 } 9277 ai = getAppInfoForUser(ai, userId); 9278 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9279 } catch (RemoteException ex) { 9280 // pm is in same process, this will never happen. 9281 } finally { 9282 Binder.restoreCallingIdentity(ident); 9283 } 9284 } 9285 9286 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9287 9288 if (r != null && cpr.canRunHere(r)) { 9289 // If this is a multiprocess provider, then just return its 9290 // info and allow the caller to instantiate it. Only do 9291 // this if the provider is the same user as the caller's 9292 // process, or can run as root (so can be in any process). 9293 return cpr.newHolder(null); 9294 } 9295 9296 if (DEBUG_PROVIDER) { 9297 RuntimeException e = new RuntimeException("here"); 9298 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9299 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9300 } 9301 9302 // This is single process, and our app is now connecting to it. 9303 // See if we are already in the process of launching this 9304 // provider. 9305 final int N = mLaunchingProviders.size(); 9306 int i; 9307 for (i=0; i<N; i++) { 9308 if (mLaunchingProviders.get(i) == cpr) { 9309 break; 9310 } 9311 } 9312 9313 // If the provider is not already being launched, then get it 9314 // started. 9315 if (i >= N) { 9316 final long origId = Binder.clearCallingIdentity(); 9317 9318 try { 9319 // Content provider is now in use, its package can't be stopped. 9320 try { 9321 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9322 AppGlobals.getPackageManager().setPackageStoppedState( 9323 cpr.appInfo.packageName, false, userId); 9324 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9325 } catch (RemoteException e) { 9326 } catch (IllegalArgumentException e) { 9327 Slog.w(TAG, "Failed trying to unstop package " 9328 + cpr.appInfo.packageName + ": " + e); 9329 } 9330 9331 // Use existing process if already started 9332 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9333 ProcessRecord proc = getProcessRecordLocked( 9334 cpi.processName, cpr.appInfo.uid, false); 9335 if (proc != null && proc.thread != null) { 9336 if (DEBUG_PROVIDER) { 9337 Slog.d(TAG, "Installing in existing process " + proc); 9338 } 9339 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9340 proc.pubProviders.put(cpi.name, cpr); 9341 try { 9342 proc.thread.scheduleInstallProvider(cpi); 9343 } catch (RemoteException e) { 9344 } 9345 } else { 9346 checkTime(startTime, "getContentProviderImpl: before start process"); 9347 proc = startProcessLocked(cpi.processName, 9348 cpr.appInfo, false, 0, "content provider", 9349 new ComponentName(cpi.applicationInfo.packageName, 9350 cpi.name), false, false, false); 9351 checkTime(startTime, "getContentProviderImpl: after start process"); 9352 if (proc == null) { 9353 Slog.w(TAG, "Unable to launch app " 9354 + cpi.applicationInfo.packageName + "/" 9355 + cpi.applicationInfo.uid + " for provider " 9356 + name + ": process is bad"); 9357 return null; 9358 } 9359 } 9360 cpr.launchingApp = proc; 9361 mLaunchingProviders.add(cpr); 9362 } finally { 9363 Binder.restoreCallingIdentity(origId); 9364 } 9365 } 9366 9367 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9368 9369 // Make sure the provider is published (the same provider class 9370 // may be published under multiple names). 9371 if (firstClass) { 9372 mProviderMap.putProviderByClass(comp, cpr); 9373 } 9374 9375 mProviderMap.putProviderByName(name, cpr); 9376 conn = incProviderCountLocked(r, cpr, token, stable); 9377 if (conn != null) { 9378 conn.waiting = true; 9379 } 9380 } 9381 checkTime(startTime, "getContentProviderImpl: done!"); 9382 } 9383 9384 // Wait for the provider to be published... 9385 synchronized (cpr) { 9386 while (cpr.provider == null) { 9387 if (cpr.launchingApp == null) { 9388 Slog.w(TAG, "Unable to launch app " 9389 + cpi.applicationInfo.packageName + "/" 9390 + cpi.applicationInfo.uid + " for provider " 9391 + name + ": launching app became null"); 9392 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9393 UserHandle.getUserId(cpi.applicationInfo.uid), 9394 cpi.applicationInfo.packageName, 9395 cpi.applicationInfo.uid, name); 9396 return null; 9397 } 9398 try { 9399 if (DEBUG_MU) { 9400 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9401 + cpr.launchingApp); 9402 } 9403 if (conn != null) { 9404 conn.waiting = true; 9405 } 9406 cpr.wait(); 9407 } catch (InterruptedException ex) { 9408 } finally { 9409 if (conn != null) { 9410 conn.waiting = false; 9411 } 9412 } 9413 } 9414 } 9415 return cpr != null ? cpr.newHolder(conn) : null; 9416 } 9417 9418 @Override 9419 public final ContentProviderHolder getContentProvider( 9420 IApplicationThread caller, String name, int userId, boolean stable) { 9421 enforceNotIsolatedCaller("getContentProvider"); 9422 if (caller == null) { 9423 String msg = "null IApplicationThread when getting content provider " 9424 + name; 9425 Slog.w(TAG, msg); 9426 throw new SecurityException(msg); 9427 } 9428 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9429 // with cross-user grant. 9430 return getContentProviderImpl(caller, name, null, stable, userId); 9431 } 9432 9433 public ContentProviderHolder getContentProviderExternal( 9434 String name, int userId, IBinder token) { 9435 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9436 "Do not have permission in call getContentProviderExternal()"); 9437 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9438 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9439 return getContentProviderExternalUnchecked(name, token, userId); 9440 } 9441 9442 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9443 IBinder token, int userId) { 9444 return getContentProviderImpl(null, name, token, true, userId); 9445 } 9446 9447 /** 9448 * Drop a content provider from a ProcessRecord's bookkeeping 9449 */ 9450 public void removeContentProvider(IBinder connection, boolean stable) { 9451 enforceNotIsolatedCaller("removeContentProvider"); 9452 long ident = Binder.clearCallingIdentity(); 9453 try { 9454 synchronized (this) { 9455 ContentProviderConnection conn; 9456 try { 9457 conn = (ContentProviderConnection)connection; 9458 } catch (ClassCastException e) { 9459 String msg ="removeContentProvider: " + connection 9460 + " not a ContentProviderConnection"; 9461 Slog.w(TAG, msg); 9462 throw new IllegalArgumentException(msg); 9463 } 9464 if (conn == null) { 9465 throw new NullPointerException("connection is null"); 9466 } 9467 if (decProviderCountLocked(conn, null, null, stable)) { 9468 updateOomAdjLocked(); 9469 } 9470 } 9471 } finally { 9472 Binder.restoreCallingIdentity(ident); 9473 } 9474 } 9475 9476 public void removeContentProviderExternal(String name, IBinder token) { 9477 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9478 "Do not have permission in call removeContentProviderExternal()"); 9479 int userId = UserHandle.getCallingUserId(); 9480 long ident = Binder.clearCallingIdentity(); 9481 try { 9482 removeContentProviderExternalUnchecked(name, token, userId); 9483 } finally { 9484 Binder.restoreCallingIdentity(ident); 9485 } 9486 } 9487 9488 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9489 synchronized (this) { 9490 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9491 if(cpr == null) { 9492 //remove from mProvidersByClass 9493 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9494 return; 9495 } 9496 9497 //update content provider record entry info 9498 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9499 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9500 if (localCpr.hasExternalProcessHandles()) { 9501 if (localCpr.removeExternalProcessHandleLocked(token)) { 9502 updateOomAdjLocked(); 9503 } else { 9504 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9505 + " with no external reference for token: " 9506 + token + "."); 9507 } 9508 } else { 9509 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9510 + " with no external references."); 9511 } 9512 } 9513 } 9514 9515 public final void publishContentProviders(IApplicationThread caller, 9516 List<ContentProviderHolder> providers) { 9517 if (providers == null) { 9518 return; 9519 } 9520 9521 enforceNotIsolatedCaller("publishContentProviders"); 9522 synchronized (this) { 9523 final ProcessRecord r = getRecordForAppLocked(caller); 9524 if (DEBUG_MU) 9525 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9526 if (r == null) { 9527 throw new SecurityException( 9528 "Unable to find app for caller " + caller 9529 + " (pid=" + Binder.getCallingPid() 9530 + ") when publishing content providers"); 9531 } 9532 9533 final long origId = Binder.clearCallingIdentity(); 9534 9535 final int N = providers.size(); 9536 for (int i=0; i<N; i++) { 9537 ContentProviderHolder src = providers.get(i); 9538 if (src == null || src.info == null || src.provider == null) { 9539 continue; 9540 } 9541 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9542 if (DEBUG_MU) 9543 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9544 if (dst != null) { 9545 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9546 mProviderMap.putProviderByClass(comp, dst); 9547 String names[] = dst.info.authority.split(";"); 9548 for (int j = 0; j < names.length; j++) { 9549 mProviderMap.putProviderByName(names[j], dst); 9550 } 9551 9552 int NL = mLaunchingProviders.size(); 9553 int j; 9554 for (j=0; j<NL; j++) { 9555 if (mLaunchingProviders.get(j) == dst) { 9556 mLaunchingProviders.remove(j); 9557 j--; 9558 NL--; 9559 } 9560 } 9561 synchronized (dst) { 9562 dst.provider = src.provider; 9563 dst.proc = r; 9564 dst.notifyAll(); 9565 } 9566 updateOomAdjLocked(r); 9567 } 9568 } 9569 9570 Binder.restoreCallingIdentity(origId); 9571 } 9572 } 9573 9574 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9575 ContentProviderConnection conn; 9576 try { 9577 conn = (ContentProviderConnection)connection; 9578 } catch (ClassCastException e) { 9579 String msg ="refContentProvider: " + connection 9580 + " not a ContentProviderConnection"; 9581 Slog.w(TAG, msg); 9582 throw new IllegalArgumentException(msg); 9583 } 9584 if (conn == null) { 9585 throw new NullPointerException("connection is null"); 9586 } 9587 9588 synchronized (this) { 9589 if (stable > 0) { 9590 conn.numStableIncs += stable; 9591 } 9592 stable = conn.stableCount + stable; 9593 if (stable < 0) { 9594 throw new IllegalStateException("stableCount < 0: " + stable); 9595 } 9596 9597 if (unstable > 0) { 9598 conn.numUnstableIncs += unstable; 9599 } 9600 unstable = conn.unstableCount + unstable; 9601 if (unstable < 0) { 9602 throw new IllegalStateException("unstableCount < 0: " + unstable); 9603 } 9604 9605 if ((stable+unstable) <= 0) { 9606 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9607 + stable + " unstable=" + unstable); 9608 } 9609 conn.stableCount = stable; 9610 conn.unstableCount = unstable; 9611 return !conn.dead; 9612 } 9613 } 9614 9615 public void unstableProviderDied(IBinder connection) { 9616 ContentProviderConnection conn; 9617 try { 9618 conn = (ContentProviderConnection)connection; 9619 } catch (ClassCastException e) { 9620 String msg ="refContentProvider: " + connection 9621 + " not a ContentProviderConnection"; 9622 Slog.w(TAG, msg); 9623 throw new IllegalArgumentException(msg); 9624 } 9625 if (conn == null) { 9626 throw new NullPointerException("connection is null"); 9627 } 9628 9629 // Safely retrieve the content provider associated with the connection. 9630 IContentProvider provider; 9631 synchronized (this) { 9632 provider = conn.provider.provider; 9633 } 9634 9635 if (provider == null) { 9636 // Um, yeah, we're way ahead of you. 9637 return; 9638 } 9639 9640 // Make sure the caller is being honest with us. 9641 if (provider.asBinder().pingBinder()) { 9642 // Er, no, still looks good to us. 9643 synchronized (this) { 9644 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9645 + " says " + conn + " died, but we don't agree"); 9646 return; 9647 } 9648 } 9649 9650 // Well look at that! It's dead! 9651 synchronized (this) { 9652 if (conn.provider.provider != provider) { 9653 // But something changed... good enough. 9654 return; 9655 } 9656 9657 ProcessRecord proc = conn.provider.proc; 9658 if (proc == null || proc.thread == null) { 9659 // Seems like the process is already cleaned up. 9660 return; 9661 } 9662 9663 // As far as we're concerned, this is just like receiving a 9664 // death notification... just a bit prematurely. 9665 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9666 + ") early provider death"); 9667 final long ident = Binder.clearCallingIdentity(); 9668 try { 9669 appDiedLocked(proc); 9670 } finally { 9671 Binder.restoreCallingIdentity(ident); 9672 } 9673 } 9674 } 9675 9676 @Override 9677 public void appNotRespondingViaProvider(IBinder connection) { 9678 enforceCallingPermission( 9679 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9680 9681 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9682 if (conn == null) { 9683 Slog.w(TAG, "ContentProviderConnection is null"); 9684 return; 9685 } 9686 9687 final ProcessRecord host = conn.provider.proc; 9688 if (host == null) { 9689 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9690 return; 9691 } 9692 9693 final long token = Binder.clearCallingIdentity(); 9694 try { 9695 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9696 } finally { 9697 Binder.restoreCallingIdentity(token); 9698 } 9699 } 9700 9701 public final void installSystemProviders() { 9702 List<ProviderInfo> providers; 9703 synchronized (this) { 9704 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9705 providers = generateApplicationProvidersLocked(app); 9706 if (providers != null) { 9707 for (int i=providers.size()-1; i>=0; i--) { 9708 ProviderInfo pi = (ProviderInfo)providers.get(i); 9709 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9710 Slog.w(TAG, "Not installing system proc provider " + pi.name 9711 + ": not system .apk"); 9712 providers.remove(i); 9713 } 9714 } 9715 } 9716 } 9717 if (providers != null) { 9718 mSystemThread.installSystemProviders(providers); 9719 } 9720 9721 mCoreSettingsObserver = new CoreSettingsObserver(this); 9722 9723 //mUsageStatsService.monitorPackages(); 9724 } 9725 9726 /** 9727 * Allows apps to retrieve the MIME type of a URI. 9728 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9729 * users, then it does not need permission to access the ContentProvider. 9730 * Either, it needs cross-user uri grants. 9731 * 9732 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9733 * 9734 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9735 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9736 */ 9737 public String getProviderMimeType(Uri uri, int userId) { 9738 enforceNotIsolatedCaller("getProviderMimeType"); 9739 final String name = uri.getAuthority(); 9740 int callingUid = Binder.getCallingUid(); 9741 int callingPid = Binder.getCallingPid(); 9742 long ident = 0; 9743 boolean clearedIdentity = false; 9744 userId = unsafeConvertIncomingUser(userId); 9745 if (canClearIdentity(callingPid, callingUid, userId)) { 9746 clearedIdentity = true; 9747 ident = Binder.clearCallingIdentity(); 9748 } 9749 ContentProviderHolder holder = null; 9750 try { 9751 holder = getContentProviderExternalUnchecked(name, null, userId); 9752 if (holder != null) { 9753 return holder.provider.getType(uri); 9754 } 9755 } catch (RemoteException e) { 9756 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9757 return null; 9758 } finally { 9759 // We need to clear the identity to call removeContentProviderExternalUnchecked 9760 if (!clearedIdentity) { 9761 ident = Binder.clearCallingIdentity(); 9762 } 9763 try { 9764 if (holder != null) { 9765 removeContentProviderExternalUnchecked(name, null, userId); 9766 } 9767 } finally { 9768 Binder.restoreCallingIdentity(ident); 9769 } 9770 } 9771 9772 return null; 9773 } 9774 9775 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9776 if (UserHandle.getUserId(callingUid) == userId) { 9777 return true; 9778 } 9779 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9780 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9781 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9782 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9783 return true; 9784 } 9785 return false; 9786 } 9787 9788 // ========================================================= 9789 // GLOBAL MANAGEMENT 9790 // ========================================================= 9791 9792 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9793 boolean isolated, int isolatedUid) { 9794 String proc = customProcess != null ? customProcess : info.processName; 9795 BatteryStatsImpl.Uid.Proc ps = null; 9796 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9797 int uid = info.uid; 9798 if (isolated) { 9799 if (isolatedUid == 0) { 9800 int userId = UserHandle.getUserId(uid); 9801 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9802 while (true) { 9803 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9804 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9805 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9806 } 9807 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9808 mNextIsolatedProcessUid++; 9809 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9810 // No process for this uid, use it. 9811 break; 9812 } 9813 stepsLeft--; 9814 if (stepsLeft <= 0) { 9815 return null; 9816 } 9817 } 9818 } else { 9819 // Special case for startIsolatedProcess (internal only), where 9820 // the uid of the isolated process is specified by the caller. 9821 uid = isolatedUid; 9822 } 9823 } 9824 return new ProcessRecord(stats, info, proc, uid); 9825 } 9826 9827 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9828 String abiOverride) { 9829 ProcessRecord app; 9830 if (!isolated) { 9831 app = getProcessRecordLocked(info.processName, info.uid, true); 9832 } else { 9833 app = null; 9834 } 9835 9836 if (app == null) { 9837 app = newProcessRecordLocked(info, null, isolated, 0); 9838 mProcessNames.put(info.processName, app.uid, app); 9839 if (isolated) { 9840 mIsolatedProcesses.put(app.uid, app); 9841 } 9842 updateLruProcessLocked(app, false, null); 9843 updateOomAdjLocked(); 9844 } 9845 9846 // This package really, really can not be stopped. 9847 try { 9848 AppGlobals.getPackageManager().setPackageStoppedState( 9849 info.packageName, false, UserHandle.getUserId(app.uid)); 9850 } catch (RemoteException e) { 9851 } catch (IllegalArgumentException e) { 9852 Slog.w(TAG, "Failed trying to unstop package " 9853 + info.packageName + ": " + e); 9854 } 9855 9856 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9857 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9858 app.persistent = true; 9859 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9860 } 9861 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9862 mPersistentStartingProcesses.add(app); 9863 startProcessLocked(app, "added application", app.processName, abiOverride, 9864 null /* entryPoint */, null /* entryPointArgs */); 9865 } 9866 9867 return app; 9868 } 9869 9870 public void unhandledBack() { 9871 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9872 "unhandledBack()"); 9873 9874 synchronized(this) { 9875 final long origId = Binder.clearCallingIdentity(); 9876 try { 9877 getFocusedStack().unhandledBackLocked(); 9878 } finally { 9879 Binder.restoreCallingIdentity(origId); 9880 } 9881 } 9882 } 9883 9884 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9885 enforceNotIsolatedCaller("openContentUri"); 9886 final int userId = UserHandle.getCallingUserId(); 9887 String name = uri.getAuthority(); 9888 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9889 ParcelFileDescriptor pfd = null; 9890 if (cph != null) { 9891 // We record the binder invoker's uid in thread-local storage before 9892 // going to the content provider to open the file. Later, in the code 9893 // that handles all permissions checks, we look for this uid and use 9894 // that rather than the Activity Manager's own uid. The effect is that 9895 // we do the check against the caller's permissions even though it looks 9896 // to the content provider like the Activity Manager itself is making 9897 // the request. 9898 Binder token = new Binder(); 9899 sCallerIdentity.set(new Identity( 9900 token, Binder.getCallingPid(), Binder.getCallingUid())); 9901 try { 9902 pfd = cph.provider.openFile(null, uri, "r", null, token); 9903 } catch (FileNotFoundException e) { 9904 // do nothing; pfd will be returned null 9905 } finally { 9906 // Ensure that whatever happens, we clean up the identity state 9907 sCallerIdentity.remove(); 9908 } 9909 9910 // We've got the fd now, so we're done with the provider. 9911 removeContentProviderExternalUnchecked(name, null, userId); 9912 } else { 9913 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9914 } 9915 return pfd; 9916 } 9917 9918 // Actually is sleeping or shutting down or whatever else in the future 9919 // is an inactive state. 9920 public boolean isSleepingOrShuttingDown() { 9921 return isSleeping() || mShuttingDown; 9922 } 9923 9924 public boolean isSleeping() { 9925 return mSleeping; 9926 } 9927 9928 void goingToSleep() { 9929 synchronized(this) { 9930 mWentToSleep = true; 9931 goToSleepIfNeededLocked(); 9932 } 9933 } 9934 9935 void finishRunningVoiceLocked() { 9936 if (mRunningVoice) { 9937 mRunningVoice = false; 9938 goToSleepIfNeededLocked(); 9939 } 9940 } 9941 9942 void goToSleepIfNeededLocked() { 9943 if (mWentToSleep && !mRunningVoice) { 9944 if (!mSleeping) { 9945 mSleeping = true; 9946 mStackSupervisor.goingToSleepLocked(); 9947 9948 // Initialize the wake times of all processes. 9949 checkExcessivePowerUsageLocked(false); 9950 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9951 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9952 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9953 } 9954 } 9955 } 9956 9957 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9958 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9959 // Never persist the home stack. 9960 return; 9961 } 9962 mTaskPersister.wakeup(task, flush); 9963 } 9964 9965 @Override 9966 public boolean shutdown(int timeout) { 9967 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9968 != PackageManager.PERMISSION_GRANTED) { 9969 throw new SecurityException("Requires permission " 9970 + android.Manifest.permission.SHUTDOWN); 9971 } 9972 9973 boolean timedout = false; 9974 9975 synchronized(this) { 9976 mShuttingDown = true; 9977 updateEventDispatchingLocked(); 9978 timedout = mStackSupervisor.shutdownLocked(timeout); 9979 } 9980 9981 mAppOpsService.shutdown(); 9982 if (mUsageStatsService != null) { 9983 mUsageStatsService.prepareShutdown(); 9984 } 9985 mBatteryStatsService.shutdown(); 9986 synchronized (this) { 9987 mProcessStats.shutdownLocked(); 9988 } 9989 notifyTaskPersisterLocked(null, true); 9990 9991 return timedout; 9992 } 9993 9994 public final void activitySlept(IBinder token) { 9995 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9996 9997 final long origId = Binder.clearCallingIdentity(); 9998 9999 synchronized (this) { 10000 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10001 if (r != null) { 10002 mStackSupervisor.activitySleptLocked(r); 10003 } 10004 } 10005 10006 Binder.restoreCallingIdentity(origId); 10007 } 10008 10009 private String lockScreenShownToString() { 10010 switch (mLockScreenShown) { 10011 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10012 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10013 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10014 default: return "Unknown=" + mLockScreenShown; 10015 } 10016 } 10017 10018 void logLockScreen(String msg) { 10019 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10020 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 10021 mWentToSleep + " mSleeping=" + mSleeping); 10022 } 10023 10024 void comeOutOfSleepIfNeededLocked() { 10025 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 10026 if (mSleeping) { 10027 mSleeping = false; 10028 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10029 } 10030 } 10031 } 10032 10033 void wakingUp() { 10034 synchronized(this) { 10035 mWentToSleep = false; 10036 comeOutOfSleepIfNeededLocked(); 10037 } 10038 } 10039 10040 void startRunningVoiceLocked() { 10041 if (!mRunningVoice) { 10042 mRunningVoice = true; 10043 comeOutOfSleepIfNeededLocked(); 10044 } 10045 } 10046 10047 private void updateEventDispatchingLocked() { 10048 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10049 } 10050 10051 public void setLockScreenShown(boolean shown) { 10052 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10053 != PackageManager.PERMISSION_GRANTED) { 10054 throw new SecurityException("Requires permission " 10055 + android.Manifest.permission.DEVICE_POWER); 10056 } 10057 10058 synchronized(this) { 10059 long ident = Binder.clearCallingIdentity(); 10060 try { 10061 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10062 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10063 comeOutOfSleepIfNeededLocked(); 10064 } finally { 10065 Binder.restoreCallingIdentity(ident); 10066 } 10067 } 10068 } 10069 10070 @Override 10071 public void stopAppSwitches() { 10072 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10073 != PackageManager.PERMISSION_GRANTED) { 10074 throw new SecurityException("Requires permission " 10075 + android.Manifest.permission.STOP_APP_SWITCHES); 10076 } 10077 10078 synchronized(this) { 10079 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10080 + APP_SWITCH_DELAY_TIME; 10081 mDidAppSwitch = false; 10082 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10083 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10084 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10085 } 10086 } 10087 10088 public void resumeAppSwitches() { 10089 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10090 != PackageManager.PERMISSION_GRANTED) { 10091 throw new SecurityException("Requires permission " 10092 + android.Manifest.permission.STOP_APP_SWITCHES); 10093 } 10094 10095 synchronized(this) { 10096 // Note that we don't execute any pending app switches... we will 10097 // let those wait until either the timeout, or the next start 10098 // activity request. 10099 mAppSwitchesAllowedTime = 0; 10100 } 10101 } 10102 10103 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10104 int callingPid, int callingUid, String name) { 10105 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10106 return true; 10107 } 10108 10109 int perm = checkComponentPermission( 10110 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10111 sourceUid, -1, true); 10112 if (perm == PackageManager.PERMISSION_GRANTED) { 10113 return true; 10114 } 10115 10116 // If the actual IPC caller is different from the logical source, then 10117 // also see if they are allowed to control app switches. 10118 if (callingUid != -1 && callingUid != sourceUid) { 10119 perm = checkComponentPermission( 10120 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10121 callingUid, -1, true); 10122 if (perm == PackageManager.PERMISSION_GRANTED) { 10123 return true; 10124 } 10125 } 10126 10127 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10128 return false; 10129 } 10130 10131 public void setDebugApp(String packageName, boolean waitForDebugger, 10132 boolean persistent) { 10133 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10134 "setDebugApp()"); 10135 10136 long ident = Binder.clearCallingIdentity(); 10137 try { 10138 // Note that this is not really thread safe if there are multiple 10139 // callers into it at the same time, but that's not a situation we 10140 // care about. 10141 if (persistent) { 10142 final ContentResolver resolver = mContext.getContentResolver(); 10143 Settings.Global.putString( 10144 resolver, Settings.Global.DEBUG_APP, 10145 packageName); 10146 Settings.Global.putInt( 10147 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10148 waitForDebugger ? 1 : 0); 10149 } 10150 10151 synchronized (this) { 10152 if (!persistent) { 10153 mOrigDebugApp = mDebugApp; 10154 mOrigWaitForDebugger = mWaitForDebugger; 10155 } 10156 mDebugApp = packageName; 10157 mWaitForDebugger = waitForDebugger; 10158 mDebugTransient = !persistent; 10159 if (packageName != null) { 10160 forceStopPackageLocked(packageName, -1, false, false, true, true, 10161 false, UserHandle.USER_ALL, "set debug app"); 10162 } 10163 } 10164 } finally { 10165 Binder.restoreCallingIdentity(ident); 10166 } 10167 } 10168 10169 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10170 synchronized (this) { 10171 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10172 if (!isDebuggable) { 10173 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10174 throw new SecurityException("Process not debuggable: " + app.packageName); 10175 } 10176 } 10177 10178 mOpenGlTraceApp = processName; 10179 } 10180 } 10181 10182 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10183 synchronized (this) { 10184 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10185 if (!isDebuggable) { 10186 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10187 throw new SecurityException("Process not debuggable: " + app.packageName); 10188 } 10189 } 10190 mProfileApp = processName; 10191 mProfileFile = profilerInfo.profileFile; 10192 if (mProfileFd != null) { 10193 try { 10194 mProfileFd.close(); 10195 } catch (IOException e) { 10196 } 10197 mProfileFd = null; 10198 } 10199 mProfileFd = profilerInfo.profileFd; 10200 mSamplingInterval = profilerInfo.samplingInterval; 10201 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10202 mProfileType = 0; 10203 } 10204 } 10205 10206 @Override 10207 public void setAlwaysFinish(boolean enabled) { 10208 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10209 "setAlwaysFinish()"); 10210 10211 Settings.Global.putInt( 10212 mContext.getContentResolver(), 10213 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10214 10215 synchronized (this) { 10216 mAlwaysFinishActivities = enabled; 10217 } 10218 } 10219 10220 @Override 10221 public void setActivityController(IActivityController controller) { 10222 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10223 "setActivityController()"); 10224 synchronized (this) { 10225 mController = controller; 10226 Watchdog.getInstance().setActivityController(controller); 10227 } 10228 } 10229 10230 @Override 10231 public void setUserIsMonkey(boolean userIsMonkey) { 10232 synchronized (this) { 10233 synchronized (mPidsSelfLocked) { 10234 final int callingPid = Binder.getCallingPid(); 10235 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10236 if (precessRecord == null) { 10237 throw new SecurityException("Unknown process: " + callingPid); 10238 } 10239 if (precessRecord.instrumentationUiAutomationConnection == null) { 10240 throw new SecurityException("Only an instrumentation process " 10241 + "with a UiAutomation can call setUserIsMonkey"); 10242 } 10243 } 10244 mUserIsMonkey = userIsMonkey; 10245 } 10246 } 10247 10248 @Override 10249 public boolean isUserAMonkey() { 10250 synchronized (this) { 10251 // If there is a controller also implies the user is a monkey. 10252 return (mUserIsMonkey || mController != null); 10253 } 10254 } 10255 10256 public void requestBugReport() { 10257 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10258 SystemProperties.set("ctl.start", "bugreport"); 10259 } 10260 10261 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10262 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10263 } 10264 10265 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10266 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10267 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10268 } 10269 return KEY_DISPATCHING_TIMEOUT; 10270 } 10271 10272 @Override 10273 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10274 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10275 != PackageManager.PERMISSION_GRANTED) { 10276 throw new SecurityException("Requires permission " 10277 + android.Manifest.permission.FILTER_EVENTS); 10278 } 10279 ProcessRecord proc; 10280 long timeout; 10281 synchronized (this) { 10282 synchronized (mPidsSelfLocked) { 10283 proc = mPidsSelfLocked.get(pid); 10284 } 10285 timeout = getInputDispatchingTimeoutLocked(proc); 10286 } 10287 10288 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10289 return -1; 10290 } 10291 10292 return timeout; 10293 } 10294 10295 /** 10296 * Handle input dispatching timeouts. 10297 * Returns whether input dispatching should be aborted or not. 10298 */ 10299 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10300 final ActivityRecord activity, final ActivityRecord parent, 10301 final boolean aboveSystem, String reason) { 10302 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10303 != PackageManager.PERMISSION_GRANTED) { 10304 throw new SecurityException("Requires permission " 10305 + android.Manifest.permission.FILTER_EVENTS); 10306 } 10307 10308 final String annotation; 10309 if (reason == null) { 10310 annotation = "Input dispatching timed out"; 10311 } else { 10312 annotation = "Input dispatching timed out (" + reason + ")"; 10313 } 10314 10315 if (proc != null) { 10316 synchronized (this) { 10317 if (proc.debugging) { 10318 return false; 10319 } 10320 10321 if (mDidDexOpt) { 10322 // Give more time since we were dexopting. 10323 mDidDexOpt = false; 10324 return false; 10325 } 10326 10327 if (proc.instrumentationClass != null) { 10328 Bundle info = new Bundle(); 10329 info.putString("shortMsg", "keyDispatchingTimedOut"); 10330 info.putString("longMsg", annotation); 10331 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10332 return true; 10333 } 10334 } 10335 mHandler.post(new Runnable() { 10336 @Override 10337 public void run() { 10338 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10339 } 10340 }); 10341 } 10342 10343 return true; 10344 } 10345 10346 public Bundle getAssistContextExtras(int requestType) { 10347 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10348 UserHandle.getCallingUserId()); 10349 if (pae == null) { 10350 return null; 10351 } 10352 synchronized (pae) { 10353 while (!pae.haveResult) { 10354 try { 10355 pae.wait(); 10356 } catch (InterruptedException e) { 10357 } 10358 } 10359 if (pae.result != null) { 10360 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10361 } 10362 } 10363 synchronized (this) { 10364 mPendingAssistExtras.remove(pae); 10365 mHandler.removeCallbacks(pae); 10366 } 10367 return pae.extras; 10368 } 10369 10370 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10371 int userHandle) { 10372 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10373 "getAssistContextExtras()"); 10374 PendingAssistExtras pae; 10375 Bundle extras = new Bundle(); 10376 synchronized (this) { 10377 ActivityRecord activity = getFocusedStack().mResumedActivity; 10378 if (activity == null) { 10379 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10380 return null; 10381 } 10382 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10383 if (activity.app == null || activity.app.thread == null) { 10384 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10385 return null; 10386 } 10387 if (activity.app.pid == Binder.getCallingPid()) { 10388 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10389 return null; 10390 } 10391 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10392 try { 10393 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10394 requestType); 10395 mPendingAssistExtras.add(pae); 10396 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10397 } catch (RemoteException e) { 10398 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10399 return null; 10400 } 10401 return pae; 10402 } 10403 } 10404 10405 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10406 PendingAssistExtras pae = (PendingAssistExtras)token; 10407 synchronized (pae) { 10408 pae.result = extras; 10409 pae.haveResult = true; 10410 pae.notifyAll(); 10411 if (pae.intent == null) { 10412 // Caller is just waiting for the result. 10413 return; 10414 } 10415 } 10416 10417 // We are now ready to launch the assist activity. 10418 synchronized (this) { 10419 boolean exists = mPendingAssistExtras.remove(pae); 10420 mHandler.removeCallbacks(pae); 10421 if (!exists) { 10422 // Timed out. 10423 return; 10424 } 10425 } 10426 pae.intent.replaceExtras(extras); 10427 if (pae.hint != null) { 10428 pae.intent.putExtra(pae.hint, true); 10429 } 10430 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10431 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10432 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10433 closeSystemDialogs("assist"); 10434 try { 10435 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10436 } catch (ActivityNotFoundException e) { 10437 Slog.w(TAG, "No activity to handle assist action.", e); 10438 } 10439 } 10440 10441 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10442 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10443 } 10444 10445 public void registerProcessObserver(IProcessObserver observer) { 10446 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10447 "registerProcessObserver()"); 10448 synchronized (this) { 10449 mProcessObservers.register(observer); 10450 } 10451 } 10452 10453 @Override 10454 public void unregisterProcessObserver(IProcessObserver observer) { 10455 synchronized (this) { 10456 mProcessObservers.unregister(observer); 10457 } 10458 } 10459 10460 @Override 10461 public boolean convertFromTranslucent(IBinder token) { 10462 final long origId = Binder.clearCallingIdentity(); 10463 try { 10464 synchronized (this) { 10465 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10466 if (r == null) { 10467 return false; 10468 } 10469 final boolean translucentChanged = r.changeWindowTranslucency(true); 10470 if (translucentChanged) { 10471 r.task.stack.releaseBackgroundResources(); 10472 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10473 } 10474 mWindowManager.setAppFullscreen(token, true); 10475 return translucentChanged; 10476 } 10477 } finally { 10478 Binder.restoreCallingIdentity(origId); 10479 } 10480 } 10481 10482 @Override 10483 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10484 final long origId = Binder.clearCallingIdentity(); 10485 try { 10486 synchronized (this) { 10487 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10488 if (r == null) { 10489 return false; 10490 } 10491 int index = r.task.mActivities.lastIndexOf(r); 10492 if (index > 0) { 10493 ActivityRecord under = r.task.mActivities.get(index - 1); 10494 under.returningOptions = options; 10495 } 10496 final boolean translucentChanged = r.changeWindowTranslucency(false); 10497 if (translucentChanged) { 10498 r.task.stack.convertToTranslucent(r); 10499 } 10500 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10501 mWindowManager.setAppFullscreen(token, false); 10502 return translucentChanged; 10503 } 10504 } finally { 10505 Binder.restoreCallingIdentity(origId); 10506 } 10507 } 10508 10509 @Override 10510 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10511 final long origId = Binder.clearCallingIdentity(); 10512 try { 10513 synchronized (this) { 10514 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10515 if (r != null) { 10516 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10517 } 10518 } 10519 return false; 10520 } finally { 10521 Binder.restoreCallingIdentity(origId); 10522 } 10523 } 10524 10525 @Override 10526 public boolean isBackgroundVisibleBehind(IBinder token) { 10527 final long origId = Binder.clearCallingIdentity(); 10528 try { 10529 synchronized (this) { 10530 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10531 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10532 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10533 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10534 return visible; 10535 } 10536 } finally { 10537 Binder.restoreCallingIdentity(origId); 10538 } 10539 } 10540 10541 @Override 10542 public ActivityOptions getActivityOptions(IBinder token) { 10543 final long origId = Binder.clearCallingIdentity(); 10544 try { 10545 synchronized (this) { 10546 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10547 if (r != null) { 10548 final ActivityOptions activityOptions = r.pendingOptions; 10549 r.pendingOptions = null; 10550 return activityOptions; 10551 } 10552 return null; 10553 } 10554 } finally { 10555 Binder.restoreCallingIdentity(origId); 10556 } 10557 } 10558 10559 @Override 10560 public void setImmersive(IBinder token, boolean immersive) { 10561 synchronized(this) { 10562 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10563 if (r == null) { 10564 throw new IllegalArgumentException(); 10565 } 10566 r.immersive = immersive; 10567 10568 // update associated state if we're frontmost 10569 if (r == mFocusedActivity) { 10570 if (DEBUG_IMMERSIVE) { 10571 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10572 } 10573 applyUpdateLockStateLocked(r); 10574 } 10575 } 10576 } 10577 10578 @Override 10579 public boolean isImmersive(IBinder token) { 10580 synchronized (this) { 10581 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10582 if (r == null) { 10583 throw new IllegalArgumentException(); 10584 } 10585 return r.immersive; 10586 } 10587 } 10588 10589 public boolean isTopActivityImmersive() { 10590 enforceNotIsolatedCaller("startActivity"); 10591 synchronized (this) { 10592 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10593 return (r != null) ? r.immersive : false; 10594 } 10595 } 10596 10597 @Override 10598 public boolean isTopOfTask(IBinder token) { 10599 synchronized (this) { 10600 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10601 if (r == null) { 10602 throw new IllegalArgumentException(); 10603 } 10604 return r.task.getTopActivity() == r; 10605 } 10606 } 10607 10608 public final void enterSafeMode() { 10609 synchronized(this) { 10610 // It only makes sense to do this before the system is ready 10611 // and started launching other packages. 10612 if (!mSystemReady) { 10613 try { 10614 AppGlobals.getPackageManager().enterSafeMode(); 10615 } catch (RemoteException e) { 10616 } 10617 } 10618 10619 mSafeMode = true; 10620 } 10621 } 10622 10623 public final void showSafeModeOverlay() { 10624 View v = LayoutInflater.from(mContext).inflate( 10625 com.android.internal.R.layout.safe_mode, null); 10626 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10627 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10628 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10629 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10630 lp.gravity = Gravity.BOTTOM | Gravity.START; 10631 lp.format = v.getBackground().getOpacity(); 10632 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10633 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10634 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10635 ((WindowManager)mContext.getSystemService( 10636 Context.WINDOW_SERVICE)).addView(v, lp); 10637 } 10638 10639 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10640 if (!(sender instanceof PendingIntentRecord)) { 10641 return; 10642 } 10643 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10644 synchronized (stats) { 10645 if (mBatteryStatsService.isOnBattery()) { 10646 mBatteryStatsService.enforceCallingPermission(); 10647 PendingIntentRecord rec = (PendingIntentRecord)sender; 10648 int MY_UID = Binder.getCallingUid(); 10649 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10650 BatteryStatsImpl.Uid.Pkg pkg = 10651 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10652 sourcePkg != null ? sourcePkg : rec.key.packageName); 10653 pkg.incWakeupsLocked(); 10654 } 10655 } 10656 } 10657 10658 public boolean killPids(int[] pids, String pReason, boolean secure) { 10659 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10660 throw new SecurityException("killPids only available to the system"); 10661 } 10662 String reason = (pReason == null) ? "Unknown" : pReason; 10663 // XXX Note: don't acquire main activity lock here, because the window 10664 // manager calls in with its locks held. 10665 10666 boolean killed = false; 10667 synchronized (mPidsSelfLocked) { 10668 int[] types = new int[pids.length]; 10669 int worstType = 0; 10670 for (int i=0; i<pids.length; i++) { 10671 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10672 if (proc != null) { 10673 int type = proc.setAdj; 10674 types[i] = type; 10675 if (type > worstType) { 10676 worstType = type; 10677 } 10678 } 10679 } 10680 10681 // If the worst oom_adj is somewhere in the cached proc LRU range, 10682 // then constrain it so we will kill all cached procs. 10683 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10684 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10685 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10686 } 10687 10688 // If this is not a secure call, don't let it kill processes that 10689 // are important. 10690 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10691 worstType = ProcessList.SERVICE_ADJ; 10692 } 10693 10694 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10695 for (int i=0; i<pids.length; i++) { 10696 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10697 if (proc == null) { 10698 continue; 10699 } 10700 int adj = proc.setAdj; 10701 if (adj >= worstType && !proc.killedByAm) { 10702 proc.kill(reason, true); 10703 killed = true; 10704 } 10705 } 10706 } 10707 return killed; 10708 } 10709 10710 @Override 10711 public void killUid(int uid, String reason) { 10712 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10713 throw new SecurityException("killUid only available to the system"); 10714 } 10715 synchronized (this) { 10716 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10717 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10718 reason != null ? reason : "kill uid"); 10719 } 10720 } 10721 10722 @Override 10723 public boolean killProcessesBelowForeground(String reason) { 10724 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10725 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10726 } 10727 10728 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10729 } 10730 10731 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10732 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10733 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10734 } 10735 10736 boolean killed = false; 10737 synchronized (mPidsSelfLocked) { 10738 final int size = mPidsSelfLocked.size(); 10739 for (int i = 0; i < size; i++) { 10740 final int pid = mPidsSelfLocked.keyAt(i); 10741 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10742 if (proc == null) continue; 10743 10744 final int adj = proc.setAdj; 10745 if (adj > belowAdj && !proc.killedByAm) { 10746 proc.kill(reason, true); 10747 killed = true; 10748 } 10749 } 10750 } 10751 return killed; 10752 } 10753 10754 @Override 10755 public void hang(final IBinder who, boolean allowRestart) { 10756 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10757 != PackageManager.PERMISSION_GRANTED) { 10758 throw new SecurityException("Requires permission " 10759 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10760 } 10761 10762 final IBinder.DeathRecipient death = new DeathRecipient() { 10763 @Override 10764 public void binderDied() { 10765 synchronized (this) { 10766 notifyAll(); 10767 } 10768 } 10769 }; 10770 10771 try { 10772 who.linkToDeath(death, 0); 10773 } catch (RemoteException e) { 10774 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10775 return; 10776 } 10777 10778 synchronized (this) { 10779 Watchdog.getInstance().setAllowRestart(allowRestart); 10780 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10781 synchronized (death) { 10782 while (who.isBinderAlive()) { 10783 try { 10784 death.wait(); 10785 } catch (InterruptedException e) { 10786 } 10787 } 10788 } 10789 Watchdog.getInstance().setAllowRestart(true); 10790 } 10791 } 10792 10793 @Override 10794 public void restart() { 10795 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10796 != PackageManager.PERMISSION_GRANTED) { 10797 throw new SecurityException("Requires permission " 10798 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10799 } 10800 10801 Log.i(TAG, "Sending shutdown broadcast..."); 10802 10803 BroadcastReceiver br = new BroadcastReceiver() { 10804 @Override public void onReceive(Context context, Intent intent) { 10805 // Now the broadcast is done, finish up the low-level shutdown. 10806 Log.i(TAG, "Shutting down activity manager..."); 10807 shutdown(10000); 10808 Log.i(TAG, "Shutdown complete, restarting!"); 10809 Process.killProcess(Process.myPid()); 10810 System.exit(10); 10811 } 10812 }; 10813 10814 // First send the high-level shut down broadcast. 10815 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10816 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10817 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10818 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10819 mContext.sendOrderedBroadcastAsUser(intent, 10820 UserHandle.ALL, null, br, mHandler, 0, null, null); 10821 */ 10822 br.onReceive(mContext, intent); 10823 } 10824 10825 private long getLowRamTimeSinceIdle(long now) { 10826 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10827 } 10828 10829 @Override 10830 public void performIdleMaintenance() { 10831 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10832 != PackageManager.PERMISSION_GRANTED) { 10833 throw new SecurityException("Requires permission " 10834 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10835 } 10836 10837 synchronized (this) { 10838 final long now = SystemClock.uptimeMillis(); 10839 final long timeSinceLastIdle = now - mLastIdleTime; 10840 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10841 mLastIdleTime = now; 10842 mLowRamTimeSinceLastIdle = 0; 10843 if (mLowRamStartTime != 0) { 10844 mLowRamStartTime = now; 10845 } 10846 10847 StringBuilder sb = new StringBuilder(128); 10848 sb.append("Idle maintenance over "); 10849 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10850 sb.append(" low RAM for "); 10851 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10852 Slog.i(TAG, sb.toString()); 10853 10854 // If at least 1/3 of our time since the last idle period has been spent 10855 // with RAM low, then we want to kill processes. 10856 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10857 10858 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10859 ProcessRecord proc = mLruProcesses.get(i); 10860 if (proc.notCachedSinceIdle) { 10861 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10862 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10863 if (doKilling && proc.initialIdlePss != 0 10864 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10865 proc.kill("idle maint (pss " + proc.lastPss 10866 + " from " + proc.initialIdlePss + ")", true); 10867 } 10868 } 10869 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10870 proc.notCachedSinceIdle = true; 10871 proc.initialIdlePss = 0; 10872 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10873 isSleeping(), now); 10874 } 10875 } 10876 10877 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10878 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10879 } 10880 } 10881 10882 private void retrieveSettings() { 10883 final ContentResolver resolver = mContext.getContentResolver(); 10884 String debugApp = Settings.Global.getString( 10885 resolver, Settings.Global.DEBUG_APP); 10886 boolean waitForDebugger = Settings.Global.getInt( 10887 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10888 boolean alwaysFinishActivities = Settings.Global.getInt( 10889 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10890 boolean forceRtl = Settings.Global.getInt( 10891 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10892 // Transfer any global setting for forcing RTL layout, into a System Property 10893 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10894 10895 Configuration configuration = new Configuration(); 10896 Settings.System.getConfiguration(resolver, configuration); 10897 if (forceRtl) { 10898 // This will take care of setting the correct layout direction flags 10899 configuration.setLayoutDirection(configuration.locale); 10900 } 10901 10902 synchronized (this) { 10903 mDebugApp = mOrigDebugApp = debugApp; 10904 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10905 mAlwaysFinishActivities = alwaysFinishActivities; 10906 // This happens before any activities are started, so we can 10907 // change mConfiguration in-place. 10908 updateConfigurationLocked(configuration, null, false, true); 10909 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10910 } 10911 } 10912 10913 /** Loads resources after the current configuration has been set. */ 10914 private void loadResourcesOnSystemReady() { 10915 final Resources res = mContext.getResources(); 10916 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10917 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10918 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10919 } 10920 10921 public boolean testIsSystemReady() { 10922 // no need to synchronize(this) just to read & return the value 10923 return mSystemReady; 10924 } 10925 10926 private static File getCalledPreBootReceiversFile() { 10927 File dataDir = Environment.getDataDirectory(); 10928 File systemDir = new File(dataDir, "system"); 10929 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10930 return fname; 10931 } 10932 10933 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10934 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10935 File file = getCalledPreBootReceiversFile(); 10936 FileInputStream fis = null; 10937 try { 10938 fis = new FileInputStream(file); 10939 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10940 int fvers = dis.readInt(); 10941 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10942 String vers = dis.readUTF(); 10943 String codename = dis.readUTF(); 10944 String build = dis.readUTF(); 10945 if (android.os.Build.VERSION.RELEASE.equals(vers) 10946 && android.os.Build.VERSION.CODENAME.equals(codename) 10947 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10948 int num = dis.readInt(); 10949 while (num > 0) { 10950 num--; 10951 String pkg = dis.readUTF(); 10952 String cls = dis.readUTF(); 10953 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10954 } 10955 } 10956 } 10957 } catch (FileNotFoundException e) { 10958 } catch (IOException e) { 10959 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10960 } finally { 10961 if (fis != null) { 10962 try { 10963 fis.close(); 10964 } catch (IOException e) { 10965 } 10966 } 10967 } 10968 return lastDoneReceivers; 10969 } 10970 10971 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10972 File file = getCalledPreBootReceiversFile(); 10973 FileOutputStream fos = null; 10974 DataOutputStream dos = null; 10975 try { 10976 fos = new FileOutputStream(file); 10977 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10978 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10979 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10980 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10981 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10982 dos.writeInt(list.size()); 10983 for (int i=0; i<list.size(); i++) { 10984 dos.writeUTF(list.get(i).getPackageName()); 10985 dos.writeUTF(list.get(i).getClassName()); 10986 } 10987 } catch (IOException e) { 10988 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10989 file.delete(); 10990 } finally { 10991 FileUtils.sync(fos); 10992 if (dos != null) { 10993 try { 10994 dos.close(); 10995 } catch (IOException e) { 10996 // TODO Auto-generated catch block 10997 e.printStackTrace(); 10998 } 10999 } 11000 } 11001 } 11002 11003 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11004 ArrayList<ComponentName> doneReceivers, int userId) { 11005 boolean waitingUpdate = false; 11006 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11007 List<ResolveInfo> ris = null; 11008 try { 11009 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11010 intent, null, 0, userId); 11011 } catch (RemoteException e) { 11012 } 11013 if (ris != null) { 11014 for (int i=ris.size()-1; i>=0; i--) { 11015 if ((ris.get(i).activityInfo.applicationInfo.flags 11016 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11017 ris.remove(i); 11018 } 11019 } 11020 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11021 11022 // For User 0, load the version number. When delivering to a new user, deliver 11023 // to all receivers. 11024 if (userId == UserHandle.USER_OWNER) { 11025 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11026 for (int i=0; i<ris.size(); i++) { 11027 ActivityInfo ai = ris.get(i).activityInfo; 11028 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11029 if (lastDoneReceivers.contains(comp)) { 11030 // We already did the pre boot receiver for this app with the current 11031 // platform version, so don't do it again... 11032 ris.remove(i); 11033 i--; 11034 // ...however, do keep it as one that has been done, so we don't 11035 // forget about it when rewriting the file of last done receivers. 11036 doneReceivers.add(comp); 11037 } 11038 } 11039 } 11040 11041 // If primary user, send broadcast to all available users, else just to userId 11042 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11043 : new int[] { userId }; 11044 for (int i = 0; i < ris.size(); i++) { 11045 ActivityInfo ai = ris.get(i).activityInfo; 11046 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11047 doneReceivers.add(comp); 11048 intent.setComponent(comp); 11049 for (int j=0; j<users.length; j++) { 11050 IIntentReceiver finisher = null; 11051 // On last receiver and user, set up a completion callback 11052 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11053 finisher = new IIntentReceiver.Stub() { 11054 public void performReceive(Intent intent, int resultCode, 11055 String data, Bundle extras, boolean ordered, 11056 boolean sticky, int sendingUser) { 11057 // The raw IIntentReceiver interface is called 11058 // with the AM lock held, so redispatch to 11059 // execute our code without the lock. 11060 mHandler.post(onFinishCallback); 11061 } 11062 }; 11063 } 11064 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11065 + " for user " + users[j]); 11066 broadcastIntentLocked(null, null, intent, null, finisher, 11067 0, null, null, null, AppOpsManager.OP_NONE, 11068 true, false, MY_PID, Process.SYSTEM_UID, 11069 users[j]); 11070 if (finisher != null) { 11071 waitingUpdate = true; 11072 } 11073 } 11074 } 11075 } 11076 11077 return waitingUpdate; 11078 } 11079 11080 public void systemReady(final Runnable goingCallback) { 11081 synchronized(this) { 11082 if (mSystemReady) { 11083 // If we're done calling all the receivers, run the next "boot phase" passed in 11084 // by the SystemServer 11085 if (goingCallback != null) { 11086 goingCallback.run(); 11087 } 11088 return; 11089 } 11090 11091 // Make sure we have the current profile info, since it is needed for 11092 // security checks. 11093 updateCurrentProfileIdsLocked(); 11094 11095 if (mRecentTasks == null) { 11096 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11097 if (!mRecentTasks.isEmpty()) { 11098 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11099 } 11100 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11101 mTaskPersister.startPersisting(); 11102 } 11103 11104 // Check to see if there are any update receivers to run. 11105 if (!mDidUpdate) { 11106 if (mWaitingUpdate) { 11107 return; 11108 } 11109 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11110 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11111 public void run() { 11112 synchronized (ActivityManagerService.this) { 11113 mDidUpdate = true; 11114 } 11115 writeLastDonePreBootReceivers(doneReceivers); 11116 showBootMessage(mContext.getText( 11117 R.string.android_upgrading_complete), 11118 false); 11119 systemReady(goingCallback); 11120 } 11121 }, doneReceivers, UserHandle.USER_OWNER); 11122 11123 if (mWaitingUpdate) { 11124 return; 11125 } 11126 mDidUpdate = true; 11127 } 11128 11129 mAppOpsService.systemReady(); 11130 mSystemReady = true; 11131 } 11132 11133 ArrayList<ProcessRecord> procsToKill = null; 11134 synchronized(mPidsSelfLocked) { 11135 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11136 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11137 if (!isAllowedWhileBooting(proc.info)){ 11138 if (procsToKill == null) { 11139 procsToKill = new ArrayList<ProcessRecord>(); 11140 } 11141 procsToKill.add(proc); 11142 } 11143 } 11144 } 11145 11146 synchronized(this) { 11147 if (procsToKill != null) { 11148 for (int i=procsToKill.size()-1; i>=0; i--) { 11149 ProcessRecord proc = procsToKill.get(i); 11150 Slog.i(TAG, "Removing system update proc: " + proc); 11151 removeProcessLocked(proc, true, false, "system update done"); 11152 } 11153 } 11154 11155 // Now that we have cleaned up any update processes, we 11156 // are ready to start launching real processes and know that 11157 // we won't trample on them any more. 11158 mProcessesReady = true; 11159 } 11160 11161 Slog.i(TAG, "System now ready"); 11162 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11163 SystemClock.uptimeMillis()); 11164 11165 synchronized(this) { 11166 // Make sure we have no pre-ready processes sitting around. 11167 11168 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11169 ResolveInfo ri = mContext.getPackageManager() 11170 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11171 STOCK_PM_FLAGS); 11172 CharSequence errorMsg = null; 11173 if (ri != null) { 11174 ActivityInfo ai = ri.activityInfo; 11175 ApplicationInfo app = ai.applicationInfo; 11176 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11177 mTopAction = Intent.ACTION_FACTORY_TEST; 11178 mTopData = null; 11179 mTopComponent = new ComponentName(app.packageName, 11180 ai.name); 11181 } else { 11182 errorMsg = mContext.getResources().getText( 11183 com.android.internal.R.string.factorytest_not_system); 11184 } 11185 } else { 11186 errorMsg = mContext.getResources().getText( 11187 com.android.internal.R.string.factorytest_no_action); 11188 } 11189 if (errorMsg != null) { 11190 mTopAction = null; 11191 mTopData = null; 11192 mTopComponent = null; 11193 Message msg = Message.obtain(); 11194 msg.what = SHOW_FACTORY_ERROR_MSG; 11195 msg.getData().putCharSequence("msg", errorMsg); 11196 mHandler.sendMessage(msg); 11197 } 11198 } 11199 } 11200 11201 retrieveSettings(); 11202 loadResourcesOnSystemReady(); 11203 11204 synchronized (this) { 11205 readGrantedUriPermissionsLocked(); 11206 } 11207 11208 if (goingCallback != null) goingCallback.run(); 11209 11210 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11211 Integer.toString(mCurrentUserId), mCurrentUserId); 11212 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11213 Integer.toString(mCurrentUserId), mCurrentUserId); 11214 mSystemServiceManager.startUser(mCurrentUserId); 11215 11216 synchronized (this) { 11217 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11218 try { 11219 List apps = AppGlobals.getPackageManager(). 11220 getPersistentApplications(STOCK_PM_FLAGS); 11221 if (apps != null) { 11222 int N = apps.size(); 11223 int i; 11224 for (i=0; i<N; i++) { 11225 ApplicationInfo info 11226 = (ApplicationInfo)apps.get(i); 11227 if (info != null && 11228 !info.packageName.equals("android")) { 11229 addAppLocked(info, false, null /* ABI override */); 11230 } 11231 } 11232 } 11233 } catch (RemoteException ex) { 11234 // pm is in same process, this will never happen. 11235 } 11236 } 11237 11238 // Start up initial activity. 11239 mBooting = true; 11240 startHomeActivityLocked(mCurrentUserId); 11241 11242 try { 11243 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11244 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11245 + " data partition or your device will be unstable."); 11246 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11247 } 11248 } catch (RemoteException e) { 11249 } 11250 11251 if (!Build.isFingerprintConsistent()) { 11252 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11253 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11254 } 11255 11256 long ident = Binder.clearCallingIdentity(); 11257 try { 11258 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11259 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11260 | Intent.FLAG_RECEIVER_FOREGROUND); 11261 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11262 broadcastIntentLocked(null, null, intent, 11263 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11264 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11265 intent = new Intent(Intent.ACTION_USER_STARTING); 11266 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11267 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11268 broadcastIntentLocked(null, null, intent, 11269 null, new IIntentReceiver.Stub() { 11270 @Override 11271 public void performReceive(Intent intent, int resultCode, String data, 11272 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11273 throws RemoteException { 11274 } 11275 }, 0, null, null, 11276 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11277 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11278 } catch (Throwable t) { 11279 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11280 } finally { 11281 Binder.restoreCallingIdentity(ident); 11282 } 11283 mStackSupervisor.resumeTopActivitiesLocked(); 11284 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11285 } 11286 } 11287 11288 private boolean makeAppCrashingLocked(ProcessRecord app, 11289 String shortMsg, String longMsg, String stackTrace) { 11290 app.crashing = true; 11291 app.crashingReport = generateProcessError(app, 11292 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11293 startAppProblemLocked(app); 11294 app.stopFreezingAllLocked(); 11295 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11296 } 11297 11298 private void makeAppNotRespondingLocked(ProcessRecord app, 11299 String activity, String shortMsg, String longMsg) { 11300 app.notResponding = true; 11301 app.notRespondingReport = generateProcessError(app, 11302 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11303 activity, shortMsg, longMsg, null); 11304 startAppProblemLocked(app); 11305 app.stopFreezingAllLocked(); 11306 } 11307 11308 /** 11309 * Generate a process error record, suitable for attachment to a ProcessRecord. 11310 * 11311 * @param app The ProcessRecord in which the error occurred. 11312 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11313 * ActivityManager.AppErrorStateInfo 11314 * @param activity The activity associated with the crash, if known. 11315 * @param shortMsg Short message describing the crash. 11316 * @param longMsg Long message describing the crash. 11317 * @param stackTrace Full crash stack trace, may be null. 11318 * 11319 * @return Returns a fully-formed AppErrorStateInfo record. 11320 */ 11321 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11322 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11323 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11324 11325 report.condition = condition; 11326 report.processName = app.processName; 11327 report.pid = app.pid; 11328 report.uid = app.info.uid; 11329 report.tag = activity; 11330 report.shortMsg = shortMsg; 11331 report.longMsg = longMsg; 11332 report.stackTrace = stackTrace; 11333 11334 return report; 11335 } 11336 11337 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11338 synchronized (this) { 11339 app.crashing = false; 11340 app.crashingReport = null; 11341 app.notResponding = false; 11342 app.notRespondingReport = null; 11343 if (app.anrDialog == fromDialog) { 11344 app.anrDialog = null; 11345 } 11346 if (app.waitDialog == fromDialog) { 11347 app.waitDialog = null; 11348 } 11349 if (app.pid > 0 && app.pid != MY_PID) { 11350 handleAppCrashLocked(app, null, null, null); 11351 app.kill("user request after error", true); 11352 } 11353 } 11354 } 11355 11356 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11357 String stackTrace) { 11358 long now = SystemClock.uptimeMillis(); 11359 11360 Long crashTime; 11361 if (!app.isolated) { 11362 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11363 } else { 11364 crashTime = null; 11365 } 11366 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11367 // This process loses! 11368 Slog.w(TAG, "Process " + app.info.processName 11369 + " has crashed too many times: killing!"); 11370 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11371 app.userId, app.info.processName, app.uid); 11372 mStackSupervisor.handleAppCrashLocked(app); 11373 if (!app.persistent) { 11374 // We don't want to start this process again until the user 11375 // explicitly does so... but for persistent process, we really 11376 // need to keep it running. If a persistent process is actually 11377 // repeatedly crashing, then badness for everyone. 11378 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11379 app.info.processName); 11380 if (!app.isolated) { 11381 // XXX We don't have a way to mark isolated processes 11382 // as bad, since they don't have a peristent identity. 11383 mBadProcesses.put(app.info.processName, app.uid, 11384 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11385 mProcessCrashTimes.remove(app.info.processName, app.uid); 11386 } 11387 app.bad = true; 11388 app.removed = true; 11389 // Don't let services in this process be restarted and potentially 11390 // annoy the user repeatedly. Unless it is persistent, since those 11391 // processes run critical code. 11392 removeProcessLocked(app, false, false, "crash"); 11393 mStackSupervisor.resumeTopActivitiesLocked(); 11394 return false; 11395 } 11396 mStackSupervisor.resumeTopActivitiesLocked(); 11397 } else { 11398 mStackSupervisor.finishTopRunningActivityLocked(app); 11399 } 11400 11401 // Bump up the crash count of any services currently running in the proc. 11402 for (int i=app.services.size()-1; i>=0; i--) { 11403 // Any services running in the application need to be placed 11404 // back in the pending list. 11405 ServiceRecord sr = app.services.valueAt(i); 11406 sr.crashCount++; 11407 } 11408 11409 // If the crashing process is what we consider to be the "home process" and it has been 11410 // replaced by a third-party app, clear the package preferred activities from packages 11411 // with a home activity running in the process to prevent a repeatedly crashing app 11412 // from blocking the user to manually clear the list. 11413 final ArrayList<ActivityRecord> activities = app.activities; 11414 if (app == mHomeProcess && activities.size() > 0 11415 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11416 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11417 final ActivityRecord r = activities.get(activityNdx); 11418 if (r.isHomeActivity()) { 11419 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11420 try { 11421 ActivityThread.getPackageManager() 11422 .clearPackagePreferredActivities(r.packageName); 11423 } catch (RemoteException c) { 11424 // pm is in same process, this will never happen. 11425 } 11426 } 11427 } 11428 } 11429 11430 if (!app.isolated) { 11431 // XXX Can't keep track of crash times for isolated processes, 11432 // because they don't have a perisistent identity. 11433 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11434 } 11435 11436 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11437 return true; 11438 } 11439 11440 void startAppProblemLocked(ProcessRecord app) { 11441 // If this app is not running under the current user, then we 11442 // can't give it a report button because that would require 11443 // launching the report UI under a different user. 11444 app.errorReportReceiver = null; 11445 11446 for (int userId : mCurrentProfileIds) { 11447 if (app.userId == userId) { 11448 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11449 mContext, app.info.packageName, app.info.flags); 11450 } 11451 } 11452 skipCurrentReceiverLocked(app); 11453 } 11454 11455 void skipCurrentReceiverLocked(ProcessRecord app) { 11456 for (BroadcastQueue queue : mBroadcastQueues) { 11457 queue.skipCurrentReceiverLocked(app); 11458 } 11459 } 11460 11461 /** 11462 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11463 * The application process will exit immediately after this call returns. 11464 * @param app object of the crashing app, null for the system server 11465 * @param crashInfo describing the exception 11466 */ 11467 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11468 ProcessRecord r = findAppProcess(app, "Crash"); 11469 final String processName = app == null ? "system_server" 11470 : (r == null ? "unknown" : r.processName); 11471 11472 handleApplicationCrashInner("crash", r, processName, crashInfo); 11473 } 11474 11475 /* Native crash reporting uses this inner version because it needs to be somewhat 11476 * decoupled from the AM-managed cleanup lifecycle 11477 */ 11478 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11479 ApplicationErrorReport.CrashInfo crashInfo) { 11480 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11481 UserHandle.getUserId(Binder.getCallingUid()), processName, 11482 r == null ? -1 : r.info.flags, 11483 crashInfo.exceptionClassName, 11484 crashInfo.exceptionMessage, 11485 crashInfo.throwFileName, 11486 crashInfo.throwLineNumber); 11487 11488 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11489 11490 crashApplication(r, crashInfo); 11491 } 11492 11493 public void handleApplicationStrictModeViolation( 11494 IBinder app, 11495 int violationMask, 11496 StrictMode.ViolationInfo info) { 11497 ProcessRecord r = findAppProcess(app, "StrictMode"); 11498 if (r == null) { 11499 return; 11500 } 11501 11502 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11503 Integer stackFingerprint = info.hashCode(); 11504 boolean logIt = true; 11505 synchronized (mAlreadyLoggedViolatedStacks) { 11506 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11507 logIt = false; 11508 // TODO: sub-sample into EventLog for these, with 11509 // the info.durationMillis? Then we'd get 11510 // the relative pain numbers, without logging all 11511 // the stack traces repeatedly. We'd want to do 11512 // likewise in the client code, which also does 11513 // dup suppression, before the Binder call. 11514 } else { 11515 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11516 mAlreadyLoggedViolatedStacks.clear(); 11517 } 11518 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11519 } 11520 } 11521 if (logIt) { 11522 logStrictModeViolationToDropBox(r, info); 11523 } 11524 } 11525 11526 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11527 AppErrorResult result = new AppErrorResult(); 11528 synchronized (this) { 11529 final long origId = Binder.clearCallingIdentity(); 11530 11531 Message msg = Message.obtain(); 11532 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11533 HashMap<String, Object> data = new HashMap<String, Object>(); 11534 data.put("result", result); 11535 data.put("app", r); 11536 data.put("violationMask", violationMask); 11537 data.put("info", info); 11538 msg.obj = data; 11539 mHandler.sendMessage(msg); 11540 11541 Binder.restoreCallingIdentity(origId); 11542 } 11543 int res = result.get(); 11544 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11545 } 11546 } 11547 11548 // Depending on the policy in effect, there could be a bunch of 11549 // these in quick succession so we try to batch these together to 11550 // minimize disk writes, number of dropbox entries, and maximize 11551 // compression, by having more fewer, larger records. 11552 private void logStrictModeViolationToDropBox( 11553 ProcessRecord process, 11554 StrictMode.ViolationInfo info) { 11555 if (info == null) { 11556 return; 11557 } 11558 final boolean isSystemApp = process == null || 11559 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11560 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11561 final String processName = process == null ? "unknown" : process.processName; 11562 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11563 final DropBoxManager dbox = (DropBoxManager) 11564 mContext.getSystemService(Context.DROPBOX_SERVICE); 11565 11566 // Exit early if the dropbox isn't configured to accept this report type. 11567 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11568 11569 boolean bufferWasEmpty; 11570 boolean needsFlush; 11571 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11572 synchronized (sb) { 11573 bufferWasEmpty = sb.length() == 0; 11574 appendDropBoxProcessHeaders(process, processName, sb); 11575 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11576 sb.append("System-App: ").append(isSystemApp).append("\n"); 11577 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11578 if (info.violationNumThisLoop != 0) { 11579 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11580 } 11581 if (info.numAnimationsRunning != 0) { 11582 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11583 } 11584 if (info.broadcastIntentAction != null) { 11585 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11586 } 11587 if (info.durationMillis != -1) { 11588 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11589 } 11590 if (info.numInstances != -1) { 11591 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11592 } 11593 if (info.tags != null) { 11594 for (String tag : info.tags) { 11595 sb.append("Span-Tag: ").append(tag).append("\n"); 11596 } 11597 } 11598 sb.append("\n"); 11599 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11600 sb.append(info.crashInfo.stackTrace); 11601 } 11602 sb.append("\n"); 11603 11604 // Only buffer up to ~64k. Various logging bits truncate 11605 // things at 128k. 11606 needsFlush = (sb.length() > 64 * 1024); 11607 } 11608 11609 // Flush immediately if the buffer's grown too large, or this 11610 // is a non-system app. Non-system apps are isolated with a 11611 // different tag & policy and not batched. 11612 // 11613 // Batching is useful during internal testing with 11614 // StrictMode settings turned up high. Without batching, 11615 // thousands of separate files could be created on boot. 11616 if (!isSystemApp || needsFlush) { 11617 new Thread("Error dump: " + dropboxTag) { 11618 @Override 11619 public void run() { 11620 String report; 11621 synchronized (sb) { 11622 report = sb.toString(); 11623 sb.delete(0, sb.length()); 11624 sb.trimToSize(); 11625 } 11626 if (report.length() != 0) { 11627 dbox.addText(dropboxTag, report); 11628 } 11629 } 11630 }.start(); 11631 return; 11632 } 11633 11634 // System app batching: 11635 if (!bufferWasEmpty) { 11636 // An existing dropbox-writing thread is outstanding, so 11637 // we don't need to start it up. The existing thread will 11638 // catch the buffer appends we just did. 11639 return; 11640 } 11641 11642 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11643 // (After this point, we shouldn't access AMS internal data structures.) 11644 new Thread("Error dump: " + dropboxTag) { 11645 @Override 11646 public void run() { 11647 // 5 second sleep to let stacks arrive and be batched together 11648 try { 11649 Thread.sleep(5000); // 5 seconds 11650 } catch (InterruptedException e) {} 11651 11652 String errorReport; 11653 synchronized (mStrictModeBuffer) { 11654 errorReport = mStrictModeBuffer.toString(); 11655 if (errorReport.length() == 0) { 11656 return; 11657 } 11658 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11659 mStrictModeBuffer.trimToSize(); 11660 } 11661 dbox.addText(dropboxTag, errorReport); 11662 } 11663 }.start(); 11664 } 11665 11666 /** 11667 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11668 * @param app object of the crashing app, null for the system server 11669 * @param tag reported by the caller 11670 * @param system whether this wtf is coming from the system 11671 * @param crashInfo describing the context of the error 11672 * @return true if the process should exit immediately (WTF is fatal) 11673 */ 11674 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11675 final ApplicationErrorReport.CrashInfo crashInfo) { 11676 final int callingUid = Binder.getCallingUid(); 11677 final int callingPid = Binder.getCallingPid(); 11678 11679 if (system) { 11680 // If this is coming from the system, we could very well have low-level 11681 // system locks held, so we want to do this all asynchronously. And we 11682 // never want this to become fatal, so there is that too. 11683 mHandler.post(new Runnable() { 11684 @Override public void run() { 11685 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11686 } 11687 }); 11688 return false; 11689 } 11690 11691 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11692 crashInfo); 11693 11694 if (r != null && r.pid != Process.myPid() && 11695 Settings.Global.getInt(mContext.getContentResolver(), 11696 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11697 crashApplication(r, crashInfo); 11698 return true; 11699 } else { 11700 return false; 11701 } 11702 } 11703 11704 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11705 final ApplicationErrorReport.CrashInfo crashInfo) { 11706 final ProcessRecord r = findAppProcess(app, "WTF"); 11707 final String processName = app == null ? "system_server" 11708 : (r == null ? "unknown" : r.processName); 11709 11710 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11711 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11712 11713 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11714 11715 return r; 11716 } 11717 11718 /** 11719 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11720 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11721 */ 11722 private ProcessRecord findAppProcess(IBinder app, String reason) { 11723 if (app == null) { 11724 return null; 11725 } 11726 11727 synchronized (this) { 11728 final int NP = mProcessNames.getMap().size(); 11729 for (int ip=0; ip<NP; ip++) { 11730 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11731 final int NA = apps.size(); 11732 for (int ia=0; ia<NA; ia++) { 11733 ProcessRecord p = apps.valueAt(ia); 11734 if (p.thread != null && p.thread.asBinder() == app) { 11735 return p; 11736 } 11737 } 11738 } 11739 11740 Slog.w(TAG, "Can't find mystery application for " + reason 11741 + " from pid=" + Binder.getCallingPid() 11742 + " uid=" + Binder.getCallingUid() + ": " + app); 11743 return null; 11744 } 11745 } 11746 11747 /** 11748 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11749 * to append various headers to the dropbox log text. 11750 */ 11751 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11752 StringBuilder sb) { 11753 // Watchdog thread ends up invoking this function (with 11754 // a null ProcessRecord) to add the stack file to dropbox. 11755 // Do not acquire a lock on this (am) in such cases, as it 11756 // could cause a potential deadlock, if and when watchdog 11757 // is invoked due to unavailability of lock on am and it 11758 // would prevent watchdog from killing system_server. 11759 if (process == null) { 11760 sb.append("Process: ").append(processName).append("\n"); 11761 return; 11762 } 11763 // Note: ProcessRecord 'process' is guarded by the service 11764 // instance. (notably process.pkgList, which could otherwise change 11765 // concurrently during execution of this method) 11766 synchronized (this) { 11767 sb.append("Process: ").append(processName).append("\n"); 11768 int flags = process.info.flags; 11769 IPackageManager pm = AppGlobals.getPackageManager(); 11770 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11771 for (int ip=0; ip<process.pkgList.size(); ip++) { 11772 String pkg = process.pkgList.keyAt(ip); 11773 sb.append("Package: ").append(pkg); 11774 try { 11775 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11776 if (pi != null) { 11777 sb.append(" v").append(pi.versionCode); 11778 if (pi.versionName != null) { 11779 sb.append(" (").append(pi.versionName).append(")"); 11780 } 11781 } 11782 } catch (RemoteException e) { 11783 Slog.e(TAG, "Error getting package info: " + pkg, e); 11784 } 11785 sb.append("\n"); 11786 } 11787 } 11788 } 11789 11790 private static String processClass(ProcessRecord process) { 11791 if (process == null || process.pid == MY_PID) { 11792 return "system_server"; 11793 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11794 return "system_app"; 11795 } else { 11796 return "data_app"; 11797 } 11798 } 11799 11800 /** 11801 * Write a description of an error (crash, WTF, ANR) to the drop box. 11802 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11803 * @param process which caused the error, null means the system server 11804 * @param activity which triggered the error, null if unknown 11805 * @param parent activity related to the error, null if unknown 11806 * @param subject line related to the error, null if absent 11807 * @param report in long form describing the error, null if absent 11808 * @param logFile to include in the report, null if none 11809 * @param crashInfo giving an application stack trace, null if absent 11810 */ 11811 public void addErrorToDropBox(String eventType, 11812 ProcessRecord process, String processName, ActivityRecord activity, 11813 ActivityRecord parent, String subject, 11814 final String report, final File logFile, 11815 final ApplicationErrorReport.CrashInfo crashInfo) { 11816 // NOTE -- this must never acquire the ActivityManagerService lock, 11817 // otherwise the watchdog may be prevented from resetting the system. 11818 11819 final String dropboxTag = processClass(process) + "_" + eventType; 11820 final DropBoxManager dbox = (DropBoxManager) 11821 mContext.getSystemService(Context.DROPBOX_SERVICE); 11822 11823 // Exit early if the dropbox isn't configured to accept this report type. 11824 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11825 11826 final StringBuilder sb = new StringBuilder(1024); 11827 appendDropBoxProcessHeaders(process, processName, sb); 11828 if (activity != null) { 11829 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11830 } 11831 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11832 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11833 } 11834 if (parent != null && parent != activity) { 11835 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11836 } 11837 if (subject != null) { 11838 sb.append("Subject: ").append(subject).append("\n"); 11839 } 11840 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11841 if (Debug.isDebuggerConnected()) { 11842 sb.append("Debugger: Connected\n"); 11843 } 11844 sb.append("\n"); 11845 11846 // Do the rest in a worker thread to avoid blocking the caller on I/O 11847 // (After this point, we shouldn't access AMS internal data structures.) 11848 Thread worker = new Thread("Error dump: " + dropboxTag) { 11849 @Override 11850 public void run() { 11851 if (report != null) { 11852 sb.append(report); 11853 } 11854 if (logFile != null) { 11855 try { 11856 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11857 "\n\n[[TRUNCATED]]")); 11858 } catch (IOException e) { 11859 Slog.e(TAG, "Error reading " + logFile, e); 11860 } 11861 } 11862 if (crashInfo != null && crashInfo.stackTrace != null) { 11863 sb.append(crashInfo.stackTrace); 11864 } 11865 11866 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11867 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11868 if (lines > 0) { 11869 sb.append("\n"); 11870 11871 // Merge several logcat streams, and take the last N lines 11872 InputStreamReader input = null; 11873 try { 11874 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11875 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11876 "-b", "crash", 11877 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11878 11879 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11880 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11881 input = new InputStreamReader(logcat.getInputStream()); 11882 11883 int num; 11884 char[] buf = new char[8192]; 11885 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11886 } catch (IOException e) { 11887 Slog.e(TAG, "Error running logcat", e); 11888 } finally { 11889 if (input != null) try { input.close(); } catch (IOException e) {} 11890 } 11891 } 11892 11893 dbox.addText(dropboxTag, sb.toString()); 11894 } 11895 }; 11896 11897 if (process == null) { 11898 // If process is null, we are being called from some internal code 11899 // and may be about to die -- run this synchronously. 11900 worker.run(); 11901 } else { 11902 worker.start(); 11903 } 11904 } 11905 11906 /** 11907 * Bring up the "unexpected error" dialog box for a crashing app. 11908 * Deal with edge cases (intercepts from instrumented applications, 11909 * ActivityController, error intent receivers, that sort of thing). 11910 * @param r the application crashing 11911 * @param crashInfo describing the failure 11912 */ 11913 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11914 long timeMillis = System.currentTimeMillis(); 11915 String shortMsg = crashInfo.exceptionClassName; 11916 String longMsg = crashInfo.exceptionMessage; 11917 String stackTrace = crashInfo.stackTrace; 11918 if (shortMsg != null && longMsg != null) { 11919 longMsg = shortMsg + ": " + longMsg; 11920 } else if (shortMsg != null) { 11921 longMsg = shortMsg; 11922 } 11923 11924 AppErrorResult result = new AppErrorResult(); 11925 synchronized (this) { 11926 if (mController != null) { 11927 try { 11928 String name = r != null ? r.processName : null; 11929 int pid = r != null ? r.pid : Binder.getCallingPid(); 11930 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11931 if (!mController.appCrashed(name, pid, 11932 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11933 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11934 && "Native crash".equals(crashInfo.exceptionClassName)) { 11935 Slog.w(TAG, "Skip killing native crashed app " + name 11936 + "(" + pid + ") during testing"); 11937 } else { 11938 Slog.w(TAG, "Force-killing crashed app " + name 11939 + " at watcher's request"); 11940 if (r != null) { 11941 r.kill("crash", true); 11942 } else { 11943 // Huh. 11944 Process.killProcess(pid); 11945 Process.killProcessGroup(uid, pid); 11946 } 11947 } 11948 return; 11949 } 11950 } catch (RemoteException e) { 11951 mController = null; 11952 Watchdog.getInstance().setActivityController(null); 11953 } 11954 } 11955 11956 final long origId = Binder.clearCallingIdentity(); 11957 11958 // If this process is running instrumentation, finish it. 11959 if (r != null && r.instrumentationClass != null) { 11960 Slog.w(TAG, "Error in app " + r.processName 11961 + " running instrumentation " + r.instrumentationClass + ":"); 11962 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11963 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11964 Bundle info = new Bundle(); 11965 info.putString("shortMsg", shortMsg); 11966 info.putString("longMsg", longMsg); 11967 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11968 Binder.restoreCallingIdentity(origId); 11969 return; 11970 } 11971 11972 // If we can't identify the process or it's already exceeded its crash quota, 11973 // quit right away without showing a crash dialog. 11974 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11975 Binder.restoreCallingIdentity(origId); 11976 return; 11977 } 11978 11979 Message msg = Message.obtain(); 11980 msg.what = SHOW_ERROR_MSG; 11981 HashMap data = new HashMap(); 11982 data.put("result", result); 11983 data.put("app", r); 11984 msg.obj = data; 11985 mHandler.sendMessage(msg); 11986 11987 Binder.restoreCallingIdentity(origId); 11988 } 11989 11990 int res = result.get(); 11991 11992 Intent appErrorIntent = null; 11993 synchronized (this) { 11994 if (r != null && !r.isolated) { 11995 // XXX Can't keep track of crash time for isolated processes, 11996 // since they don't have a persistent identity. 11997 mProcessCrashTimes.put(r.info.processName, r.uid, 11998 SystemClock.uptimeMillis()); 11999 } 12000 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12001 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12002 } 12003 } 12004 12005 if (appErrorIntent != null) { 12006 try { 12007 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12008 } catch (ActivityNotFoundException e) { 12009 Slog.w(TAG, "bug report receiver dissappeared", e); 12010 } 12011 } 12012 } 12013 12014 Intent createAppErrorIntentLocked(ProcessRecord r, 12015 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12016 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12017 if (report == null) { 12018 return null; 12019 } 12020 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12021 result.setComponent(r.errorReportReceiver); 12022 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12023 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12024 return result; 12025 } 12026 12027 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12028 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12029 if (r.errorReportReceiver == null) { 12030 return null; 12031 } 12032 12033 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12034 return null; 12035 } 12036 12037 ApplicationErrorReport report = new ApplicationErrorReport(); 12038 report.packageName = r.info.packageName; 12039 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12040 report.processName = r.processName; 12041 report.time = timeMillis; 12042 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12043 12044 if (r.crashing || r.forceCrashReport) { 12045 report.type = ApplicationErrorReport.TYPE_CRASH; 12046 report.crashInfo = crashInfo; 12047 } else if (r.notResponding) { 12048 report.type = ApplicationErrorReport.TYPE_ANR; 12049 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12050 12051 report.anrInfo.activity = r.notRespondingReport.tag; 12052 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12053 report.anrInfo.info = r.notRespondingReport.longMsg; 12054 } 12055 12056 return report; 12057 } 12058 12059 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12060 enforceNotIsolatedCaller("getProcessesInErrorState"); 12061 // assume our apps are happy - lazy create the list 12062 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12063 12064 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12065 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12066 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12067 12068 synchronized (this) { 12069 12070 // iterate across all processes 12071 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12072 ProcessRecord app = mLruProcesses.get(i); 12073 if (!allUsers && app.userId != userId) { 12074 continue; 12075 } 12076 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12077 // This one's in trouble, so we'll generate a report for it 12078 // crashes are higher priority (in case there's a crash *and* an anr) 12079 ActivityManager.ProcessErrorStateInfo report = null; 12080 if (app.crashing) { 12081 report = app.crashingReport; 12082 } else if (app.notResponding) { 12083 report = app.notRespondingReport; 12084 } 12085 12086 if (report != null) { 12087 if (errList == null) { 12088 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12089 } 12090 errList.add(report); 12091 } else { 12092 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12093 " crashing = " + app.crashing + 12094 " notResponding = " + app.notResponding); 12095 } 12096 } 12097 } 12098 } 12099 12100 return errList; 12101 } 12102 12103 static int procStateToImportance(int procState, int memAdj, 12104 ActivityManager.RunningAppProcessInfo currApp) { 12105 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12106 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12107 currApp.lru = memAdj; 12108 } else { 12109 currApp.lru = 0; 12110 } 12111 return imp; 12112 } 12113 12114 private void fillInProcMemInfo(ProcessRecord app, 12115 ActivityManager.RunningAppProcessInfo outInfo) { 12116 outInfo.pid = app.pid; 12117 outInfo.uid = app.info.uid; 12118 if (mHeavyWeightProcess == app) { 12119 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12120 } 12121 if (app.persistent) { 12122 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12123 } 12124 if (app.activities.size() > 0) { 12125 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12126 } 12127 outInfo.lastTrimLevel = app.trimMemoryLevel; 12128 int adj = app.curAdj; 12129 int procState = app.curProcState; 12130 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12131 outInfo.importanceReasonCode = app.adjTypeCode; 12132 outInfo.processState = app.curProcState; 12133 } 12134 12135 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12136 enforceNotIsolatedCaller("getRunningAppProcesses"); 12137 // Lazy instantiation of list 12138 List<ActivityManager.RunningAppProcessInfo> runList = null; 12139 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12140 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12141 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12142 synchronized (this) { 12143 // Iterate across all processes 12144 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12145 ProcessRecord app = mLruProcesses.get(i); 12146 if (!allUsers && app.userId != userId) { 12147 continue; 12148 } 12149 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12150 // Generate process state info for running application 12151 ActivityManager.RunningAppProcessInfo currApp = 12152 new ActivityManager.RunningAppProcessInfo(app.processName, 12153 app.pid, app.getPackageList()); 12154 fillInProcMemInfo(app, currApp); 12155 if (app.adjSource instanceof ProcessRecord) { 12156 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12157 currApp.importanceReasonImportance = 12158 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12159 app.adjSourceProcState); 12160 } else if (app.adjSource instanceof ActivityRecord) { 12161 ActivityRecord r = (ActivityRecord)app.adjSource; 12162 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12163 } 12164 if (app.adjTarget instanceof ComponentName) { 12165 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12166 } 12167 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12168 // + " lru=" + currApp.lru); 12169 if (runList == null) { 12170 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12171 } 12172 runList.add(currApp); 12173 } 12174 } 12175 } 12176 return runList; 12177 } 12178 12179 public List<ApplicationInfo> getRunningExternalApplications() { 12180 enforceNotIsolatedCaller("getRunningExternalApplications"); 12181 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12182 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12183 if (runningApps != null && runningApps.size() > 0) { 12184 Set<String> extList = new HashSet<String>(); 12185 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12186 if (app.pkgList != null) { 12187 for (String pkg : app.pkgList) { 12188 extList.add(pkg); 12189 } 12190 } 12191 } 12192 IPackageManager pm = AppGlobals.getPackageManager(); 12193 for (String pkg : extList) { 12194 try { 12195 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12196 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12197 retList.add(info); 12198 } 12199 } catch (RemoteException e) { 12200 } 12201 } 12202 } 12203 return retList; 12204 } 12205 12206 @Override 12207 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12208 enforceNotIsolatedCaller("getMyMemoryState"); 12209 synchronized (this) { 12210 ProcessRecord proc; 12211 synchronized (mPidsSelfLocked) { 12212 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12213 } 12214 fillInProcMemInfo(proc, outInfo); 12215 } 12216 } 12217 12218 @Override 12219 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12220 if (checkCallingPermission(android.Manifest.permission.DUMP) 12221 != PackageManager.PERMISSION_GRANTED) { 12222 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12223 + Binder.getCallingPid() 12224 + ", uid=" + Binder.getCallingUid() 12225 + " without permission " 12226 + android.Manifest.permission.DUMP); 12227 return; 12228 } 12229 12230 boolean dumpAll = false; 12231 boolean dumpClient = false; 12232 String dumpPackage = null; 12233 12234 int opti = 0; 12235 while (opti < args.length) { 12236 String opt = args[opti]; 12237 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12238 break; 12239 } 12240 opti++; 12241 if ("-a".equals(opt)) { 12242 dumpAll = true; 12243 } else if ("-c".equals(opt)) { 12244 dumpClient = true; 12245 } else if ("-h".equals(opt)) { 12246 pw.println("Activity manager dump options:"); 12247 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12248 pw.println(" cmd may be one of:"); 12249 pw.println(" a[ctivities]: activity stack state"); 12250 pw.println(" r[recents]: recent activities state"); 12251 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12252 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12253 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12254 pw.println(" o[om]: out of memory management"); 12255 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12256 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12257 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12258 pw.println(" service [COMP_SPEC]: service client-side state"); 12259 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12260 pw.println(" all: dump all activities"); 12261 pw.println(" top: dump the top activity"); 12262 pw.println(" write: write all pending state to storage"); 12263 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12264 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12265 pw.println(" a partial substring in a component name, a"); 12266 pw.println(" hex object identifier."); 12267 pw.println(" -a: include all available server state."); 12268 pw.println(" -c: include client state."); 12269 return; 12270 } else { 12271 pw.println("Unknown argument: " + opt + "; use -h for help"); 12272 } 12273 } 12274 12275 long origId = Binder.clearCallingIdentity(); 12276 boolean more = false; 12277 // Is the caller requesting to dump a particular piece of data? 12278 if (opti < args.length) { 12279 String cmd = args[opti]; 12280 opti++; 12281 if ("activities".equals(cmd) || "a".equals(cmd)) { 12282 synchronized (this) { 12283 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12284 } 12285 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12286 synchronized (this) { 12287 dumpRecentsLocked(fd, pw, args, opti, true, null); 12288 } 12289 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12290 String[] newArgs; 12291 String name; 12292 if (opti >= args.length) { 12293 name = null; 12294 newArgs = EMPTY_STRING_ARRAY; 12295 } else { 12296 name = args[opti]; 12297 opti++; 12298 newArgs = new String[args.length - opti]; 12299 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12300 args.length - opti); 12301 } 12302 synchronized (this) { 12303 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12304 } 12305 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12306 String[] newArgs; 12307 String name; 12308 if (opti >= args.length) { 12309 name = null; 12310 newArgs = EMPTY_STRING_ARRAY; 12311 } else { 12312 name = args[opti]; 12313 opti++; 12314 newArgs = new String[args.length - opti]; 12315 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12316 args.length - opti); 12317 } 12318 synchronized (this) { 12319 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12320 } 12321 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12322 String[] newArgs; 12323 String name; 12324 if (opti >= args.length) { 12325 name = null; 12326 newArgs = EMPTY_STRING_ARRAY; 12327 } else { 12328 name = args[opti]; 12329 opti++; 12330 newArgs = new String[args.length - opti]; 12331 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12332 args.length - opti); 12333 } 12334 synchronized (this) { 12335 dumpProcessesLocked(fd, pw, args, opti, true, name); 12336 } 12337 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12338 synchronized (this) { 12339 dumpOomLocked(fd, pw, args, opti, true); 12340 } 12341 } else if ("provider".equals(cmd)) { 12342 String[] newArgs; 12343 String name; 12344 if (opti >= args.length) { 12345 name = null; 12346 newArgs = EMPTY_STRING_ARRAY; 12347 } else { 12348 name = args[opti]; 12349 opti++; 12350 newArgs = new String[args.length - opti]; 12351 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12352 } 12353 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12354 pw.println("No providers match: " + name); 12355 pw.println("Use -h for help."); 12356 } 12357 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12358 synchronized (this) { 12359 dumpProvidersLocked(fd, pw, args, opti, true, null); 12360 } 12361 } else if ("service".equals(cmd)) { 12362 String[] newArgs; 12363 String name; 12364 if (opti >= args.length) { 12365 name = null; 12366 newArgs = EMPTY_STRING_ARRAY; 12367 } else { 12368 name = args[opti]; 12369 opti++; 12370 newArgs = new String[args.length - opti]; 12371 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12372 args.length - opti); 12373 } 12374 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12375 pw.println("No services match: " + name); 12376 pw.println("Use -h for help."); 12377 } 12378 } else if ("package".equals(cmd)) { 12379 String[] newArgs; 12380 if (opti >= args.length) { 12381 pw.println("package: no package name specified"); 12382 pw.println("Use -h for help."); 12383 } else { 12384 dumpPackage = args[opti]; 12385 opti++; 12386 newArgs = new String[args.length - opti]; 12387 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12388 args.length - opti); 12389 args = newArgs; 12390 opti = 0; 12391 more = true; 12392 } 12393 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12394 synchronized (this) { 12395 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12396 } 12397 } else if ("write".equals(cmd)) { 12398 mTaskPersister.flush(); 12399 pw.println("All tasks persisted."); 12400 return; 12401 } else { 12402 // Dumping a single activity? 12403 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12404 pw.println("Bad activity command, or no activities match: " + cmd); 12405 pw.println("Use -h for help."); 12406 } 12407 } 12408 if (!more) { 12409 Binder.restoreCallingIdentity(origId); 12410 return; 12411 } 12412 } 12413 12414 // No piece of data specified, dump everything. 12415 synchronized (this) { 12416 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12417 pw.println(); 12418 if (dumpAll) { 12419 pw.println("-------------------------------------------------------------------------------"); 12420 } 12421 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12422 pw.println(); 12423 if (dumpAll) { 12424 pw.println("-------------------------------------------------------------------------------"); 12425 } 12426 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12427 pw.println(); 12428 if (dumpAll) { 12429 pw.println("-------------------------------------------------------------------------------"); 12430 } 12431 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12432 pw.println(); 12433 if (dumpAll) { 12434 pw.println("-------------------------------------------------------------------------------"); 12435 } 12436 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12437 pw.println(); 12438 if (dumpAll) { 12439 pw.println("-------------------------------------------------------------------------------"); 12440 } 12441 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12442 pw.println(); 12443 if (dumpAll) { 12444 pw.println("-------------------------------------------------------------------------------"); 12445 } 12446 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12447 } 12448 Binder.restoreCallingIdentity(origId); 12449 } 12450 12451 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12452 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12453 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12454 12455 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12456 dumpPackage); 12457 boolean needSep = printedAnything; 12458 12459 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12460 dumpPackage, needSep, " mFocusedActivity: "); 12461 if (printed) { 12462 printedAnything = true; 12463 needSep = false; 12464 } 12465 12466 if (dumpPackage == null) { 12467 if (needSep) { 12468 pw.println(); 12469 } 12470 needSep = true; 12471 printedAnything = true; 12472 mStackSupervisor.dump(pw, " "); 12473 } 12474 12475 if (!printedAnything) { 12476 pw.println(" (nothing)"); 12477 } 12478 } 12479 12480 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12481 int opti, boolean dumpAll, String dumpPackage) { 12482 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12483 12484 boolean printedAnything = false; 12485 12486 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12487 boolean printedHeader = false; 12488 12489 final int N = mRecentTasks.size(); 12490 for (int i=0; i<N; i++) { 12491 TaskRecord tr = mRecentTasks.get(i); 12492 if (dumpPackage != null) { 12493 if (tr.realActivity == null || 12494 !dumpPackage.equals(tr.realActivity)) { 12495 continue; 12496 } 12497 } 12498 if (!printedHeader) { 12499 pw.println(" Recent tasks:"); 12500 printedHeader = true; 12501 printedAnything = true; 12502 } 12503 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12504 pw.println(tr); 12505 if (dumpAll) { 12506 mRecentTasks.get(i).dump(pw, " "); 12507 } 12508 } 12509 } 12510 12511 if (!printedAnything) { 12512 pw.println(" (nothing)"); 12513 } 12514 } 12515 12516 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12517 int opti, boolean dumpAll, String dumpPackage) { 12518 boolean needSep = false; 12519 boolean printedAnything = false; 12520 int numPers = 0; 12521 12522 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12523 12524 if (dumpAll) { 12525 final int NP = mProcessNames.getMap().size(); 12526 for (int ip=0; ip<NP; ip++) { 12527 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12528 final int NA = procs.size(); 12529 for (int ia=0; ia<NA; ia++) { 12530 ProcessRecord r = procs.valueAt(ia); 12531 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12532 continue; 12533 } 12534 if (!needSep) { 12535 pw.println(" All known processes:"); 12536 needSep = true; 12537 printedAnything = true; 12538 } 12539 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12540 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12541 pw.print(" "); pw.println(r); 12542 r.dump(pw, " "); 12543 if (r.persistent) { 12544 numPers++; 12545 } 12546 } 12547 } 12548 } 12549 12550 if (mIsolatedProcesses.size() > 0) { 12551 boolean printed = false; 12552 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12553 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12554 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12555 continue; 12556 } 12557 if (!printed) { 12558 if (needSep) { 12559 pw.println(); 12560 } 12561 pw.println(" Isolated process list (sorted by uid):"); 12562 printedAnything = true; 12563 printed = true; 12564 needSep = true; 12565 } 12566 pw.println(String.format("%sIsolated #%2d: %s", 12567 " ", i, r.toString())); 12568 } 12569 } 12570 12571 if (mLruProcesses.size() > 0) { 12572 if (needSep) { 12573 pw.println(); 12574 } 12575 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12576 pw.print(" total, non-act at "); 12577 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12578 pw.print(", non-svc at "); 12579 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12580 pw.println("):"); 12581 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12582 needSep = true; 12583 printedAnything = true; 12584 } 12585 12586 if (dumpAll || dumpPackage != null) { 12587 synchronized (mPidsSelfLocked) { 12588 boolean printed = false; 12589 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12590 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12591 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12592 continue; 12593 } 12594 if (!printed) { 12595 if (needSep) pw.println(); 12596 needSep = true; 12597 pw.println(" PID mappings:"); 12598 printed = true; 12599 printedAnything = true; 12600 } 12601 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12602 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12603 } 12604 } 12605 } 12606 12607 if (mForegroundProcesses.size() > 0) { 12608 synchronized (mPidsSelfLocked) { 12609 boolean printed = false; 12610 for (int i=0; i<mForegroundProcesses.size(); i++) { 12611 ProcessRecord r = mPidsSelfLocked.get( 12612 mForegroundProcesses.valueAt(i).pid); 12613 if (dumpPackage != null && (r == null 12614 || !r.pkgList.containsKey(dumpPackage))) { 12615 continue; 12616 } 12617 if (!printed) { 12618 if (needSep) pw.println(); 12619 needSep = true; 12620 pw.println(" Foreground Processes:"); 12621 printed = true; 12622 printedAnything = true; 12623 } 12624 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12625 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12626 } 12627 } 12628 } 12629 12630 if (mPersistentStartingProcesses.size() > 0) { 12631 if (needSep) pw.println(); 12632 needSep = true; 12633 printedAnything = true; 12634 pw.println(" Persisent processes that are starting:"); 12635 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12636 "Starting Norm", "Restarting PERS", dumpPackage); 12637 } 12638 12639 if (mRemovedProcesses.size() > 0) { 12640 if (needSep) pw.println(); 12641 needSep = true; 12642 printedAnything = true; 12643 pw.println(" Processes that are being removed:"); 12644 dumpProcessList(pw, this, mRemovedProcesses, " ", 12645 "Removed Norm", "Removed PERS", dumpPackage); 12646 } 12647 12648 if (mProcessesOnHold.size() > 0) { 12649 if (needSep) pw.println(); 12650 needSep = true; 12651 printedAnything = true; 12652 pw.println(" Processes that are on old until the system is ready:"); 12653 dumpProcessList(pw, this, mProcessesOnHold, " ", 12654 "OnHold Norm", "OnHold PERS", dumpPackage); 12655 } 12656 12657 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12658 12659 if (mProcessCrashTimes.getMap().size() > 0) { 12660 boolean printed = false; 12661 long now = SystemClock.uptimeMillis(); 12662 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12663 final int NP = pmap.size(); 12664 for (int ip=0; ip<NP; ip++) { 12665 String pname = pmap.keyAt(ip); 12666 SparseArray<Long> uids = pmap.valueAt(ip); 12667 final int N = uids.size(); 12668 for (int i=0; i<N; i++) { 12669 int puid = uids.keyAt(i); 12670 ProcessRecord r = mProcessNames.get(pname, puid); 12671 if (dumpPackage != null && (r == null 12672 || !r.pkgList.containsKey(dumpPackage))) { 12673 continue; 12674 } 12675 if (!printed) { 12676 if (needSep) pw.println(); 12677 needSep = true; 12678 pw.println(" Time since processes crashed:"); 12679 printed = true; 12680 printedAnything = true; 12681 } 12682 pw.print(" Process "); pw.print(pname); 12683 pw.print(" uid "); pw.print(puid); 12684 pw.print(": last crashed "); 12685 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12686 pw.println(" ago"); 12687 } 12688 } 12689 } 12690 12691 if (mBadProcesses.getMap().size() > 0) { 12692 boolean printed = false; 12693 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12694 final int NP = pmap.size(); 12695 for (int ip=0; ip<NP; ip++) { 12696 String pname = pmap.keyAt(ip); 12697 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12698 final int N = uids.size(); 12699 for (int i=0; i<N; i++) { 12700 int puid = uids.keyAt(i); 12701 ProcessRecord r = mProcessNames.get(pname, puid); 12702 if (dumpPackage != null && (r == null 12703 || !r.pkgList.containsKey(dumpPackage))) { 12704 continue; 12705 } 12706 if (!printed) { 12707 if (needSep) pw.println(); 12708 needSep = true; 12709 pw.println(" Bad processes:"); 12710 printedAnything = true; 12711 } 12712 BadProcessInfo info = uids.valueAt(i); 12713 pw.print(" Bad process "); pw.print(pname); 12714 pw.print(" uid "); pw.print(puid); 12715 pw.print(": crashed at time "); pw.println(info.time); 12716 if (info.shortMsg != null) { 12717 pw.print(" Short msg: "); pw.println(info.shortMsg); 12718 } 12719 if (info.longMsg != null) { 12720 pw.print(" Long msg: "); pw.println(info.longMsg); 12721 } 12722 if (info.stack != null) { 12723 pw.println(" Stack:"); 12724 int lastPos = 0; 12725 for (int pos=0; pos<info.stack.length(); pos++) { 12726 if (info.stack.charAt(pos) == '\n') { 12727 pw.print(" "); 12728 pw.write(info.stack, lastPos, pos-lastPos); 12729 pw.println(); 12730 lastPos = pos+1; 12731 } 12732 } 12733 if (lastPos < info.stack.length()) { 12734 pw.print(" "); 12735 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12736 pw.println(); 12737 } 12738 } 12739 } 12740 } 12741 } 12742 12743 if (dumpPackage == null) { 12744 pw.println(); 12745 needSep = false; 12746 pw.println(" mStartedUsers:"); 12747 for (int i=0; i<mStartedUsers.size(); i++) { 12748 UserStartedState uss = mStartedUsers.valueAt(i); 12749 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12750 pw.print(": "); uss.dump("", pw); 12751 } 12752 pw.print(" mStartedUserArray: ["); 12753 for (int i=0; i<mStartedUserArray.length; i++) { 12754 if (i > 0) pw.print(", "); 12755 pw.print(mStartedUserArray[i]); 12756 } 12757 pw.println("]"); 12758 pw.print(" mUserLru: ["); 12759 for (int i=0; i<mUserLru.size(); i++) { 12760 if (i > 0) pw.print(", "); 12761 pw.print(mUserLru.get(i)); 12762 } 12763 pw.println("]"); 12764 if (dumpAll) { 12765 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12766 } 12767 synchronized (mUserProfileGroupIdsSelfLocked) { 12768 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12769 pw.println(" mUserProfileGroupIds:"); 12770 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12771 pw.print(" User #"); 12772 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12773 pw.print(" -> profile #"); 12774 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12775 } 12776 } 12777 } 12778 } 12779 if (mHomeProcess != null && (dumpPackage == null 12780 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12781 if (needSep) { 12782 pw.println(); 12783 needSep = false; 12784 } 12785 pw.println(" mHomeProcess: " + mHomeProcess); 12786 } 12787 if (mPreviousProcess != null && (dumpPackage == null 12788 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12789 if (needSep) { 12790 pw.println(); 12791 needSep = false; 12792 } 12793 pw.println(" mPreviousProcess: " + mPreviousProcess); 12794 } 12795 if (dumpAll) { 12796 StringBuilder sb = new StringBuilder(128); 12797 sb.append(" mPreviousProcessVisibleTime: "); 12798 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12799 pw.println(sb); 12800 } 12801 if (mHeavyWeightProcess != null && (dumpPackage == null 12802 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12803 if (needSep) { 12804 pw.println(); 12805 needSep = false; 12806 } 12807 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12808 } 12809 if (dumpPackage == null) { 12810 pw.println(" mConfiguration: " + mConfiguration); 12811 } 12812 if (dumpAll) { 12813 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12814 if (mCompatModePackages.getPackages().size() > 0) { 12815 boolean printed = false; 12816 for (Map.Entry<String, Integer> entry 12817 : mCompatModePackages.getPackages().entrySet()) { 12818 String pkg = entry.getKey(); 12819 int mode = entry.getValue(); 12820 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12821 continue; 12822 } 12823 if (!printed) { 12824 pw.println(" mScreenCompatPackages:"); 12825 printed = true; 12826 } 12827 pw.print(" "); pw.print(pkg); pw.print(": "); 12828 pw.print(mode); pw.println(); 12829 } 12830 } 12831 } 12832 if (dumpPackage == null) { 12833 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12834 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12835 + " mLockScreenShown " + lockScreenShownToString()); 12836 } 12837 if (mShuttingDown || mRunningVoice) { 12838 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12839 } 12840 } 12841 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12842 || mOrigWaitForDebugger) { 12843 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12844 || dumpPackage.equals(mOrigDebugApp)) { 12845 if (needSep) { 12846 pw.println(); 12847 needSep = false; 12848 } 12849 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12850 + " mDebugTransient=" + mDebugTransient 12851 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12852 } 12853 } 12854 if (mOpenGlTraceApp != null) { 12855 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12856 if (needSep) { 12857 pw.println(); 12858 needSep = false; 12859 } 12860 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12861 } 12862 } 12863 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12864 || mProfileFd != null) { 12865 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12866 if (needSep) { 12867 pw.println(); 12868 needSep = false; 12869 } 12870 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12871 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12872 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12873 + mAutoStopProfiler); 12874 pw.println(" mProfileType=" + mProfileType); 12875 } 12876 } 12877 if (dumpPackage == null) { 12878 if (mAlwaysFinishActivities || mController != null) { 12879 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12880 + " mController=" + mController); 12881 } 12882 if (dumpAll) { 12883 pw.println(" Total persistent processes: " + numPers); 12884 pw.println(" mProcessesReady=" + mProcessesReady 12885 + " mSystemReady=" + mSystemReady 12886 + " mBooted=" + mBooted 12887 + " mFactoryTest=" + mFactoryTest); 12888 pw.println(" mBooting=" + mBooting 12889 + " mCallFinishBooting=" + mCallFinishBooting 12890 + " mBootAnimationComplete=" + mBootAnimationComplete); 12891 pw.print(" mLastPowerCheckRealtime="); 12892 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12893 pw.println(""); 12894 pw.print(" mLastPowerCheckUptime="); 12895 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12896 pw.println(""); 12897 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12898 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12899 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12900 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12901 + " (" + mLruProcesses.size() + " total)" 12902 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12903 + " mNumServiceProcs=" + mNumServiceProcs 12904 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12905 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12906 + " mLastMemoryLevel" + mLastMemoryLevel 12907 + " mLastNumProcesses" + mLastNumProcesses); 12908 long now = SystemClock.uptimeMillis(); 12909 pw.print(" mLastIdleTime="); 12910 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12911 pw.print(" mLowRamSinceLastIdle="); 12912 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12913 pw.println(); 12914 } 12915 } 12916 12917 if (!printedAnything) { 12918 pw.println(" (nothing)"); 12919 } 12920 } 12921 12922 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12923 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12924 if (mProcessesToGc.size() > 0) { 12925 boolean printed = false; 12926 long now = SystemClock.uptimeMillis(); 12927 for (int i=0; i<mProcessesToGc.size(); i++) { 12928 ProcessRecord proc = mProcessesToGc.get(i); 12929 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12930 continue; 12931 } 12932 if (!printed) { 12933 if (needSep) pw.println(); 12934 needSep = true; 12935 pw.println(" Processes that are waiting to GC:"); 12936 printed = true; 12937 } 12938 pw.print(" Process "); pw.println(proc); 12939 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12940 pw.print(", last gced="); 12941 pw.print(now-proc.lastRequestedGc); 12942 pw.print(" ms ago, last lowMem="); 12943 pw.print(now-proc.lastLowMemory); 12944 pw.println(" ms ago"); 12945 12946 } 12947 } 12948 return needSep; 12949 } 12950 12951 void printOomLevel(PrintWriter pw, String name, int adj) { 12952 pw.print(" "); 12953 if (adj >= 0) { 12954 pw.print(' '); 12955 if (adj < 10) pw.print(' '); 12956 } else { 12957 if (adj > -10) pw.print(' '); 12958 } 12959 pw.print(adj); 12960 pw.print(": "); 12961 pw.print(name); 12962 pw.print(" ("); 12963 pw.print(mProcessList.getMemLevel(adj)/1024); 12964 pw.println(" kB)"); 12965 } 12966 12967 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12968 int opti, boolean dumpAll) { 12969 boolean needSep = false; 12970 12971 if (mLruProcesses.size() > 0) { 12972 if (needSep) pw.println(); 12973 needSep = true; 12974 pw.println(" OOM levels:"); 12975 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12976 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12977 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12978 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12979 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12980 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12981 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12982 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12983 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12984 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12985 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12986 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12987 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12988 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12989 12990 if (needSep) pw.println(); 12991 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12992 pw.print(" total, non-act at "); 12993 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12994 pw.print(", non-svc at "); 12995 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12996 pw.println("):"); 12997 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12998 needSep = true; 12999 } 13000 13001 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13002 13003 pw.println(); 13004 pw.println(" mHomeProcess: " + mHomeProcess); 13005 pw.println(" mPreviousProcess: " + mPreviousProcess); 13006 if (mHeavyWeightProcess != null) { 13007 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13008 } 13009 13010 return true; 13011 } 13012 13013 /** 13014 * There are three ways to call this: 13015 * - no provider specified: dump all the providers 13016 * - a flattened component name that matched an existing provider was specified as the 13017 * first arg: dump that one provider 13018 * - the first arg isn't the flattened component name of an existing provider: 13019 * dump all providers whose component contains the first arg as a substring 13020 */ 13021 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13022 int opti, boolean dumpAll) { 13023 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13024 } 13025 13026 static class ItemMatcher { 13027 ArrayList<ComponentName> components; 13028 ArrayList<String> strings; 13029 ArrayList<Integer> objects; 13030 boolean all; 13031 13032 ItemMatcher() { 13033 all = true; 13034 } 13035 13036 void build(String name) { 13037 ComponentName componentName = ComponentName.unflattenFromString(name); 13038 if (componentName != null) { 13039 if (components == null) { 13040 components = new ArrayList<ComponentName>(); 13041 } 13042 components.add(componentName); 13043 all = false; 13044 } else { 13045 int objectId = 0; 13046 // Not a '/' separated full component name; maybe an object ID? 13047 try { 13048 objectId = Integer.parseInt(name, 16); 13049 if (objects == null) { 13050 objects = new ArrayList<Integer>(); 13051 } 13052 objects.add(objectId); 13053 all = false; 13054 } catch (RuntimeException e) { 13055 // Not an integer; just do string match. 13056 if (strings == null) { 13057 strings = new ArrayList<String>(); 13058 } 13059 strings.add(name); 13060 all = false; 13061 } 13062 } 13063 } 13064 13065 int build(String[] args, int opti) { 13066 for (; opti<args.length; opti++) { 13067 String name = args[opti]; 13068 if ("--".equals(name)) { 13069 return opti+1; 13070 } 13071 build(name); 13072 } 13073 return opti; 13074 } 13075 13076 boolean match(Object object, ComponentName comp) { 13077 if (all) { 13078 return true; 13079 } 13080 if (components != null) { 13081 for (int i=0; i<components.size(); i++) { 13082 if (components.get(i).equals(comp)) { 13083 return true; 13084 } 13085 } 13086 } 13087 if (objects != null) { 13088 for (int i=0; i<objects.size(); i++) { 13089 if (System.identityHashCode(object) == objects.get(i)) { 13090 return true; 13091 } 13092 } 13093 } 13094 if (strings != null) { 13095 String flat = comp.flattenToString(); 13096 for (int i=0; i<strings.size(); i++) { 13097 if (flat.contains(strings.get(i))) { 13098 return true; 13099 } 13100 } 13101 } 13102 return false; 13103 } 13104 } 13105 13106 /** 13107 * There are three things that cmd can be: 13108 * - a flattened component name that matches an existing activity 13109 * - the cmd arg isn't the flattened component name of an existing activity: 13110 * dump all activity whose component contains the cmd as a substring 13111 * - A hex number of the ActivityRecord object instance. 13112 */ 13113 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13114 int opti, boolean dumpAll) { 13115 ArrayList<ActivityRecord> activities; 13116 13117 synchronized (this) { 13118 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13119 } 13120 13121 if (activities.size() <= 0) { 13122 return false; 13123 } 13124 13125 String[] newArgs = new String[args.length - opti]; 13126 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13127 13128 TaskRecord lastTask = null; 13129 boolean needSep = false; 13130 for (int i=activities.size()-1; i>=0; i--) { 13131 ActivityRecord r = activities.get(i); 13132 if (needSep) { 13133 pw.println(); 13134 } 13135 needSep = true; 13136 synchronized (this) { 13137 if (lastTask != r.task) { 13138 lastTask = r.task; 13139 pw.print("TASK "); pw.print(lastTask.affinity); 13140 pw.print(" id="); pw.println(lastTask.taskId); 13141 if (dumpAll) { 13142 lastTask.dump(pw, " "); 13143 } 13144 } 13145 } 13146 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13147 } 13148 return true; 13149 } 13150 13151 /** 13152 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13153 * there is a thread associated with the activity. 13154 */ 13155 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13156 final ActivityRecord r, String[] args, boolean dumpAll) { 13157 String innerPrefix = prefix + " "; 13158 synchronized (this) { 13159 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13160 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13161 pw.print(" pid="); 13162 if (r.app != null) pw.println(r.app.pid); 13163 else pw.println("(not running)"); 13164 if (dumpAll) { 13165 r.dump(pw, innerPrefix); 13166 } 13167 } 13168 if (r.app != null && r.app.thread != null) { 13169 // flush anything that is already in the PrintWriter since the thread is going 13170 // to write to the file descriptor directly 13171 pw.flush(); 13172 try { 13173 TransferPipe tp = new TransferPipe(); 13174 try { 13175 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13176 r.appToken, innerPrefix, args); 13177 tp.go(fd); 13178 } finally { 13179 tp.kill(); 13180 } 13181 } catch (IOException e) { 13182 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13183 } catch (RemoteException e) { 13184 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13185 } 13186 } 13187 } 13188 13189 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13190 int opti, boolean dumpAll, String dumpPackage) { 13191 boolean needSep = false; 13192 boolean onlyHistory = false; 13193 boolean printedAnything = false; 13194 13195 if ("history".equals(dumpPackage)) { 13196 if (opti < args.length && "-s".equals(args[opti])) { 13197 dumpAll = false; 13198 } 13199 onlyHistory = true; 13200 dumpPackage = null; 13201 } 13202 13203 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13204 if (!onlyHistory && dumpAll) { 13205 if (mRegisteredReceivers.size() > 0) { 13206 boolean printed = false; 13207 Iterator it = mRegisteredReceivers.values().iterator(); 13208 while (it.hasNext()) { 13209 ReceiverList r = (ReceiverList)it.next(); 13210 if (dumpPackage != null && (r.app == null || 13211 !dumpPackage.equals(r.app.info.packageName))) { 13212 continue; 13213 } 13214 if (!printed) { 13215 pw.println(" Registered Receivers:"); 13216 needSep = true; 13217 printed = true; 13218 printedAnything = true; 13219 } 13220 pw.print(" * "); pw.println(r); 13221 r.dump(pw, " "); 13222 } 13223 } 13224 13225 if (mReceiverResolver.dump(pw, needSep ? 13226 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13227 " ", dumpPackage, false)) { 13228 needSep = true; 13229 printedAnything = true; 13230 } 13231 } 13232 13233 for (BroadcastQueue q : mBroadcastQueues) { 13234 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13235 printedAnything |= needSep; 13236 } 13237 13238 needSep = true; 13239 13240 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13241 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13242 if (needSep) { 13243 pw.println(); 13244 } 13245 needSep = true; 13246 printedAnything = true; 13247 pw.print(" Sticky broadcasts for user "); 13248 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13249 StringBuilder sb = new StringBuilder(128); 13250 for (Map.Entry<String, ArrayList<Intent>> ent 13251 : mStickyBroadcasts.valueAt(user).entrySet()) { 13252 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13253 if (dumpAll) { 13254 pw.println(":"); 13255 ArrayList<Intent> intents = ent.getValue(); 13256 final int N = intents.size(); 13257 for (int i=0; i<N; i++) { 13258 sb.setLength(0); 13259 sb.append(" Intent: "); 13260 intents.get(i).toShortString(sb, false, true, false, false); 13261 pw.println(sb.toString()); 13262 Bundle bundle = intents.get(i).getExtras(); 13263 if (bundle != null) { 13264 pw.print(" "); 13265 pw.println(bundle.toString()); 13266 } 13267 } 13268 } else { 13269 pw.println(""); 13270 } 13271 } 13272 } 13273 } 13274 13275 if (!onlyHistory && dumpAll) { 13276 pw.println(); 13277 for (BroadcastQueue queue : mBroadcastQueues) { 13278 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13279 + queue.mBroadcastsScheduled); 13280 } 13281 pw.println(" mHandler:"); 13282 mHandler.dump(new PrintWriterPrinter(pw), " "); 13283 needSep = true; 13284 printedAnything = true; 13285 } 13286 13287 if (!printedAnything) { 13288 pw.println(" (nothing)"); 13289 } 13290 } 13291 13292 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13293 int opti, boolean dumpAll, String dumpPackage) { 13294 boolean needSep; 13295 boolean printedAnything = false; 13296 13297 ItemMatcher matcher = new ItemMatcher(); 13298 matcher.build(args, opti); 13299 13300 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13301 13302 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13303 printedAnything |= needSep; 13304 13305 if (mLaunchingProviders.size() > 0) { 13306 boolean printed = false; 13307 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13308 ContentProviderRecord r = mLaunchingProviders.get(i); 13309 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13310 continue; 13311 } 13312 if (!printed) { 13313 if (needSep) pw.println(); 13314 needSep = true; 13315 pw.println(" Launching content providers:"); 13316 printed = true; 13317 printedAnything = true; 13318 } 13319 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13320 pw.println(r); 13321 } 13322 } 13323 13324 if (mGrantedUriPermissions.size() > 0) { 13325 boolean printed = false; 13326 int dumpUid = -2; 13327 if (dumpPackage != null) { 13328 try { 13329 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13330 } catch (NameNotFoundException e) { 13331 dumpUid = -1; 13332 } 13333 } 13334 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13335 int uid = mGrantedUriPermissions.keyAt(i); 13336 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13337 continue; 13338 } 13339 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13340 if (!printed) { 13341 if (needSep) pw.println(); 13342 needSep = true; 13343 pw.println(" Granted Uri Permissions:"); 13344 printed = true; 13345 printedAnything = true; 13346 } 13347 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13348 for (UriPermission perm : perms.values()) { 13349 pw.print(" "); pw.println(perm); 13350 if (dumpAll) { 13351 perm.dump(pw, " "); 13352 } 13353 } 13354 } 13355 } 13356 13357 if (!printedAnything) { 13358 pw.println(" (nothing)"); 13359 } 13360 } 13361 13362 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13363 int opti, boolean dumpAll, String dumpPackage) { 13364 boolean printed = false; 13365 13366 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13367 13368 if (mIntentSenderRecords.size() > 0) { 13369 Iterator<WeakReference<PendingIntentRecord>> it 13370 = mIntentSenderRecords.values().iterator(); 13371 while (it.hasNext()) { 13372 WeakReference<PendingIntentRecord> ref = it.next(); 13373 PendingIntentRecord rec = ref != null ? ref.get(): null; 13374 if (dumpPackage != null && (rec == null 13375 || !dumpPackage.equals(rec.key.packageName))) { 13376 continue; 13377 } 13378 printed = true; 13379 if (rec != null) { 13380 pw.print(" * "); pw.println(rec); 13381 if (dumpAll) { 13382 rec.dump(pw, " "); 13383 } 13384 } else { 13385 pw.print(" * "); pw.println(ref); 13386 } 13387 } 13388 } 13389 13390 if (!printed) { 13391 pw.println(" (nothing)"); 13392 } 13393 } 13394 13395 private static final int dumpProcessList(PrintWriter pw, 13396 ActivityManagerService service, List list, 13397 String prefix, String normalLabel, String persistentLabel, 13398 String dumpPackage) { 13399 int numPers = 0; 13400 final int N = list.size()-1; 13401 for (int i=N; i>=0; i--) { 13402 ProcessRecord r = (ProcessRecord)list.get(i); 13403 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13404 continue; 13405 } 13406 pw.println(String.format("%s%s #%2d: %s", 13407 prefix, (r.persistent ? persistentLabel : normalLabel), 13408 i, r.toString())); 13409 if (r.persistent) { 13410 numPers++; 13411 } 13412 } 13413 return numPers; 13414 } 13415 13416 private static final boolean dumpProcessOomList(PrintWriter pw, 13417 ActivityManagerService service, List<ProcessRecord> origList, 13418 String prefix, String normalLabel, String persistentLabel, 13419 boolean inclDetails, String dumpPackage) { 13420 13421 ArrayList<Pair<ProcessRecord, Integer>> list 13422 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13423 for (int i=0; i<origList.size(); i++) { 13424 ProcessRecord r = origList.get(i); 13425 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13426 continue; 13427 } 13428 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13429 } 13430 13431 if (list.size() <= 0) { 13432 return false; 13433 } 13434 13435 Comparator<Pair<ProcessRecord, Integer>> comparator 13436 = new Comparator<Pair<ProcessRecord, Integer>>() { 13437 @Override 13438 public int compare(Pair<ProcessRecord, Integer> object1, 13439 Pair<ProcessRecord, Integer> object2) { 13440 if (object1.first.setAdj != object2.first.setAdj) { 13441 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13442 } 13443 if (object1.second.intValue() != object2.second.intValue()) { 13444 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13445 } 13446 return 0; 13447 } 13448 }; 13449 13450 Collections.sort(list, comparator); 13451 13452 final long curRealtime = SystemClock.elapsedRealtime(); 13453 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13454 final long curUptime = SystemClock.uptimeMillis(); 13455 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13456 13457 for (int i=list.size()-1; i>=0; i--) { 13458 ProcessRecord r = list.get(i).first; 13459 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13460 char schedGroup; 13461 switch (r.setSchedGroup) { 13462 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13463 schedGroup = 'B'; 13464 break; 13465 case Process.THREAD_GROUP_DEFAULT: 13466 schedGroup = 'F'; 13467 break; 13468 default: 13469 schedGroup = '?'; 13470 break; 13471 } 13472 char foreground; 13473 if (r.foregroundActivities) { 13474 foreground = 'A'; 13475 } else if (r.foregroundServices) { 13476 foreground = 'S'; 13477 } else { 13478 foreground = ' '; 13479 } 13480 String procState = ProcessList.makeProcStateString(r.curProcState); 13481 pw.print(prefix); 13482 pw.print(r.persistent ? persistentLabel : normalLabel); 13483 pw.print(" #"); 13484 int num = (origList.size()-1)-list.get(i).second; 13485 if (num < 10) pw.print(' '); 13486 pw.print(num); 13487 pw.print(": "); 13488 pw.print(oomAdj); 13489 pw.print(' '); 13490 pw.print(schedGroup); 13491 pw.print('/'); 13492 pw.print(foreground); 13493 pw.print('/'); 13494 pw.print(procState); 13495 pw.print(" trm:"); 13496 if (r.trimMemoryLevel < 10) pw.print(' '); 13497 pw.print(r.trimMemoryLevel); 13498 pw.print(' '); 13499 pw.print(r.toShortString()); 13500 pw.print(" ("); 13501 pw.print(r.adjType); 13502 pw.println(')'); 13503 if (r.adjSource != null || r.adjTarget != null) { 13504 pw.print(prefix); 13505 pw.print(" "); 13506 if (r.adjTarget instanceof ComponentName) { 13507 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13508 } else if (r.adjTarget != null) { 13509 pw.print(r.adjTarget.toString()); 13510 } else { 13511 pw.print("{null}"); 13512 } 13513 pw.print("<="); 13514 if (r.adjSource instanceof ProcessRecord) { 13515 pw.print("Proc{"); 13516 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13517 pw.println("}"); 13518 } else if (r.adjSource != null) { 13519 pw.println(r.adjSource.toString()); 13520 } else { 13521 pw.println("{null}"); 13522 } 13523 } 13524 if (inclDetails) { 13525 pw.print(prefix); 13526 pw.print(" "); 13527 pw.print("oom: max="); pw.print(r.maxAdj); 13528 pw.print(" curRaw="); pw.print(r.curRawAdj); 13529 pw.print(" setRaw="); pw.print(r.setRawAdj); 13530 pw.print(" cur="); pw.print(r.curAdj); 13531 pw.print(" set="); pw.println(r.setAdj); 13532 pw.print(prefix); 13533 pw.print(" "); 13534 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13535 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13536 pw.print(" lastPss="); pw.print(r.lastPss); 13537 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13538 pw.print(prefix); 13539 pw.print(" "); 13540 pw.print("cached="); pw.print(r.cached); 13541 pw.print(" empty="); pw.print(r.empty); 13542 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13543 13544 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13545 if (r.lastWakeTime != 0) { 13546 long wtime; 13547 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13548 synchronized (stats) { 13549 wtime = stats.getProcessWakeTime(r.info.uid, 13550 r.pid, curRealtime); 13551 } 13552 long timeUsed = wtime - r.lastWakeTime; 13553 pw.print(prefix); 13554 pw.print(" "); 13555 pw.print("keep awake over "); 13556 TimeUtils.formatDuration(realtimeSince, pw); 13557 pw.print(" used "); 13558 TimeUtils.formatDuration(timeUsed, pw); 13559 pw.print(" ("); 13560 pw.print((timeUsed*100)/realtimeSince); 13561 pw.println("%)"); 13562 } 13563 if (r.lastCpuTime != 0) { 13564 long timeUsed = r.curCpuTime - r.lastCpuTime; 13565 pw.print(prefix); 13566 pw.print(" "); 13567 pw.print("run cpu over "); 13568 TimeUtils.formatDuration(uptimeSince, pw); 13569 pw.print(" used "); 13570 TimeUtils.formatDuration(timeUsed, pw); 13571 pw.print(" ("); 13572 pw.print((timeUsed*100)/uptimeSince); 13573 pw.println("%)"); 13574 } 13575 } 13576 } 13577 } 13578 return true; 13579 } 13580 13581 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13582 String[] args) { 13583 ArrayList<ProcessRecord> procs; 13584 synchronized (this) { 13585 if (args != null && args.length > start 13586 && args[start].charAt(0) != '-') { 13587 procs = new ArrayList<ProcessRecord>(); 13588 int pid = -1; 13589 try { 13590 pid = Integer.parseInt(args[start]); 13591 } catch (NumberFormatException e) { 13592 } 13593 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13594 ProcessRecord proc = mLruProcesses.get(i); 13595 if (proc.pid == pid) { 13596 procs.add(proc); 13597 } else if (allPkgs && proc.pkgList != null 13598 && proc.pkgList.containsKey(args[start])) { 13599 procs.add(proc); 13600 } else if (proc.processName.equals(args[start])) { 13601 procs.add(proc); 13602 } 13603 } 13604 if (procs.size() <= 0) { 13605 return null; 13606 } 13607 } else { 13608 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13609 } 13610 } 13611 return procs; 13612 } 13613 13614 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13615 PrintWriter pw, String[] args) { 13616 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13617 if (procs == null) { 13618 pw.println("No process found for: " + args[0]); 13619 return; 13620 } 13621 13622 long uptime = SystemClock.uptimeMillis(); 13623 long realtime = SystemClock.elapsedRealtime(); 13624 pw.println("Applications Graphics Acceleration Info:"); 13625 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13626 13627 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13628 ProcessRecord r = procs.get(i); 13629 if (r.thread != null) { 13630 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13631 pw.flush(); 13632 try { 13633 TransferPipe tp = new TransferPipe(); 13634 try { 13635 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13636 tp.go(fd); 13637 } finally { 13638 tp.kill(); 13639 } 13640 } catch (IOException e) { 13641 pw.println("Failure while dumping the app: " + r); 13642 pw.flush(); 13643 } catch (RemoteException e) { 13644 pw.println("Got a RemoteException while dumping the app " + r); 13645 pw.flush(); 13646 } 13647 } 13648 } 13649 } 13650 13651 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13652 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13653 if (procs == null) { 13654 pw.println("No process found for: " + args[0]); 13655 return; 13656 } 13657 13658 pw.println("Applications Database Info:"); 13659 13660 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13661 ProcessRecord r = procs.get(i); 13662 if (r.thread != null) { 13663 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13664 pw.flush(); 13665 try { 13666 TransferPipe tp = new TransferPipe(); 13667 try { 13668 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13669 tp.go(fd); 13670 } finally { 13671 tp.kill(); 13672 } 13673 } catch (IOException e) { 13674 pw.println("Failure while dumping the app: " + r); 13675 pw.flush(); 13676 } catch (RemoteException e) { 13677 pw.println("Got a RemoteException while dumping the app " + r); 13678 pw.flush(); 13679 } 13680 } 13681 } 13682 } 13683 13684 final static class MemItem { 13685 final boolean isProc; 13686 final String label; 13687 final String shortLabel; 13688 final long pss; 13689 final int id; 13690 final boolean hasActivities; 13691 ArrayList<MemItem> subitems; 13692 13693 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13694 boolean _hasActivities) { 13695 isProc = true; 13696 label = _label; 13697 shortLabel = _shortLabel; 13698 pss = _pss; 13699 id = _id; 13700 hasActivities = _hasActivities; 13701 } 13702 13703 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13704 isProc = false; 13705 label = _label; 13706 shortLabel = _shortLabel; 13707 pss = _pss; 13708 id = _id; 13709 hasActivities = false; 13710 } 13711 } 13712 13713 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13714 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13715 if (sort && !isCompact) { 13716 Collections.sort(items, new Comparator<MemItem>() { 13717 @Override 13718 public int compare(MemItem lhs, MemItem rhs) { 13719 if (lhs.pss < rhs.pss) { 13720 return 1; 13721 } else if (lhs.pss > rhs.pss) { 13722 return -1; 13723 } 13724 return 0; 13725 } 13726 }); 13727 } 13728 13729 for (int i=0; i<items.size(); i++) { 13730 MemItem mi = items.get(i); 13731 if (!isCompact) { 13732 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13733 } else if (mi.isProc) { 13734 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13735 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13736 pw.println(mi.hasActivities ? ",a" : ",e"); 13737 } else { 13738 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13739 pw.println(mi.pss); 13740 } 13741 if (mi.subitems != null) { 13742 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13743 true, isCompact); 13744 } 13745 } 13746 } 13747 13748 // These are in KB. 13749 static final long[] DUMP_MEM_BUCKETS = new long[] { 13750 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13751 120*1024, 160*1024, 200*1024, 13752 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13753 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13754 }; 13755 13756 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13757 boolean stackLike) { 13758 int start = label.lastIndexOf('.'); 13759 if (start >= 0) start++; 13760 else start = 0; 13761 int end = label.length(); 13762 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13763 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13764 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13765 out.append(bucket); 13766 out.append(stackLike ? "MB." : "MB "); 13767 out.append(label, start, end); 13768 return; 13769 } 13770 } 13771 out.append(memKB/1024); 13772 out.append(stackLike ? "MB." : "MB "); 13773 out.append(label, start, end); 13774 } 13775 13776 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13777 ProcessList.NATIVE_ADJ, 13778 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13779 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13780 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13781 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13782 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13783 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13784 }; 13785 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13786 "Native", 13787 "System", "Persistent", "Persistent Service", "Foreground", 13788 "Visible", "Perceptible", 13789 "Heavy Weight", "Backup", 13790 "A Services", "Home", 13791 "Previous", "B Services", "Cached" 13792 }; 13793 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13794 "native", 13795 "sys", "pers", "persvc", "fore", 13796 "vis", "percept", 13797 "heavy", "backup", 13798 "servicea", "home", 13799 "prev", "serviceb", "cached" 13800 }; 13801 13802 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13803 long realtime, boolean isCheckinRequest, boolean isCompact) { 13804 if (isCheckinRequest || isCompact) { 13805 // short checkin version 13806 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13807 } else { 13808 pw.println("Applications Memory Usage (kB):"); 13809 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13810 } 13811 } 13812 13813 private static final int KSM_SHARED = 0; 13814 private static final int KSM_SHARING = 1; 13815 private static final int KSM_UNSHARED = 2; 13816 private static final int KSM_VOLATILE = 3; 13817 13818 private final long[] getKsmInfo() { 13819 long[] longOut = new long[4]; 13820 final int[] SINGLE_LONG_FORMAT = new int[] { 13821 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13822 }; 13823 long[] longTmp = new long[1]; 13824 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13825 SINGLE_LONG_FORMAT, null, longTmp, null); 13826 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13827 longTmp[0] = 0; 13828 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13829 SINGLE_LONG_FORMAT, null, longTmp, null); 13830 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13831 longTmp[0] = 0; 13832 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13833 SINGLE_LONG_FORMAT, null, longTmp, null); 13834 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13835 longTmp[0] = 0; 13836 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13837 SINGLE_LONG_FORMAT, null, longTmp, null); 13838 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13839 return longOut; 13840 } 13841 13842 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13843 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13844 boolean dumpDetails = false; 13845 boolean dumpFullDetails = false; 13846 boolean dumpDalvik = false; 13847 boolean oomOnly = false; 13848 boolean isCompact = false; 13849 boolean localOnly = false; 13850 boolean packages = false; 13851 13852 int opti = 0; 13853 while (opti < args.length) { 13854 String opt = args[opti]; 13855 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13856 break; 13857 } 13858 opti++; 13859 if ("-a".equals(opt)) { 13860 dumpDetails = true; 13861 dumpFullDetails = true; 13862 dumpDalvik = true; 13863 } else if ("-d".equals(opt)) { 13864 dumpDalvik = true; 13865 } else if ("-c".equals(opt)) { 13866 isCompact = true; 13867 } else if ("--oom".equals(opt)) { 13868 oomOnly = true; 13869 } else if ("--local".equals(opt)) { 13870 localOnly = true; 13871 } else if ("--package".equals(opt)) { 13872 packages = true; 13873 } else if ("-h".equals(opt)) { 13874 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13875 pw.println(" -a: include all available information for each process."); 13876 pw.println(" -d: include dalvik details when dumping process details."); 13877 pw.println(" -c: dump in a compact machine-parseable representation."); 13878 pw.println(" --oom: only show processes organized by oom adj."); 13879 pw.println(" --local: only collect details locally, don't call process."); 13880 pw.println(" --package: interpret process arg as package, dumping all"); 13881 pw.println(" processes that have loaded that package."); 13882 pw.println("If [process] is specified it can be the name or "); 13883 pw.println("pid of a specific process to dump."); 13884 return; 13885 } else { 13886 pw.println("Unknown argument: " + opt + "; use -h for help"); 13887 } 13888 } 13889 13890 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13891 long uptime = SystemClock.uptimeMillis(); 13892 long realtime = SystemClock.elapsedRealtime(); 13893 final long[] tmpLong = new long[1]; 13894 13895 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13896 if (procs == null) { 13897 // No Java processes. Maybe they want to print a native process. 13898 if (args != null && args.length > opti 13899 && args[opti].charAt(0) != '-') { 13900 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13901 = new ArrayList<ProcessCpuTracker.Stats>(); 13902 updateCpuStatsNow(); 13903 int findPid = -1; 13904 try { 13905 findPid = Integer.parseInt(args[opti]); 13906 } catch (NumberFormatException e) { 13907 } 13908 synchronized (mProcessCpuTracker) { 13909 final int N = mProcessCpuTracker.countStats(); 13910 for (int i=0; i<N; i++) { 13911 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13912 if (st.pid == findPid || (st.baseName != null 13913 && st.baseName.equals(args[opti]))) { 13914 nativeProcs.add(st); 13915 } 13916 } 13917 } 13918 if (nativeProcs.size() > 0) { 13919 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13920 isCompact); 13921 Debug.MemoryInfo mi = null; 13922 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13923 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13924 final int pid = r.pid; 13925 if (!isCheckinRequest && dumpDetails) { 13926 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13927 } 13928 if (mi == null) { 13929 mi = new Debug.MemoryInfo(); 13930 } 13931 if (dumpDetails || (!brief && !oomOnly)) { 13932 Debug.getMemoryInfo(pid, mi); 13933 } else { 13934 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13935 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13936 } 13937 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13938 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13939 if (isCheckinRequest) { 13940 pw.println(); 13941 } 13942 } 13943 return; 13944 } 13945 } 13946 pw.println("No process found for: " + args[opti]); 13947 return; 13948 } 13949 13950 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13951 dumpDetails = true; 13952 } 13953 13954 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13955 13956 String[] innerArgs = new String[args.length-opti]; 13957 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13958 13959 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13960 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13961 long nativePss = 0; 13962 long dalvikPss = 0; 13963 long otherPss = 0; 13964 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13965 13966 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13967 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13968 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13969 13970 long totalPss = 0; 13971 long cachedPss = 0; 13972 13973 Debug.MemoryInfo mi = null; 13974 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13975 final ProcessRecord r = procs.get(i); 13976 final IApplicationThread thread; 13977 final int pid; 13978 final int oomAdj; 13979 final boolean hasActivities; 13980 synchronized (this) { 13981 thread = r.thread; 13982 pid = r.pid; 13983 oomAdj = r.getSetAdjWithServices(); 13984 hasActivities = r.activities.size() > 0; 13985 } 13986 if (thread != null) { 13987 if (!isCheckinRequest && dumpDetails) { 13988 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13989 } 13990 if (mi == null) { 13991 mi = new Debug.MemoryInfo(); 13992 } 13993 if (dumpDetails || (!brief && !oomOnly)) { 13994 Debug.getMemoryInfo(pid, mi); 13995 } else { 13996 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13997 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13998 } 13999 if (dumpDetails) { 14000 if (localOnly) { 14001 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14002 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14003 if (isCheckinRequest) { 14004 pw.println(); 14005 } 14006 } else { 14007 try { 14008 pw.flush(); 14009 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14010 dumpDalvik, innerArgs); 14011 } catch (RemoteException e) { 14012 if (!isCheckinRequest) { 14013 pw.println("Got RemoteException!"); 14014 pw.flush(); 14015 } 14016 } 14017 } 14018 } 14019 14020 final long myTotalPss = mi.getTotalPss(); 14021 final long myTotalUss = mi.getTotalUss(); 14022 14023 synchronized (this) { 14024 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14025 // Record this for posterity if the process has been stable. 14026 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14027 } 14028 } 14029 14030 if (!isCheckinRequest && mi != null) { 14031 totalPss += myTotalPss; 14032 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14033 (hasActivities ? " / activities)" : ")"), 14034 r.processName, myTotalPss, pid, hasActivities); 14035 procMems.add(pssItem); 14036 procMemsMap.put(pid, pssItem); 14037 14038 nativePss += mi.nativePss; 14039 dalvikPss += mi.dalvikPss; 14040 otherPss += mi.otherPss; 14041 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14042 long mem = mi.getOtherPss(j); 14043 miscPss[j] += mem; 14044 otherPss -= mem; 14045 } 14046 14047 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14048 cachedPss += myTotalPss; 14049 } 14050 14051 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14052 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14053 || oomIndex == (oomPss.length-1)) { 14054 oomPss[oomIndex] += myTotalPss; 14055 if (oomProcs[oomIndex] == null) { 14056 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14057 } 14058 oomProcs[oomIndex].add(pssItem); 14059 break; 14060 } 14061 } 14062 } 14063 } 14064 } 14065 14066 long nativeProcTotalPss = 0; 14067 14068 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14069 // If we are showing aggregations, also look for native processes to 14070 // include so that our aggregations are more accurate. 14071 updateCpuStatsNow(); 14072 synchronized (mProcessCpuTracker) { 14073 final int N = mProcessCpuTracker.countStats(); 14074 for (int i=0; i<N; i++) { 14075 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14076 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14077 if (mi == null) { 14078 mi = new Debug.MemoryInfo(); 14079 } 14080 if (!brief && !oomOnly) { 14081 Debug.getMemoryInfo(st.pid, mi); 14082 } else { 14083 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14084 mi.nativePrivateDirty = (int)tmpLong[0]; 14085 } 14086 14087 final long myTotalPss = mi.getTotalPss(); 14088 totalPss += myTotalPss; 14089 nativeProcTotalPss += myTotalPss; 14090 14091 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14092 st.name, myTotalPss, st.pid, false); 14093 procMems.add(pssItem); 14094 14095 nativePss += mi.nativePss; 14096 dalvikPss += mi.dalvikPss; 14097 otherPss += mi.otherPss; 14098 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14099 long mem = mi.getOtherPss(j); 14100 miscPss[j] += mem; 14101 otherPss -= mem; 14102 } 14103 oomPss[0] += myTotalPss; 14104 if (oomProcs[0] == null) { 14105 oomProcs[0] = new ArrayList<MemItem>(); 14106 } 14107 oomProcs[0].add(pssItem); 14108 } 14109 } 14110 } 14111 14112 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14113 14114 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14115 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14116 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14117 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14118 String label = Debug.MemoryInfo.getOtherLabel(j); 14119 catMems.add(new MemItem(label, label, miscPss[j], j)); 14120 } 14121 14122 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14123 for (int j=0; j<oomPss.length; j++) { 14124 if (oomPss[j] != 0) { 14125 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14126 : DUMP_MEM_OOM_LABEL[j]; 14127 MemItem item = new MemItem(label, label, oomPss[j], 14128 DUMP_MEM_OOM_ADJ[j]); 14129 item.subitems = oomProcs[j]; 14130 oomMems.add(item); 14131 } 14132 } 14133 14134 if (!brief && !oomOnly && !isCompact) { 14135 pw.println(); 14136 pw.println("Total PSS by process:"); 14137 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14138 pw.println(); 14139 } 14140 if (!isCompact) { 14141 pw.println("Total PSS by OOM adjustment:"); 14142 } 14143 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14144 if (!brief && !oomOnly) { 14145 PrintWriter out = categoryPw != null ? categoryPw : pw; 14146 if (!isCompact) { 14147 out.println(); 14148 out.println("Total PSS by category:"); 14149 } 14150 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14151 } 14152 if (!isCompact) { 14153 pw.println(); 14154 } 14155 MemInfoReader memInfo = new MemInfoReader(); 14156 memInfo.readMemInfo(); 14157 if (nativeProcTotalPss > 0) { 14158 synchronized (this) { 14159 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14160 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14161 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14162 } 14163 } 14164 if (!brief) { 14165 if (!isCompact) { 14166 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14167 pw.print(" kB (status "); 14168 switch (mLastMemoryLevel) { 14169 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14170 pw.println("normal)"); 14171 break; 14172 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14173 pw.println("moderate)"); 14174 break; 14175 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14176 pw.println("low)"); 14177 break; 14178 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14179 pw.println("critical)"); 14180 break; 14181 default: 14182 pw.print(mLastMemoryLevel); 14183 pw.println(")"); 14184 break; 14185 } 14186 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14187 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14188 pw.print(cachedPss); pw.print(" cached pss + "); 14189 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14190 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14191 } else { 14192 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14193 pw.print(cachedPss + memInfo.getCachedSizeKb() 14194 + memInfo.getFreeSizeKb()); pw.print(","); 14195 pw.println(totalPss - cachedPss); 14196 } 14197 } 14198 if (!isCompact) { 14199 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14200 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14201 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14202 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14203 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14204 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14205 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14206 } 14207 if (!brief) { 14208 if (memInfo.getZramTotalSizeKb() != 0) { 14209 if (!isCompact) { 14210 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14211 pw.print(" kB physical used for "); 14212 pw.print(memInfo.getSwapTotalSizeKb() 14213 - memInfo.getSwapFreeSizeKb()); 14214 pw.print(" kB in swap ("); 14215 pw.print(memInfo.getSwapTotalSizeKb()); 14216 pw.println(" kB total swap)"); 14217 } else { 14218 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14219 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14220 pw.println(memInfo.getSwapFreeSizeKb()); 14221 } 14222 } 14223 final long[] ksm = getKsmInfo(); 14224 if (!isCompact) { 14225 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14226 || ksm[KSM_VOLATILE] != 0) { 14227 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14228 pw.print(" kB saved from shared "); 14229 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14230 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14231 pw.print(" kB unshared; "); 14232 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14233 } 14234 pw.print(" Tuning: "); 14235 pw.print(ActivityManager.staticGetMemoryClass()); 14236 pw.print(" (large "); 14237 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14238 pw.print("), oom "); 14239 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14240 pw.print(" kB"); 14241 pw.print(", restore limit "); 14242 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14243 pw.print(" kB"); 14244 if (ActivityManager.isLowRamDeviceStatic()) { 14245 pw.print(" (low-ram)"); 14246 } 14247 if (ActivityManager.isHighEndGfx()) { 14248 pw.print(" (high-end-gfx)"); 14249 } 14250 pw.println(); 14251 } else { 14252 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14253 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14254 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14255 pw.print("tuning,"); 14256 pw.print(ActivityManager.staticGetMemoryClass()); 14257 pw.print(','); 14258 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14259 pw.print(','); 14260 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14261 if (ActivityManager.isLowRamDeviceStatic()) { 14262 pw.print(",low-ram"); 14263 } 14264 if (ActivityManager.isHighEndGfx()) { 14265 pw.print(",high-end-gfx"); 14266 } 14267 pw.println(); 14268 } 14269 } 14270 } 14271 } 14272 14273 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14274 String name) { 14275 sb.append(" "); 14276 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14277 sb.append(' '); 14278 sb.append(ProcessList.makeProcStateString(procState)); 14279 sb.append(' '); 14280 ProcessList.appendRamKb(sb, pss); 14281 sb.append(" kB: "); 14282 sb.append(name); 14283 } 14284 14285 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14286 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14287 sb.append(" ("); 14288 sb.append(mi.pid); 14289 sb.append(") "); 14290 sb.append(mi.adjType); 14291 sb.append('\n'); 14292 if (mi.adjReason != null) { 14293 sb.append(" "); 14294 sb.append(mi.adjReason); 14295 sb.append('\n'); 14296 } 14297 } 14298 14299 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14300 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14301 for (int i=0, N=memInfos.size(); i<N; i++) { 14302 ProcessMemInfo mi = memInfos.get(i); 14303 infoMap.put(mi.pid, mi); 14304 } 14305 updateCpuStatsNow(); 14306 synchronized (mProcessCpuTracker) { 14307 final int N = mProcessCpuTracker.countStats(); 14308 for (int i=0; i<N; i++) { 14309 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14310 if (st.vsize > 0) { 14311 long pss = Debug.getPss(st.pid, null); 14312 if (pss > 0) { 14313 if (infoMap.indexOfKey(st.pid) < 0) { 14314 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14315 ProcessList.NATIVE_ADJ, -1, "native", null); 14316 mi.pss = pss; 14317 memInfos.add(mi); 14318 } 14319 } 14320 } 14321 } 14322 } 14323 14324 long totalPss = 0; 14325 for (int i=0, N=memInfos.size(); i<N; i++) { 14326 ProcessMemInfo mi = memInfos.get(i); 14327 if (mi.pss == 0) { 14328 mi.pss = Debug.getPss(mi.pid, null); 14329 } 14330 totalPss += mi.pss; 14331 } 14332 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14333 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14334 if (lhs.oomAdj != rhs.oomAdj) { 14335 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14336 } 14337 if (lhs.pss != rhs.pss) { 14338 return lhs.pss < rhs.pss ? 1 : -1; 14339 } 14340 return 0; 14341 } 14342 }); 14343 14344 StringBuilder tag = new StringBuilder(128); 14345 StringBuilder stack = new StringBuilder(128); 14346 tag.append("Low on memory -- "); 14347 appendMemBucket(tag, totalPss, "total", false); 14348 appendMemBucket(stack, totalPss, "total", true); 14349 14350 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14351 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14352 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14353 14354 boolean firstLine = true; 14355 int lastOomAdj = Integer.MIN_VALUE; 14356 long extraNativeRam = 0; 14357 long cachedPss = 0; 14358 for (int i=0, N=memInfos.size(); i<N; i++) { 14359 ProcessMemInfo mi = memInfos.get(i); 14360 14361 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14362 cachedPss += mi.pss; 14363 } 14364 14365 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14366 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14367 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14368 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14369 if (lastOomAdj != mi.oomAdj) { 14370 lastOomAdj = mi.oomAdj; 14371 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14372 tag.append(" / "); 14373 } 14374 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14375 if (firstLine) { 14376 stack.append(":"); 14377 firstLine = false; 14378 } 14379 stack.append("\n\t at "); 14380 } else { 14381 stack.append("$"); 14382 } 14383 } else { 14384 tag.append(" "); 14385 stack.append("$"); 14386 } 14387 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14388 appendMemBucket(tag, mi.pss, mi.name, false); 14389 } 14390 appendMemBucket(stack, mi.pss, mi.name, true); 14391 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14392 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14393 stack.append("("); 14394 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14395 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14396 stack.append(DUMP_MEM_OOM_LABEL[k]); 14397 stack.append(":"); 14398 stack.append(DUMP_MEM_OOM_ADJ[k]); 14399 } 14400 } 14401 stack.append(")"); 14402 } 14403 } 14404 14405 appendMemInfo(fullNativeBuilder, mi); 14406 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14407 // The short form only has native processes that are >= 1MB. 14408 if (mi.pss >= 1000) { 14409 appendMemInfo(shortNativeBuilder, mi); 14410 } else { 14411 extraNativeRam += mi.pss; 14412 } 14413 } else { 14414 // Short form has all other details, but if we have collected RAM 14415 // from smaller native processes let's dump a summary of that. 14416 if (extraNativeRam > 0) { 14417 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14418 -1, extraNativeRam, "(Other native)"); 14419 shortNativeBuilder.append('\n'); 14420 extraNativeRam = 0; 14421 } 14422 appendMemInfo(fullJavaBuilder, mi); 14423 } 14424 } 14425 14426 fullJavaBuilder.append(" "); 14427 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14428 fullJavaBuilder.append(" kB: TOTAL\n"); 14429 14430 MemInfoReader memInfo = new MemInfoReader(); 14431 memInfo.readMemInfo(); 14432 final long[] infos = memInfo.getRawInfo(); 14433 14434 StringBuilder memInfoBuilder = new StringBuilder(1024); 14435 Debug.getMemInfo(infos); 14436 memInfoBuilder.append(" MemInfo: "); 14437 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14438 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14439 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14440 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14441 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14442 memInfoBuilder.append(" "); 14443 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14444 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14445 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14446 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14447 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14448 memInfoBuilder.append(" ZRAM: "); 14449 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14450 memInfoBuilder.append(" kB RAM, "); 14451 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14452 memInfoBuilder.append(" kB swap total, "); 14453 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14454 memInfoBuilder.append(" kB swap free\n"); 14455 } 14456 final long[] ksm = getKsmInfo(); 14457 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14458 || ksm[KSM_VOLATILE] != 0) { 14459 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14460 memInfoBuilder.append(" kB saved from shared "); 14461 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14462 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14463 memInfoBuilder.append(" kB unshared; "); 14464 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14465 } 14466 memInfoBuilder.append(" Free RAM: "); 14467 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14468 + memInfo.getFreeSizeKb()); 14469 memInfoBuilder.append(" kB\n"); 14470 memInfoBuilder.append(" Used RAM: "); 14471 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14472 memInfoBuilder.append(" kB\n"); 14473 memInfoBuilder.append(" Lost RAM: "); 14474 memInfoBuilder.append(memInfo.getTotalSizeKb() 14475 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14476 - memInfo.getKernelUsedSizeKb()); 14477 memInfoBuilder.append(" kB\n"); 14478 Slog.i(TAG, "Low on memory:"); 14479 Slog.i(TAG, shortNativeBuilder.toString()); 14480 Slog.i(TAG, fullJavaBuilder.toString()); 14481 Slog.i(TAG, memInfoBuilder.toString()); 14482 14483 StringBuilder dropBuilder = new StringBuilder(1024); 14484 /* 14485 StringWriter oomSw = new StringWriter(); 14486 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14487 StringWriter catSw = new StringWriter(); 14488 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14489 String[] emptyArgs = new String[] { }; 14490 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14491 oomPw.flush(); 14492 String oomString = oomSw.toString(); 14493 */ 14494 dropBuilder.append("Low on memory:"); 14495 dropBuilder.append(stack); 14496 dropBuilder.append('\n'); 14497 dropBuilder.append(fullNativeBuilder); 14498 dropBuilder.append(fullJavaBuilder); 14499 dropBuilder.append('\n'); 14500 dropBuilder.append(memInfoBuilder); 14501 dropBuilder.append('\n'); 14502 /* 14503 dropBuilder.append(oomString); 14504 dropBuilder.append('\n'); 14505 */ 14506 StringWriter catSw = new StringWriter(); 14507 synchronized (ActivityManagerService.this) { 14508 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14509 String[] emptyArgs = new String[] { }; 14510 catPw.println(); 14511 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14512 catPw.println(); 14513 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14514 false, false, null); 14515 catPw.println(); 14516 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14517 catPw.flush(); 14518 } 14519 dropBuilder.append(catSw.toString()); 14520 addErrorToDropBox("lowmem", null, "system_server", null, 14521 null, tag.toString(), dropBuilder.toString(), null, null); 14522 //Slog.i(TAG, "Sent to dropbox:"); 14523 //Slog.i(TAG, dropBuilder.toString()); 14524 synchronized (ActivityManagerService.this) { 14525 long now = SystemClock.uptimeMillis(); 14526 if (mLastMemUsageReportTime < now) { 14527 mLastMemUsageReportTime = now; 14528 } 14529 } 14530 } 14531 14532 /** 14533 * Searches array of arguments for the specified string 14534 * @param args array of argument strings 14535 * @param value value to search for 14536 * @return true if the value is contained in the array 14537 */ 14538 private static boolean scanArgs(String[] args, String value) { 14539 if (args != null) { 14540 for (String arg : args) { 14541 if (value.equals(arg)) { 14542 return true; 14543 } 14544 } 14545 } 14546 return false; 14547 } 14548 14549 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14550 ContentProviderRecord cpr, boolean always) { 14551 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14552 14553 if (!inLaunching || always) { 14554 synchronized (cpr) { 14555 cpr.launchingApp = null; 14556 cpr.notifyAll(); 14557 } 14558 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14559 String names[] = cpr.info.authority.split(";"); 14560 for (int j = 0; j < names.length; j++) { 14561 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14562 } 14563 } 14564 14565 for (int i=0; i<cpr.connections.size(); i++) { 14566 ContentProviderConnection conn = cpr.connections.get(i); 14567 if (conn.waiting) { 14568 // If this connection is waiting for the provider, then we don't 14569 // need to mess with its process unless we are always removing 14570 // or for some reason the provider is not currently launching. 14571 if (inLaunching && !always) { 14572 continue; 14573 } 14574 } 14575 ProcessRecord capp = conn.client; 14576 conn.dead = true; 14577 if (conn.stableCount > 0) { 14578 if (!capp.persistent && capp.thread != null 14579 && capp.pid != 0 14580 && capp.pid != MY_PID) { 14581 capp.kill("depends on provider " 14582 + cpr.name.flattenToShortString() 14583 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14584 } 14585 } else if (capp.thread != null && conn.provider.provider != null) { 14586 try { 14587 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14588 } catch (RemoteException e) { 14589 } 14590 // In the protocol here, we don't expect the client to correctly 14591 // clean up this connection, we'll just remove it. 14592 cpr.connections.remove(i); 14593 conn.client.conProviders.remove(conn); 14594 } 14595 } 14596 14597 if (inLaunching && always) { 14598 mLaunchingProviders.remove(cpr); 14599 } 14600 return inLaunching; 14601 } 14602 14603 /** 14604 * Main code for cleaning up a process when it has gone away. This is 14605 * called both as a result of the process dying, or directly when stopping 14606 * a process when running in single process mode. 14607 * 14608 * @return Returns true if the given process has been restarted, so the 14609 * app that was passed in must remain on the process lists. 14610 */ 14611 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14612 boolean restarting, boolean allowRestart, int index) { 14613 if (index >= 0) { 14614 removeLruProcessLocked(app); 14615 ProcessList.remove(app.pid); 14616 } 14617 14618 mProcessesToGc.remove(app); 14619 mPendingPssProcesses.remove(app); 14620 14621 // Dismiss any open dialogs. 14622 if (app.crashDialog != null && !app.forceCrashReport) { 14623 app.crashDialog.dismiss(); 14624 app.crashDialog = null; 14625 } 14626 if (app.anrDialog != null) { 14627 app.anrDialog.dismiss(); 14628 app.anrDialog = null; 14629 } 14630 if (app.waitDialog != null) { 14631 app.waitDialog.dismiss(); 14632 app.waitDialog = null; 14633 } 14634 14635 app.crashing = false; 14636 app.notResponding = false; 14637 14638 app.resetPackageList(mProcessStats); 14639 app.unlinkDeathRecipient(); 14640 app.makeInactive(mProcessStats); 14641 app.waitingToKill = null; 14642 app.forcingToForeground = null; 14643 updateProcessForegroundLocked(app, false, false); 14644 app.foregroundActivities = false; 14645 app.hasShownUi = false; 14646 app.treatLikeActivity = false; 14647 app.hasAboveClient = false; 14648 app.hasClientActivities = false; 14649 14650 mServices.killServicesLocked(app, allowRestart); 14651 14652 boolean restart = false; 14653 14654 // Remove published content providers. 14655 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14656 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14657 final boolean always = app.bad || !allowRestart; 14658 if (removeDyingProviderLocked(app, cpr, always) || always) { 14659 // We left the provider in the launching list, need to 14660 // restart it. 14661 restart = true; 14662 } 14663 14664 cpr.provider = null; 14665 cpr.proc = null; 14666 } 14667 app.pubProviders.clear(); 14668 14669 // Take care of any launching providers waiting for this process. 14670 if (checkAppInLaunchingProvidersLocked(app, false)) { 14671 restart = true; 14672 } 14673 14674 // Unregister from connected content providers. 14675 if (!app.conProviders.isEmpty()) { 14676 for (int i=0; i<app.conProviders.size(); i++) { 14677 ContentProviderConnection conn = app.conProviders.get(i); 14678 conn.provider.connections.remove(conn); 14679 } 14680 app.conProviders.clear(); 14681 } 14682 14683 // At this point there may be remaining entries in mLaunchingProviders 14684 // where we were the only one waiting, so they are no longer of use. 14685 // Look for these and clean up if found. 14686 // XXX Commented out for now. Trying to figure out a way to reproduce 14687 // the actual situation to identify what is actually going on. 14688 if (false) { 14689 for (int i=0; i<mLaunchingProviders.size(); i++) { 14690 ContentProviderRecord cpr = (ContentProviderRecord) 14691 mLaunchingProviders.get(i); 14692 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14693 synchronized (cpr) { 14694 cpr.launchingApp = null; 14695 cpr.notifyAll(); 14696 } 14697 } 14698 } 14699 } 14700 14701 skipCurrentReceiverLocked(app); 14702 14703 // Unregister any receivers. 14704 for (int i=app.receivers.size()-1; i>=0; i--) { 14705 removeReceiverLocked(app.receivers.valueAt(i)); 14706 } 14707 app.receivers.clear(); 14708 14709 // If the app is undergoing backup, tell the backup manager about it 14710 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14711 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14712 + mBackupTarget.appInfo + " died during backup"); 14713 try { 14714 IBackupManager bm = IBackupManager.Stub.asInterface( 14715 ServiceManager.getService(Context.BACKUP_SERVICE)); 14716 bm.agentDisconnected(app.info.packageName); 14717 } catch (RemoteException e) { 14718 // can't happen; backup manager is local 14719 } 14720 } 14721 14722 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14723 ProcessChangeItem item = mPendingProcessChanges.get(i); 14724 if (item.pid == app.pid) { 14725 mPendingProcessChanges.remove(i); 14726 mAvailProcessChanges.add(item); 14727 } 14728 } 14729 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14730 14731 // If the caller is restarting this app, then leave it in its 14732 // current lists and let the caller take care of it. 14733 if (restarting) { 14734 return false; 14735 } 14736 14737 if (!app.persistent || app.isolated) { 14738 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14739 "Removing non-persistent process during cleanup: " + app); 14740 mProcessNames.remove(app.processName, app.uid); 14741 mIsolatedProcesses.remove(app.uid); 14742 if (mHeavyWeightProcess == app) { 14743 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14744 mHeavyWeightProcess.userId, 0)); 14745 mHeavyWeightProcess = null; 14746 } 14747 } else if (!app.removed) { 14748 // This app is persistent, so we need to keep its record around. 14749 // If it is not already on the pending app list, add it there 14750 // and start a new process for it. 14751 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14752 mPersistentStartingProcesses.add(app); 14753 restart = true; 14754 } 14755 } 14756 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14757 "Clean-up removing on hold: " + app); 14758 mProcessesOnHold.remove(app); 14759 14760 if (app == mHomeProcess) { 14761 mHomeProcess = null; 14762 } 14763 if (app == mPreviousProcess) { 14764 mPreviousProcess = null; 14765 } 14766 14767 if (restart && !app.isolated) { 14768 // We have components that still need to be running in the 14769 // process, so re-launch it. 14770 if (index < 0) { 14771 ProcessList.remove(app.pid); 14772 } 14773 mProcessNames.put(app.processName, app.uid, app); 14774 startProcessLocked(app, "restart", app.processName); 14775 return true; 14776 } else if (app.pid > 0 && app.pid != MY_PID) { 14777 // Goodbye! 14778 boolean removed; 14779 synchronized (mPidsSelfLocked) { 14780 mPidsSelfLocked.remove(app.pid); 14781 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14782 } 14783 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14784 if (app.isolated) { 14785 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14786 } 14787 app.setPid(0); 14788 } 14789 return false; 14790 } 14791 14792 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14793 // Look through the content providers we are waiting to have launched, 14794 // and if any run in this process then either schedule a restart of 14795 // the process or kill the client waiting for it if this process has 14796 // gone bad. 14797 int NL = mLaunchingProviders.size(); 14798 boolean restart = false; 14799 for (int i=0; i<NL; i++) { 14800 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14801 if (cpr.launchingApp == app) { 14802 if (!alwaysBad && !app.bad) { 14803 restart = true; 14804 } else { 14805 removeDyingProviderLocked(app, cpr, true); 14806 // cpr should have been removed from mLaunchingProviders 14807 NL = mLaunchingProviders.size(); 14808 i--; 14809 } 14810 } 14811 } 14812 return restart; 14813 } 14814 14815 // ========================================================= 14816 // SERVICES 14817 // ========================================================= 14818 14819 @Override 14820 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14821 int flags) { 14822 enforceNotIsolatedCaller("getServices"); 14823 synchronized (this) { 14824 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14825 } 14826 } 14827 14828 @Override 14829 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14830 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14831 synchronized (this) { 14832 return mServices.getRunningServiceControlPanelLocked(name); 14833 } 14834 } 14835 14836 @Override 14837 public ComponentName startService(IApplicationThread caller, Intent service, 14838 String resolvedType, int userId) { 14839 enforceNotIsolatedCaller("startService"); 14840 // Refuse possible leaked file descriptors 14841 if (service != null && service.hasFileDescriptors() == true) { 14842 throw new IllegalArgumentException("File descriptors passed in Intent"); 14843 } 14844 14845 if (DEBUG_SERVICE) 14846 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14847 synchronized(this) { 14848 final int callingPid = Binder.getCallingPid(); 14849 final int callingUid = Binder.getCallingUid(); 14850 final long origId = Binder.clearCallingIdentity(); 14851 ComponentName res = mServices.startServiceLocked(caller, service, 14852 resolvedType, callingPid, callingUid, userId); 14853 Binder.restoreCallingIdentity(origId); 14854 return res; 14855 } 14856 } 14857 14858 ComponentName startServiceInPackage(int uid, 14859 Intent service, String resolvedType, int userId) { 14860 synchronized(this) { 14861 if (DEBUG_SERVICE) 14862 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14863 final long origId = Binder.clearCallingIdentity(); 14864 ComponentName res = mServices.startServiceLocked(null, service, 14865 resolvedType, -1, uid, userId); 14866 Binder.restoreCallingIdentity(origId); 14867 return res; 14868 } 14869 } 14870 14871 @Override 14872 public int stopService(IApplicationThread caller, Intent service, 14873 String resolvedType, int userId) { 14874 enforceNotIsolatedCaller("stopService"); 14875 // Refuse possible leaked file descriptors 14876 if (service != null && service.hasFileDescriptors() == true) { 14877 throw new IllegalArgumentException("File descriptors passed in Intent"); 14878 } 14879 14880 synchronized(this) { 14881 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14882 } 14883 } 14884 14885 @Override 14886 public IBinder peekService(Intent service, String resolvedType) { 14887 enforceNotIsolatedCaller("peekService"); 14888 // Refuse possible leaked file descriptors 14889 if (service != null && service.hasFileDescriptors() == true) { 14890 throw new IllegalArgumentException("File descriptors passed in Intent"); 14891 } 14892 synchronized(this) { 14893 return mServices.peekServiceLocked(service, resolvedType); 14894 } 14895 } 14896 14897 @Override 14898 public boolean stopServiceToken(ComponentName className, IBinder token, 14899 int startId) { 14900 synchronized(this) { 14901 return mServices.stopServiceTokenLocked(className, token, startId); 14902 } 14903 } 14904 14905 @Override 14906 public void setServiceForeground(ComponentName className, IBinder token, 14907 int id, Notification notification, boolean removeNotification) { 14908 synchronized(this) { 14909 mServices.setServiceForegroundLocked(className, token, id, notification, 14910 removeNotification); 14911 } 14912 } 14913 14914 @Override 14915 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14916 boolean requireFull, String name, String callerPackage) { 14917 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14918 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14919 } 14920 14921 int unsafeConvertIncomingUser(int userId) { 14922 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14923 ? mCurrentUserId : userId; 14924 } 14925 14926 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14927 int allowMode, String name, String callerPackage) { 14928 final int callingUserId = UserHandle.getUserId(callingUid); 14929 if (callingUserId == userId) { 14930 return userId; 14931 } 14932 14933 // Note that we may be accessing mCurrentUserId outside of a lock... 14934 // shouldn't be a big deal, if this is being called outside 14935 // of a locked context there is intrinsically a race with 14936 // the value the caller will receive and someone else changing it. 14937 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14938 // we will switch to the calling user if access to the current user fails. 14939 int targetUserId = unsafeConvertIncomingUser(userId); 14940 14941 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14942 final boolean allow; 14943 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14944 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14945 // If the caller has this permission, they always pass go. And collect $200. 14946 allow = true; 14947 } else if (allowMode == ALLOW_FULL_ONLY) { 14948 // We require full access, sucks to be you. 14949 allow = false; 14950 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14951 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14952 // If the caller does not have either permission, they are always doomed. 14953 allow = false; 14954 } else if (allowMode == ALLOW_NON_FULL) { 14955 // We are blanket allowing non-full access, you lucky caller! 14956 allow = true; 14957 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14958 // We may or may not allow this depending on whether the two users are 14959 // in the same profile. 14960 synchronized (mUserProfileGroupIdsSelfLocked) { 14961 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14962 UserInfo.NO_PROFILE_GROUP_ID); 14963 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14964 UserInfo.NO_PROFILE_GROUP_ID); 14965 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14966 && callingProfile == targetProfile; 14967 } 14968 } else { 14969 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14970 } 14971 if (!allow) { 14972 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14973 // In this case, they would like to just execute as their 14974 // owner user instead of failing. 14975 targetUserId = callingUserId; 14976 } else { 14977 StringBuilder builder = new StringBuilder(128); 14978 builder.append("Permission Denial: "); 14979 builder.append(name); 14980 if (callerPackage != null) { 14981 builder.append(" from "); 14982 builder.append(callerPackage); 14983 } 14984 builder.append(" asks to run as user "); 14985 builder.append(userId); 14986 builder.append(" but is calling from user "); 14987 builder.append(UserHandle.getUserId(callingUid)); 14988 builder.append("; this requires "); 14989 builder.append(INTERACT_ACROSS_USERS_FULL); 14990 if (allowMode != ALLOW_FULL_ONLY) { 14991 builder.append(" or "); 14992 builder.append(INTERACT_ACROSS_USERS); 14993 } 14994 String msg = builder.toString(); 14995 Slog.w(TAG, msg); 14996 throw new SecurityException(msg); 14997 } 14998 } 14999 } 15000 if (!allowAll && targetUserId < 0) { 15001 throw new IllegalArgumentException( 15002 "Call does not support special user #" + targetUserId); 15003 } 15004 // Check shell permission 15005 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15006 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15007 targetUserId)) { 15008 throw new SecurityException("Shell does not have permission to access user " 15009 + targetUserId + "\n " + Debug.getCallers(3)); 15010 } 15011 } 15012 return targetUserId; 15013 } 15014 15015 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15016 String className, int flags) { 15017 boolean result = false; 15018 // For apps that don't have pre-defined UIDs, check for permission 15019 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15020 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15021 if (ActivityManager.checkUidPermission( 15022 INTERACT_ACROSS_USERS, 15023 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15024 ComponentName comp = new ComponentName(aInfo.packageName, className); 15025 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15026 + " requests FLAG_SINGLE_USER, but app does not hold " 15027 + INTERACT_ACROSS_USERS; 15028 Slog.w(TAG, msg); 15029 throw new SecurityException(msg); 15030 } 15031 // Permission passed 15032 result = true; 15033 } 15034 } else if ("system".equals(componentProcessName)) { 15035 result = true; 15036 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15037 // Phone app and persistent apps are allowed to export singleuser providers. 15038 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15039 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15040 } 15041 if (DEBUG_MU) { 15042 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15043 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15044 } 15045 return result; 15046 } 15047 15048 /** 15049 * Checks to see if the caller is in the same app as the singleton 15050 * component, or the component is in a special app. It allows special apps 15051 * to export singleton components but prevents exporting singleton 15052 * components for regular apps. 15053 */ 15054 boolean isValidSingletonCall(int callingUid, int componentUid) { 15055 int componentAppId = UserHandle.getAppId(componentUid); 15056 return UserHandle.isSameApp(callingUid, componentUid) 15057 || componentAppId == Process.SYSTEM_UID 15058 || componentAppId == Process.PHONE_UID 15059 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15060 == PackageManager.PERMISSION_GRANTED; 15061 } 15062 15063 public int bindService(IApplicationThread caller, IBinder token, 15064 Intent service, String resolvedType, 15065 IServiceConnection connection, int flags, int userId) { 15066 enforceNotIsolatedCaller("bindService"); 15067 15068 // Refuse possible leaked file descriptors 15069 if (service != null && service.hasFileDescriptors() == true) { 15070 throw new IllegalArgumentException("File descriptors passed in Intent"); 15071 } 15072 15073 synchronized(this) { 15074 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15075 connection, flags, userId); 15076 } 15077 } 15078 15079 public boolean unbindService(IServiceConnection connection) { 15080 synchronized (this) { 15081 return mServices.unbindServiceLocked(connection); 15082 } 15083 } 15084 15085 public void publishService(IBinder token, Intent intent, IBinder service) { 15086 // Refuse possible leaked file descriptors 15087 if (intent != null && intent.hasFileDescriptors() == true) { 15088 throw new IllegalArgumentException("File descriptors passed in Intent"); 15089 } 15090 15091 synchronized(this) { 15092 if (!(token instanceof ServiceRecord)) { 15093 throw new IllegalArgumentException("Invalid service token"); 15094 } 15095 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15096 } 15097 } 15098 15099 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15100 // Refuse possible leaked file descriptors 15101 if (intent != null && intent.hasFileDescriptors() == true) { 15102 throw new IllegalArgumentException("File descriptors passed in Intent"); 15103 } 15104 15105 synchronized(this) { 15106 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15107 } 15108 } 15109 15110 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15111 synchronized(this) { 15112 if (!(token instanceof ServiceRecord)) { 15113 throw new IllegalArgumentException("Invalid service token"); 15114 } 15115 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15116 } 15117 } 15118 15119 // ========================================================= 15120 // BACKUP AND RESTORE 15121 // ========================================================= 15122 15123 // Cause the target app to be launched if necessary and its backup agent 15124 // instantiated. The backup agent will invoke backupAgentCreated() on the 15125 // activity manager to announce its creation. 15126 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15127 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15128 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15129 15130 synchronized(this) { 15131 // !!! TODO: currently no check here that we're already bound 15132 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15133 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15134 synchronized (stats) { 15135 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15136 } 15137 15138 // Backup agent is now in use, its package can't be stopped. 15139 try { 15140 AppGlobals.getPackageManager().setPackageStoppedState( 15141 app.packageName, false, UserHandle.getUserId(app.uid)); 15142 } catch (RemoteException e) { 15143 } catch (IllegalArgumentException e) { 15144 Slog.w(TAG, "Failed trying to unstop package " 15145 + app.packageName + ": " + e); 15146 } 15147 15148 BackupRecord r = new BackupRecord(ss, app, backupMode); 15149 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15150 ? new ComponentName(app.packageName, app.backupAgentName) 15151 : new ComponentName("android", "FullBackupAgent"); 15152 // startProcessLocked() returns existing proc's record if it's already running 15153 ProcessRecord proc = startProcessLocked(app.processName, app, 15154 false, 0, "backup", hostingName, false, false, false); 15155 if (proc == null) { 15156 Slog.e(TAG, "Unable to start backup agent process " + r); 15157 return false; 15158 } 15159 15160 r.app = proc; 15161 mBackupTarget = r; 15162 mBackupAppName = app.packageName; 15163 15164 // Try not to kill the process during backup 15165 updateOomAdjLocked(proc); 15166 15167 // If the process is already attached, schedule the creation of the backup agent now. 15168 // If it is not yet live, this will be done when it attaches to the framework. 15169 if (proc.thread != null) { 15170 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15171 try { 15172 proc.thread.scheduleCreateBackupAgent(app, 15173 compatibilityInfoForPackageLocked(app), backupMode); 15174 } catch (RemoteException e) { 15175 // Will time out on the backup manager side 15176 } 15177 } else { 15178 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15179 } 15180 // Invariants: at this point, the target app process exists and the application 15181 // is either already running or in the process of coming up. mBackupTarget and 15182 // mBackupAppName describe the app, so that when it binds back to the AM we 15183 // know that it's scheduled for a backup-agent operation. 15184 } 15185 15186 return true; 15187 } 15188 15189 @Override 15190 public void clearPendingBackup() { 15191 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15192 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15193 15194 synchronized (this) { 15195 mBackupTarget = null; 15196 mBackupAppName = null; 15197 } 15198 } 15199 15200 // A backup agent has just come up 15201 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15202 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15203 + " = " + agent); 15204 15205 synchronized(this) { 15206 if (!agentPackageName.equals(mBackupAppName)) { 15207 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15208 return; 15209 } 15210 } 15211 15212 long oldIdent = Binder.clearCallingIdentity(); 15213 try { 15214 IBackupManager bm = IBackupManager.Stub.asInterface( 15215 ServiceManager.getService(Context.BACKUP_SERVICE)); 15216 bm.agentConnected(agentPackageName, agent); 15217 } catch (RemoteException e) { 15218 // can't happen; the backup manager service is local 15219 } catch (Exception e) { 15220 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15221 e.printStackTrace(); 15222 } finally { 15223 Binder.restoreCallingIdentity(oldIdent); 15224 } 15225 } 15226 15227 // done with this agent 15228 public void unbindBackupAgent(ApplicationInfo appInfo) { 15229 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15230 if (appInfo == null) { 15231 Slog.w(TAG, "unbind backup agent for null app"); 15232 return; 15233 } 15234 15235 synchronized(this) { 15236 try { 15237 if (mBackupAppName == null) { 15238 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15239 return; 15240 } 15241 15242 if (!mBackupAppName.equals(appInfo.packageName)) { 15243 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15244 return; 15245 } 15246 15247 // Not backing this app up any more; reset its OOM adjustment 15248 final ProcessRecord proc = mBackupTarget.app; 15249 updateOomAdjLocked(proc); 15250 15251 // If the app crashed during backup, 'thread' will be null here 15252 if (proc.thread != null) { 15253 try { 15254 proc.thread.scheduleDestroyBackupAgent(appInfo, 15255 compatibilityInfoForPackageLocked(appInfo)); 15256 } catch (Exception e) { 15257 Slog.e(TAG, "Exception when unbinding backup agent:"); 15258 e.printStackTrace(); 15259 } 15260 } 15261 } finally { 15262 mBackupTarget = null; 15263 mBackupAppName = null; 15264 } 15265 } 15266 } 15267 // ========================================================= 15268 // BROADCASTS 15269 // ========================================================= 15270 15271 private final List getStickiesLocked(String action, IntentFilter filter, 15272 List cur, int userId) { 15273 final ContentResolver resolver = mContext.getContentResolver(); 15274 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15275 if (stickies == null) { 15276 return cur; 15277 } 15278 final ArrayList<Intent> list = stickies.get(action); 15279 if (list == null) { 15280 return cur; 15281 } 15282 int N = list.size(); 15283 for (int i=0; i<N; i++) { 15284 Intent intent = list.get(i); 15285 if (filter.match(resolver, intent, true, TAG) >= 0) { 15286 if (cur == null) { 15287 cur = new ArrayList<Intent>(); 15288 } 15289 cur.add(intent); 15290 } 15291 } 15292 return cur; 15293 } 15294 15295 boolean isPendingBroadcastProcessLocked(int pid) { 15296 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15297 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15298 } 15299 15300 void skipPendingBroadcastLocked(int pid) { 15301 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15302 for (BroadcastQueue queue : mBroadcastQueues) { 15303 queue.skipPendingBroadcastLocked(pid); 15304 } 15305 } 15306 15307 // The app just attached; send any pending broadcasts that it should receive 15308 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15309 boolean didSomething = false; 15310 for (BroadcastQueue queue : mBroadcastQueues) { 15311 didSomething |= queue.sendPendingBroadcastsLocked(app); 15312 } 15313 return didSomething; 15314 } 15315 15316 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15317 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15318 enforceNotIsolatedCaller("registerReceiver"); 15319 int callingUid; 15320 int callingPid; 15321 synchronized(this) { 15322 ProcessRecord callerApp = null; 15323 if (caller != null) { 15324 callerApp = getRecordForAppLocked(caller); 15325 if (callerApp == null) { 15326 throw new SecurityException( 15327 "Unable to find app for caller " + caller 15328 + " (pid=" + Binder.getCallingPid() 15329 + ") when registering receiver " + receiver); 15330 } 15331 if (callerApp.info.uid != Process.SYSTEM_UID && 15332 !callerApp.pkgList.containsKey(callerPackage) && 15333 !"android".equals(callerPackage)) { 15334 throw new SecurityException("Given caller package " + callerPackage 15335 + " is not running in process " + callerApp); 15336 } 15337 callingUid = callerApp.info.uid; 15338 callingPid = callerApp.pid; 15339 } else { 15340 callerPackage = null; 15341 callingUid = Binder.getCallingUid(); 15342 callingPid = Binder.getCallingPid(); 15343 } 15344 15345 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15346 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15347 15348 List allSticky = null; 15349 15350 // Look for any matching sticky broadcasts... 15351 Iterator actions = filter.actionsIterator(); 15352 if (actions != null) { 15353 while (actions.hasNext()) { 15354 String action = (String)actions.next(); 15355 allSticky = getStickiesLocked(action, filter, allSticky, 15356 UserHandle.USER_ALL); 15357 allSticky = getStickiesLocked(action, filter, allSticky, 15358 UserHandle.getUserId(callingUid)); 15359 } 15360 } else { 15361 allSticky = getStickiesLocked(null, filter, allSticky, 15362 UserHandle.USER_ALL); 15363 allSticky = getStickiesLocked(null, filter, allSticky, 15364 UserHandle.getUserId(callingUid)); 15365 } 15366 15367 // The first sticky in the list is returned directly back to 15368 // the client. 15369 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15370 15371 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15372 + ": " + sticky); 15373 15374 if (receiver == null) { 15375 return sticky; 15376 } 15377 15378 ReceiverList rl 15379 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15380 if (rl == null) { 15381 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15382 userId, receiver); 15383 if (rl.app != null) { 15384 rl.app.receivers.add(rl); 15385 } else { 15386 try { 15387 receiver.asBinder().linkToDeath(rl, 0); 15388 } catch (RemoteException e) { 15389 return sticky; 15390 } 15391 rl.linkedToDeath = true; 15392 } 15393 mRegisteredReceivers.put(receiver.asBinder(), rl); 15394 } else if (rl.uid != callingUid) { 15395 throw new IllegalArgumentException( 15396 "Receiver requested to register for uid " + callingUid 15397 + " was previously registered for uid " + rl.uid); 15398 } else if (rl.pid != callingPid) { 15399 throw new IllegalArgumentException( 15400 "Receiver requested to register for pid " + callingPid 15401 + " was previously registered for pid " + rl.pid); 15402 } else if (rl.userId != userId) { 15403 throw new IllegalArgumentException( 15404 "Receiver requested to register for user " + userId 15405 + " was previously registered for user " + rl.userId); 15406 } 15407 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15408 permission, callingUid, userId); 15409 rl.add(bf); 15410 if (!bf.debugCheck()) { 15411 Slog.w(TAG, "==> For Dynamic broadast"); 15412 } 15413 mReceiverResolver.addFilter(bf); 15414 15415 // Enqueue broadcasts for all existing stickies that match 15416 // this filter. 15417 if (allSticky != null) { 15418 ArrayList receivers = new ArrayList(); 15419 receivers.add(bf); 15420 15421 int N = allSticky.size(); 15422 for (int i=0; i<N; i++) { 15423 Intent intent = (Intent)allSticky.get(i); 15424 BroadcastQueue queue = broadcastQueueForIntent(intent); 15425 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15426 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15427 null, null, false, true, true, -1); 15428 queue.enqueueParallelBroadcastLocked(r); 15429 queue.scheduleBroadcastsLocked(); 15430 } 15431 } 15432 15433 return sticky; 15434 } 15435 } 15436 15437 public void unregisterReceiver(IIntentReceiver receiver) { 15438 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15439 15440 final long origId = Binder.clearCallingIdentity(); 15441 try { 15442 boolean doTrim = false; 15443 15444 synchronized(this) { 15445 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15446 if (rl != null) { 15447 if (rl.curBroadcast != null) { 15448 BroadcastRecord r = rl.curBroadcast; 15449 final boolean doNext = finishReceiverLocked( 15450 receiver.asBinder(), r.resultCode, r.resultData, 15451 r.resultExtras, r.resultAbort); 15452 if (doNext) { 15453 doTrim = true; 15454 r.queue.processNextBroadcast(false); 15455 } 15456 } 15457 15458 if (rl.app != null) { 15459 rl.app.receivers.remove(rl); 15460 } 15461 removeReceiverLocked(rl); 15462 if (rl.linkedToDeath) { 15463 rl.linkedToDeath = false; 15464 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15465 } 15466 } 15467 } 15468 15469 // If we actually concluded any broadcasts, we might now be able 15470 // to trim the recipients' apps from our working set 15471 if (doTrim) { 15472 trimApplications(); 15473 return; 15474 } 15475 15476 } finally { 15477 Binder.restoreCallingIdentity(origId); 15478 } 15479 } 15480 15481 void removeReceiverLocked(ReceiverList rl) { 15482 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15483 int N = rl.size(); 15484 for (int i=0; i<N; i++) { 15485 mReceiverResolver.removeFilter(rl.get(i)); 15486 } 15487 } 15488 15489 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15490 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15491 ProcessRecord r = mLruProcesses.get(i); 15492 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15493 try { 15494 r.thread.dispatchPackageBroadcast(cmd, packages); 15495 } catch (RemoteException ex) { 15496 } 15497 } 15498 } 15499 } 15500 15501 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15502 int callingUid, int[] users) { 15503 List<ResolveInfo> receivers = null; 15504 try { 15505 HashSet<ComponentName> singleUserReceivers = null; 15506 boolean scannedFirstReceivers = false; 15507 for (int user : users) { 15508 // Skip users that have Shell restrictions 15509 if (callingUid == Process.SHELL_UID 15510 && getUserManagerLocked().hasUserRestriction( 15511 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15512 continue; 15513 } 15514 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15515 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15516 if (user != 0 && newReceivers != null) { 15517 // If this is not the primary user, we need to check for 15518 // any receivers that should be filtered out. 15519 for (int i=0; i<newReceivers.size(); i++) { 15520 ResolveInfo ri = newReceivers.get(i); 15521 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15522 newReceivers.remove(i); 15523 i--; 15524 } 15525 } 15526 } 15527 if (newReceivers != null && newReceivers.size() == 0) { 15528 newReceivers = null; 15529 } 15530 if (receivers == null) { 15531 receivers = newReceivers; 15532 } else if (newReceivers != null) { 15533 // We need to concatenate the additional receivers 15534 // found with what we have do far. This would be easy, 15535 // but we also need to de-dup any receivers that are 15536 // singleUser. 15537 if (!scannedFirstReceivers) { 15538 // Collect any single user receivers we had already retrieved. 15539 scannedFirstReceivers = true; 15540 for (int i=0; i<receivers.size(); i++) { 15541 ResolveInfo ri = receivers.get(i); 15542 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15543 ComponentName cn = new ComponentName( 15544 ri.activityInfo.packageName, ri.activityInfo.name); 15545 if (singleUserReceivers == null) { 15546 singleUserReceivers = new HashSet<ComponentName>(); 15547 } 15548 singleUserReceivers.add(cn); 15549 } 15550 } 15551 } 15552 // Add the new results to the existing results, tracking 15553 // and de-dupping single user receivers. 15554 for (int i=0; i<newReceivers.size(); i++) { 15555 ResolveInfo ri = newReceivers.get(i); 15556 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15557 ComponentName cn = new ComponentName( 15558 ri.activityInfo.packageName, ri.activityInfo.name); 15559 if (singleUserReceivers == null) { 15560 singleUserReceivers = new HashSet<ComponentName>(); 15561 } 15562 if (!singleUserReceivers.contains(cn)) { 15563 singleUserReceivers.add(cn); 15564 receivers.add(ri); 15565 } 15566 } else { 15567 receivers.add(ri); 15568 } 15569 } 15570 } 15571 } 15572 } catch (RemoteException ex) { 15573 // pm is in same process, this will never happen. 15574 } 15575 return receivers; 15576 } 15577 15578 private final int broadcastIntentLocked(ProcessRecord callerApp, 15579 String callerPackage, Intent intent, String resolvedType, 15580 IIntentReceiver resultTo, int resultCode, String resultData, 15581 Bundle map, String requiredPermission, int appOp, 15582 boolean ordered, boolean sticky, int callingPid, int callingUid, 15583 int userId) { 15584 intent = new Intent(intent); 15585 15586 // By default broadcasts do not go to stopped apps. 15587 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15588 15589 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15590 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15591 + " ordered=" + ordered + " userid=" + userId); 15592 if ((resultTo != null) && !ordered) { 15593 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15594 } 15595 15596 userId = handleIncomingUser(callingPid, callingUid, userId, 15597 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15598 15599 // Make sure that the user who is receiving this broadcast is started. 15600 // If not, we will just skip it. 15601 15602 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15603 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15604 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15605 Slog.w(TAG, "Skipping broadcast of " + intent 15606 + ": user " + userId + " is stopped"); 15607 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15608 } 15609 } 15610 15611 /* 15612 * Prevent non-system code (defined here to be non-persistent 15613 * processes) from sending protected broadcasts. 15614 */ 15615 int callingAppId = UserHandle.getAppId(callingUid); 15616 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15617 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15618 || callingAppId == Process.NFC_UID || callingUid == 0) { 15619 // Always okay. 15620 } else if (callerApp == null || !callerApp.persistent) { 15621 try { 15622 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15623 intent.getAction())) { 15624 String msg = "Permission Denial: not allowed to send broadcast " 15625 + intent.getAction() + " from pid=" 15626 + callingPid + ", uid=" + callingUid; 15627 Slog.w(TAG, msg); 15628 throw new SecurityException(msg); 15629 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15630 // Special case for compatibility: we don't want apps to send this, 15631 // but historically it has not been protected and apps may be using it 15632 // to poke their own app widget. So, instead of making it protected, 15633 // just limit it to the caller. 15634 if (callerApp == null) { 15635 String msg = "Permission Denial: not allowed to send broadcast " 15636 + intent.getAction() + " from unknown caller."; 15637 Slog.w(TAG, msg); 15638 throw new SecurityException(msg); 15639 } else if (intent.getComponent() != null) { 15640 // They are good enough to send to an explicit component... verify 15641 // it is being sent to the calling app. 15642 if (!intent.getComponent().getPackageName().equals( 15643 callerApp.info.packageName)) { 15644 String msg = "Permission Denial: not allowed to send broadcast " 15645 + intent.getAction() + " to " 15646 + intent.getComponent().getPackageName() + " from " 15647 + callerApp.info.packageName; 15648 Slog.w(TAG, msg); 15649 throw new SecurityException(msg); 15650 } 15651 } else { 15652 // Limit broadcast to their own package. 15653 intent.setPackage(callerApp.info.packageName); 15654 } 15655 } 15656 } catch (RemoteException e) { 15657 Slog.w(TAG, "Remote exception", e); 15658 return ActivityManager.BROADCAST_SUCCESS; 15659 } 15660 } 15661 15662 final String action = intent.getAction(); 15663 if (action != null) { 15664 switch (action) { 15665 case Intent.ACTION_UID_REMOVED: 15666 case Intent.ACTION_PACKAGE_REMOVED: 15667 case Intent.ACTION_PACKAGE_CHANGED: 15668 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15669 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15670 // Handle special intents: if this broadcast is from the package 15671 // manager about a package being removed, we need to remove all of 15672 // its activities from the history stack. 15673 if (checkComponentPermission( 15674 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15675 callingPid, callingUid, -1, true) 15676 != PackageManager.PERMISSION_GRANTED) { 15677 String msg = "Permission Denial: " + intent.getAction() 15678 + " broadcast from " + callerPackage + " (pid=" + callingPid 15679 + ", uid=" + callingUid + ")" 15680 + " requires " 15681 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15682 Slog.w(TAG, msg); 15683 throw new SecurityException(msg); 15684 } 15685 switch (action) { 15686 case Intent.ACTION_UID_REMOVED: 15687 final Bundle intentExtras = intent.getExtras(); 15688 final int uid = intentExtras != null 15689 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15690 if (uid >= 0) { 15691 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15692 synchronized (bs) { 15693 bs.removeUidStatsLocked(uid); 15694 } 15695 mAppOpsService.uidRemoved(uid); 15696 } 15697 break; 15698 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15699 // If resources are unavailable just force stop all those packages 15700 // and flush the attribute cache as well. 15701 String list[] = 15702 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15703 if (list != null && list.length > 0) { 15704 for (int i = 0; i < list.length; i++) { 15705 forceStopPackageLocked(list[i], -1, false, true, true, 15706 false, false, userId, "storage unmount"); 15707 } 15708 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15709 sendPackageBroadcastLocked( 15710 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15711 userId); 15712 } 15713 break; 15714 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15715 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15716 break; 15717 case Intent.ACTION_PACKAGE_REMOVED: 15718 case Intent.ACTION_PACKAGE_CHANGED: 15719 Uri data = intent.getData(); 15720 String ssp; 15721 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15722 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15723 boolean fullUninstall = removed && 15724 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15725 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15726 forceStopPackageLocked(ssp, UserHandle.getAppId( 15727 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15728 false, true, true, false, fullUninstall, userId, 15729 removed ? "pkg removed" : "pkg changed"); 15730 } 15731 if (removed) { 15732 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15733 new String[] {ssp}, userId); 15734 if (fullUninstall) { 15735 mAppOpsService.packageRemoved( 15736 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15737 15738 // Remove all permissions granted from/to this package 15739 removeUriPermissionsForPackageLocked(ssp, userId, true); 15740 15741 removeTasksByPackageNameLocked(ssp, userId); 15742 } 15743 } else { 15744 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15745 } 15746 } 15747 break; 15748 } 15749 break; 15750 case Intent.ACTION_PACKAGE_ADDED: 15751 // Special case for adding a package: by default turn on compatibility mode. 15752 Uri data = intent.getData(); 15753 String ssp; 15754 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15755 final boolean replacing = 15756 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15757 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15758 15759 if (replacing) { 15760 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15761 } 15762 } 15763 break; 15764 case Intent.ACTION_TIMEZONE_CHANGED: 15765 // If this is the time zone changed action, queue up a message that will reset 15766 // the timezone of all currently running processes. This message will get 15767 // queued up before the broadcast happens. 15768 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15769 break; 15770 case Intent.ACTION_TIME_CHANGED: 15771 // If the user set the time, let all running processes know. 15772 final int is24Hour = 15773 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15774 : 0; 15775 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15776 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15777 synchronized (stats) { 15778 stats.noteCurrentTimeChangedLocked(); 15779 } 15780 break; 15781 case Intent.ACTION_CLEAR_DNS_CACHE: 15782 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15783 break; 15784 case Proxy.PROXY_CHANGE_ACTION: 15785 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15786 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15787 break; 15788 } 15789 } 15790 15791 // Add to the sticky list if requested. 15792 if (sticky) { 15793 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15794 callingPid, callingUid) 15795 != PackageManager.PERMISSION_GRANTED) { 15796 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15797 + callingPid + ", uid=" + callingUid 15798 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15799 Slog.w(TAG, msg); 15800 throw new SecurityException(msg); 15801 } 15802 if (requiredPermission != null) { 15803 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15804 + " and enforce permission " + requiredPermission); 15805 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15806 } 15807 if (intent.getComponent() != null) { 15808 throw new SecurityException( 15809 "Sticky broadcasts can't target a specific component"); 15810 } 15811 // We use userId directly here, since the "all" target is maintained 15812 // as a separate set of sticky broadcasts. 15813 if (userId != UserHandle.USER_ALL) { 15814 // But first, if this is not a broadcast to all users, then 15815 // make sure it doesn't conflict with an existing broadcast to 15816 // all users. 15817 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15818 UserHandle.USER_ALL); 15819 if (stickies != null) { 15820 ArrayList<Intent> list = stickies.get(intent.getAction()); 15821 if (list != null) { 15822 int N = list.size(); 15823 int i; 15824 for (i=0; i<N; i++) { 15825 if (intent.filterEquals(list.get(i))) { 15826 throw new IllegalArgumentException( 15827 "Sticky broadcast " + intent + " for user " 15828 + userId + " conflicts with existing global broadcast"); 15829 } 15830 } 15831 } 15832 } 15833 } 15834 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15835 if (stickies == null) { 15836 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15837 mStickyBroadcasts.put(userId, stickies); 15838 } 15839 ArrayList<Intent> list = stickies.get(intent.getAction()); 15840 if (list == null) { 15841 list = new ArrayList<Intent>(); 15842 stickies.put(intent.getAction(), list); 15843 } 15844 int N = list.size(); 15845 int i; 15846 for (i=0; i<N; i++) { 15847 if (intent.filterEquals(list.get(i))) { 15848 // This sticky already exists, replace it. 15849 list.set(i, new Intent(intent)); 15850 break; 15851 } 15852 } 15853 if (i >= N) { 15854 list.add(new Intent(intent)); 15855 } 15856 } 15857 15858 int[] users; 15859 if (userId == UserHandle.USER_ALL) { 15860 // Caller wants broadcast to go to all started users. 15861 users = mStartedUserArray; 15862 } else { 15863 // Caller wants broadcast to go to one specific user. 15864 users = new int[] {userId}; 15865 } 15866 15867 // Figure out who all will receive this broadcast. 15868 List receivers = null; 15869 List<BroadcastFilter> registeredReceivers = null; 15870 // Need to resolve the intent to interested receivers... 15871 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15872 == 0) { 15873 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15874 } 15875 if (intent.getComponent() == null) { 15876 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15877 // Query one target user at a time, excluding shell-restricted users 15878 UserManagerService ums = getUserManagerLocked(); 15879 for (int i = 0; i < users.length; i++) { 15880 if (ums.hasUserRestriction( 15881 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15882 continue; 15883 } 15884 List<BroadcastFilter> registeredReceiversForUser = 15885 mReceiverResolver.queryIntent(intent, 15886 resolvedType, false, users[i]); 15887 if (registeredReceivers == null) { 15888 registeredReceivers = registeredReceiversForUser; 15889 } else if (registeredReceiversForUser != null) { 15890 registeredReceivers.addAll(registeredReceiversForUser); 15891 } 15892 } 15893 } else { 15894 registeredReceivers = mReceiverResolver.queryIntent(intent, 15895 resolvedType, false, userId); 15896 } 15897 } 15898 15899 final boolean replacePending = 15900 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15901 15902 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15903 + " replacePending=" + replacePending); 15904 15905 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15906 if (!ordered && NR > 0) { 15907 // If we are not serializing this broadcast, then send the 15908 // registered receivers separately so they don't wait for the 15909 // components to be launched. 15910 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15911 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15912 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15913 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15914 ordered, sticky, false, userId); 15915 if (DEBUG_BROADCAST) Slog.v( 15916 TAG, "Enqueueing parallel broadcast " + r); 15917 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15918 if (!replaced) { 15919 queue.enqueueParallelBroadcastLocked(r); 15920 queue.scheduleBroadcastsLocked(); 15921 } 15922 registeredReceivers = null; 15923 NR = 0; 15924 } 15925 15926 // Merge into one list. 15927 int ir = 0; 15928 if (receivers != null) { 15929 // A special case for PACKAGE_ADDED: do not allow the package 15930 // being added to see this broadcast. This prevents them from 15931 // using this as a back door to get run as soon as they are 15932 // installed. Maybe in the future we want to have a special install 15933 // broadcast or such for apps, but we'd like to deliberately make 15934 // this decision. 15935 String skipPackages[] = null; 15936 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15937 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15938 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15939 Uri data = intent.getData(); 15940 if (data != null) { 15941 String pkgName = data.getSchemeSpecificPart(); 15942 if (pkgName != null) { 15943 skipPackages = new String[] { pkgName }; 15944 } 15945 } 15946 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15947 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15948 } 15949 if (skipPackages != null && (skipPackages.length > 0)) { 15950 for (String skipPackage : skipPackages) { 15951 if (skipPackage != null) { 15952 int NT = receivers.size(); 15953 for (int it=0; it<NT; it++) { 15954 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15955 if (curt.activityInfo.packageName.equals(skipPackage)) { 15956 receivers.remove(it); 15957 it--; 15958 NT--; 15959 } 15960 } 15961 } 15962 } 15963 } 15964 15965 int NT = receivers != null ? receivers.size() : 0; 15966 int it = 0; 15967 ResolveInfo curt = null; 15968 BroadcastFilter curr = null; 15969 while (it < NT && ir < NR) { 15970 if (curt == null) { 15971 curt = (ResolveInfo)receivers.get(it); 15972 } 15973 if (curr == null) { 15974 curr = registeredReceivers.get(ir); 15975 } 15976 if (curr.getPriority() >= curt.priority) { 15977 // Insert this broadcast record into the final list. 15978 receivers.add(it, curr); 15979 ir++; 15980 curr = null; 15981 it++; 15982 NT++; 15983 } else { 15984 // Skip to the next ResolveInfo in the final list. 15985 it++; 15986 curt = null; 15987 } 15988 } 15989 } 15990 while (ir < NR) { 15991 if (receivers == null) { 15992 receivers = new ArrayList(); 15993 } 15994 receivers.add(registeredReceivers.get(ir)); 15995 ir++; 15996 } 15997 15998 if ((receivers != null && receivers.size() > 0) 15999 || resultTo != null) { 16000 BroadcastQueue queue = broadcastQueueForIntent(intent); 16001 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16002 callerPackage, callingPid, callingUid, resolvedType, 16003 requiredPermission, appOp, receivers, resultTo, resultCode, 16004 resultData, map, ordered, sticky, false, userId); 16005 if (DEBUG_BROADCAST) Slog.v( 16006 TAG, "Enqueueing ordered broadcast " + r 16007 + ": prev had " + queue.mOrderedBroadcasts.size()); 16008 if (DEBUG_BROADCAST) { 16009 int seq = r.intent.getIntExtra("seq", -1); 16010 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16011 } 16012 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16013 if (!replaced) { 16014 queue.enqueueOrderedBroadcastLocked(r); 16015 queue.scheduleBroadcastsLocked(); 16016 } 16017 } 16018 16019 return ActivityManager.BROADCAST_SUCCESS; 16020 } 16021 16022 final Intent verifyBroadcastLocked(Intent intent) { 16023 // Refuse possible leaked file descriptors 16024 if (intent != null && intent.hasFileDescriptors() == true) { 16025 throw new IllegalArgumentException("File descriptors passed in Intent"); 16026 } 16027 16028 int flags = intent.getFlags(); 16029 16030 if (!mProcessesReady) { 16031 // if the caller really truly claims to know what they're doing, go 16032 // ahead and allow the broadcast without launching any receivers 16033 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16034 intent = new Intent(intent); 16035 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16036 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16037 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16038 + " before boot completion"); 16039 throw new IllegalStateException("Cannot broadcast before boot completed"); 16040 } 16041 } 16042 16043 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16044 throw new IllegalArgumentException( 16045 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16046 } 16047 16048 return intent; 16049 } 16050 16051 public final int broadcastIntent(IApplicationThread caller, 16052 Intent intent, String resolvedType, IIntentReceiver resultTo, 16053 int resultCode, String resultData, Bundle map, 16054 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16055 enforceNotIsolatedCaller("broadcastIntent"); 16056 synchronized(this) { 16057 intent = verifyBroadcastLocked(intent); 16058 16059 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16060 final int callingPid = Binder.getCallingPid(); 16061 final int callingUid = Binder.getCallingUid(); 16062 final long origId = Binder.clearCallingIdentity(); 16063 int res = broadcastIntentLocked(callerApp, 16064 callerApp != null ? callerApp.info.packageName : null, 16065 intent, resolvedType, resultTo, 16066 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16067 callingPid, callingUid, userId); 16068 Binder.restoreCallingIdentity(origId); 16069 return res; 16070 } 16071 } 16072 16073 int broadcastIntentInPackage(String packageName, int uid, 16074 Intent intent, String resolvedType, IIntentReceiver resultTo, 16075 int resultCode, String resultData, Bundle map, 16076 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16077 synchronized(this) { 16078 intent = verifyBroadcastLocked(intent); 16079 16080 final long origId = Binder.clearCallingIdentity(); 16081 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16082 resultTo, resultCode, resultData, map, requiredPermission, 16083 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16084 Binder.restoreCallingIdentity(origId); 16085 return res; 16086 } 16087 } 16088 16089 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16090 // Refuse possible leaked file descriptors 16091 if (intent != null && intent.hasFileDescriptors() == true) { 16092 throw new IllegalArgumentException("File descriptors passed in Intent"); 16093 } 16094 16095 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16096 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16097 16098 synchronized(this) { 16099 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16100 != PackageManager.PERMISSION_GRANTED) { 16101 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16102 + Binder.getCallingPid() 16103 + ", uid=" + Binder.getCallingUid() 16104 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16105 Slog.w(TAG, msg); 16106 throw new SecurityException(msg); 16107 } 16108 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16109 if (stickies != null) { 16110 ArrayList<Intent> list = stickies.get(intent.getAction()); 16111 if (list != null) { 16112 int N = list.size(); 16113 int i; 16114 for (i=0; i<N; i++) { 16115 if (intent.filterEquals(list.get(i))) { 16116 list.remove(i); 16117 break; 16118 } 16119 } 16120 if (list.size() <= 0) { 16121 stickies.remove(intent.getAction()); 16122 } 16123 } 16124 if (stickies.size() <= 0) { 16125 mStickyBroadcasts.remove(userId); 16126 } 16127 } 16128 } 16129 } 16130 16131 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16132 String resultData, Bundle resultExtras, boolean resultAbort) { 16133 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16134 if (r == null) { 16135 Slog.w(TAG, "finishReceiver called but not found on queue"); 16136 return false; 16137 } 16138 16139 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16140 } 16141 16142 void backgroundServicesFinishedLocked(int userId) { 16143 for (BroadcastQueue queue : mBroadcastQueues) { 16144 queue.backgroundServicesFinishedLocked(userId); 16145 } 16146 } 16147 16148 public void finishReceiver(IBinder who, int resultCode, String resultData, 16149 Bundle resultExtras, boolean resultAbort) { 16150 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16151 16152 // Refuse possible leaked file descriptors 16153 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16154 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16155 } 16156 16157 final long origId = Binder.clearCallingIdentity(); 16158 try { 16159 boolean doNext = false; 16160 BroadcastRecord r; 16161 16162 synchronized(this) { 16163 r = broadcastRecordForReceiverLocked(who); 16164 if (r != null) { 16165 doNext = r.queue.finishReceiverLocked(r, resultCode, 16166 resultData, resultExtras, resultAbort, true); 16167 } 16168 } 16169 16170 if (doNext) { 16171 r.queue.processNextBroadcast(false); 16172 } 16173 trimApplications(); 16174 } finally { 16175 Binder.restoreCallingIdentity(origId); 16176 } 16177 } 16178 16179 // ========================================================= 16180 // INSTRUMENTATION 16181 // ========================================================= 16182 16183 public boolean startInstrumentation(ComponentName className, 16184 String profileFile, int flags, Bundle arguments, 16185 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16186 int userId, String abiOverride) { 16187 enforceNotIsolatedCaller("startInstrumentation"); 16188 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16189 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16190 // Refuse possible leaked file descriptors 16191 if (arguments != null && arguments.hasFileDescriptors()) { 16192 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16193 } 16194 16195 synchronized(this) { 16196 InstrumentationInfo ii = null; 16197 ApplicationInfo ai = null; 16198 try { 16199 ii = mContext.getPackageManager().getInstrumentationInfo( 16200 className, STOCK_PM_FLAGS); 16201 ai = AppGlobals.getPackageManager().getApplicationInfo( 16202 ii.targetPackage, STOCK_PM_FLAGS, userId); 16203 } catch (PackageManager.NameNotFoundException e) { 16204 } catch (RemoteException e) { 16205 } 16206 if (ii == null) { 16207 reportStartInstrumentationFailure(watcher, className, 16208 "Unable to find instrumentation info for: " + className); 16209 return false; 16210 } 16211 if (ai == null) { 16212 reportStartInstrumentationFailure(watcher, className, 16213 "Unable to find instrumentation target package: " + ii.targetPackage); 16214 return false; 16215 } 16216 16217 int match = mContext.getPackageManager().checkSignatures( 16218 ii.targetPackage, ii.packageName); 16219 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16220 String msg = "Permission Denial: starting instrumentation " 16221 + className + " from pid=" 16222 + Binder.getCallingPid() 16223 + ", uid=" + Binder.getCallingPid() 16224 + " not allowed because package " + ii.packageName 16225 + " does not have a signature matching the target " 16226 + ii.targetPackage; 16227 reportStartInstrumentationFailure(watcher, className, msg); 16228 throw new SecurityException(msg); 16229 } 16230 16231 final long origId = Binder.clearCallingIdentity(); 16232 // Instrumentation can kill and relaunch even persistent processes 16233 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16234 "start instr"); 16235 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16236 app.instrumentationClass = className; 16237 app.instrumentationInfo = ai; 16238 app.instrumentationProfileFile = profileFile; 16239 app.instrumentationArguments = arguments; 16240 app.instrumentationWatcher = watcher; 16241 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16242 app.instrumentationResultClass = className; 16243 Binder.restoreCallingIdentity(origId); 16244 } 16245 16246 return true; 16247 } 16248 16249 /** 16250 * Report errors that occur while attempting to start Instrumentation. Always writes the 16251 * error to the logs, but if somebody is watching, send the report there too. This enables 16252 * the "am" command to report errors with more information. 16253 * 16254 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16255 * @param cn The component name of the instrumentation. 16256 * @param report The error report. 16257 */ 16258 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16259 ComponentName cn, String report) { 16260 Slog.w(TAG, report); 16261 try { 16262 if (watcher != null) { 16263 Bundle results = new Bundle(); 16264 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16265 results.putString("Error", report); 16266 watcher.instrumentationStatus(cn, -1, results); 16267 } 16268 } catch (RemoteException e) { 16269 Slog.w(TAG, e); 16270 } 16271 } 16272 16273 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16274 if (app.instrumentationWatcher != null) { 16275 try { 16276 // NOTE: IInstrumentationWatcher *must* be oneway here 16277 app.instrumentationWatcher.instrumentationFinished( 16278 app.instrumentationClass, 16279 resultCode, 16280 results); 16281 } catch (RemoteException e) { 16282 } 16283 } 16284 if (app.instrumentationUiAutomationConnection != null) { 16285 try { 16286 app.instrumentationUiAutomationConnection.shutdown(); 16287 } catch (RemoteException re) { 16288 /* ignore */ 16289 } 16290 // Only a UiAutomation can set this flag and now that 16291 // it is finished we make sure it is reset to its default. 16292 mUserIsMonkey = false; 16293 } 16294 app.instrumentationWatcher = null; 16295 app.instrumentationUiAutomationConnection = null; 16296 app.instrumentationClass = null; 16297 app.instrumentationInfo = null; 16298 app.instrumentationProfileFile = null; 16299 app.instrumentationArguments = null; 16300 16301 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16302 "finished inst"); 16303 } 16304 16305 public void finishInstrumentation(IApplicationThread target, 16306 int resultCode, Bundle results) { 16307 int userId = UserHandle.getCallingUserId(); 16308 // Refuse possible leaked file descriptors 16309 if (results != null && results.hasFileDescriptors()) { 16310 throw new IllegalArgumentException("File descriptors passed in Intent"); 16311 } 16312 16313 synchronized(this) { 16314 ProcessRecord app = getRecordForAppLocked(target); 16315 if (app == null) { 16316 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16317 return; 16318 } 16319 final long origId = Binder.clearCallingIdentity(); 16320 finishInstrumentationLocked(app, resultCode, results); 16321 Binder.restoreCallingIdentity(origId); 16322 } 16323 } 16324 16325 // ========================================================= 16326 // CONFIGURATION 16327 // ========================================================= 16328 16329 public ConfigurationInfo getDeviceConfigurationInfo() { 16330 ConfigurationInfo config = new ConfigurationInfo(); 16331 synchronized (this) { 16332 config.reqTouchScreen = mConfiguration.touchscreen; 16333 config.reqKeyboardType = mConfiguration.keyboard; 16334 config.reqNavigation = mConfiguration.navigation; 16335 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16336 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16337 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16338 } 16339 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16340 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16341 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16342 } 16343 config.reqGlEsVersion = GL_ES_VERSION; 16344 } 16345 return config; 16346 } 16347 16348 ActivityStack getFocusedStack() { 16349 return mStackSupervisor.getFocusedStack(); 16350 } 16351 16352 public Configuration getConfiguration() { 16353 Configuration ci; 16354 synchronized(this) { 16355 ci = new Configuration(mConfiguration); 16356 } 16357 return ci; 16358 } 16359 16360 public void updatePersistentConfiguration(Configuration values) { 16361 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16362 "updateConfiguration()"); 16363 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16364 "updateConfiguration()"); 16365 if (values == null) { 16366 throw new NullPointerException("Configuration must not be null"); 16367 } 16368 16369 synchronized(this) { 16370 final long origId = Binder.clearCallingIdentity(); 16371 updateConfigurationLocked(values, null, true, false); 16372 Binder.restoreCallingIdentity(origId); 16373 } 16374 } 16375 16376 public void updateConfiguration(Configuration values) { 16377 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16378 "updateConfiguration()"); 16379 16380 synchronized(this) { 16381 if (values == null && mWindowManager != null) { 16382 // sentinel: fetch the current configuration from the window manager 16383 values = mWindowManager.computeNewConfiguration(); 16384 } 16385 16386 if (mWindowManager != null) { 16387 mProcessList.applyDisplaySize(mWindowManager); 16388 } 16389 16390 final long origId = Binder.clearCallingIdentity(); 16391 if (values != null) { 16392 Settings.System.clearConfiguration(values); 16393 } 16394 updateConfigurationLocked(values, null, false, false); 16395 Binder.restoreCallingIdentity(origId); 16396 } 16397 } 16398 16399 /** 16400 * Do either or both things: (1) change the current configuration, and (2) 16401 * make sure the given activity is running with the (now) current 16402 * configuration. Returns true if the activity has been left running, or 16403 * false if <var>starting</var> is being destroyed to match the new 16404 * configuration. 16405 * @param persistent TODO 16406 */ 16407 boolean updateConfigurationLocked(Configuration values, 16408 ActivityRecord starting, boolean persistent, boolean initLocale) { 16409 int changes = 0; 16410 16411 if (values != null) { 16412 Configuration newConfig = new Configuration(mConfiguration); 16413 changes = newConfig.updateFrom(values); 16414 if (changes != 0) { 16415 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16416 Slog.i(TAG, "Updating configuration to: " + values); 16417 } 16418 16419 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16420 16421 if (values.locale != null && !initLocale) { 16422 saveLocaleLocked(values.locale, 16423 !values.locale.equals(mConfiguration.locale), 16424 values.userSetLocale); 16425 } 16426 16427 mConfigurationSeq++; 16428 if (mConfigurationSeq <= 0) { 16429 mConfigurationSeq = 1; 16430 } 16431 newConfig.seq = mConfigurationSeq; 16432 mConfiguration = newConfig; 16433 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16434 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16435 //mUsageStatsService.noteStartConfig(newConfig); 16436 16437 final Configuration configCopy = new Configuration(mConfiguration); 16438 16439 // TODO: If our config changes, should we auto dismiss any currently 16440 // showing dialogs? 16441 mShowDialogs = shouldShowDialogs(newConfig); 16442 16443 AttributeCache ac = AttributeCache.instance(); 16444 if (ac != null) { 16445 ac.updateConfiguration(configCopy); 16446 } 16447 16448 // Make sure all resources in our process are updated 16449 // right now, so that anyone who is going to retrieve 16450 // resource values after we return will be sure to get 16451 // the new ones. This is especially important during 16452 // boot, where the first config change needs to guarantee 16453 // all resources have that config before following boot 16454 // code is executed. 16455 mSystemThread.applyConfigurationToResources(configCopy); 16456 16457 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16458 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16459 msg.obj = new Configuration(configCopy); 16460 mHandler.sendMessage(msg); 16461 } 16462 16463 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16464 ProcessRecord app = mLruProcesses.get(i); 16465 try { 16466 if (app.thread != null) { 16467 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16468 + app.processName + " new config " + mConfiguration); 16469 app.thread.scheduleConfigurationChanged(configCopy); 16470 } 16471 } catch (Exception e) { 16472 } 16473 } 16474 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16475 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16476 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16477 | Intent.FLAG_RECEIVER_FOREGROUND); 16478 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16479 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16480 Process.SYSTEM_UID, UserHandle.USER_ALL); 16481 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16482 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16483 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16484 broadcastIntentLocked(null, null, intent, 16485 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16486 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16487 } 16488 } 16489 } 16490 16491 boolean kept = true; 16492 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16493 // mainStack is null during startup. 16494 if (mainStack != null) { 16495 if (changes != 0 && starting == null) { 16496 // If the configuration changed, and the caller is not already 16497 // in the process of starting an activity, then find the top 16498 // activity to check if its configuration needs to change. 16499 starting = mainStack.topRunningActivityLocked(null); 16500 } 16501 16502 if (starting != null) { 16503 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16504 // And we need to make sure at this point that all other activities 16505 // are made visible with the correct configuration. 16506 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16507 } 16508 } 16509 16510 if (values != null && mWindowManager != null) { 16511 mWindowManager.setNewConfiguration(mConfiguration); 16512 } 16513 16514 return kept; 16515 } 16516 16517 /** 16518 * Decide based on the configuration whether we should shouw the ANR, 16519 * crash, etc dialogs. The idea is that if there is no affordnace to 16520 * press the on-screen buttons, we shouldn't show the dialog. 16521 * 16522 * A thought: SystemUI might also want to get told about this, the Power 16523 * dialog / global actions also might want different behaviors. 16524 */ 16525 private static final boolean shouldShowDialogs(Configuration config) { 16526 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16527 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16528 } 16529 16530 /** 16531 * Save the locale. You must be inside a synchronized (this) block. 16532 */ 16533 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16534 if(isDiff) { 16535 SystemProperties.set("user.language", l.getLanguage()); 16536 SystemProperties.set("user.region", l.getCountry()); 16537 } 16538 16539 if(isPersist) { 16540 SystemProperties.set("persist.sys.language", l.getLanguage()); 16541 SystemProperties.set("persist.sys.country", l.getCountry()); 16542 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16543 16544 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16545 } 16546 } 16547 16548 @Override 16549 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16550 synchronized (this) { 16551 ActivityRecord srec = ActivityRecord.forToken(token); 16552 if (srec.task != null && srec.task.stack != null) { 16553 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16554 } 16555 } 16556 return false; 16557 } 16558 16559 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16560 Intent resultData) { 16561 16562 synchronized (this) { 16563 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16564 if (stack != null) { 16565 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16566 } 16567 return false; 16568 } 16569 } 16570 16571 public int getLaunchedFromUid(IBinder activityToken) { 16572 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16573 if (srec == null) { 16574 return -1; 16575 } 16576 return srec.launchedFromUid; 16577 } 16578 16579 public String getLaunchedFromPackage(IBinder activityToken) { 16580 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16581 if (srec == null) { 16582 return null; 16583 } 16584 return srec.launchedFromPackage; 16585 } 16586 16587 // ========================================================= 16588 // LIFETIME MANAGEMENT 16589 // ========================================================= 16590 16591 // Returns which broadcast queue the app is the current [or imminent] receiver 16592 // on, or 'null' if the app is not an active broadcast recipient. 16593 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16594 BroadcastRecord r = app.curReceiver; 16595 if (r != null) { 16596 return r.queue; 16597 } 16598 16599 // It's not the current receiver, but it might be starting up to become one 16600 synchronized (this) { 16601 for (BroadcastQueue queue : mBroadcastQueues) { 16602 r = queue.mPendingBroadcast; 16603 if (r != null && r.curApp == app) { 16604 // found it; report which queue it's in 16605 return queue; 16606 } 16607 } 16608 } 16609 16610 return null; 16611 } 16612 16613 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16614 boolean doingAll, long now) { 16615 if (mAdjSeq == app.adjSeq) { 16616 // This adjustment has already been computed. 16617 return app.curRawAdj; 16618 } 16619 16620 if (app.thread == null) { 16621 app.adjSeq = mAdjSeq; 16622 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16623 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16624 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16625 } 16626 16627 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16628 app.adjSource = null; 16629 app.adjTarget = null; 16630 app.empty = false; 16631 app.cached = false; 16632 16633 final int activitiesSize = app.activities.size(); 16634 16635 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16636 // The max adjustment doesn't allow this app to be anything 16637 // below foreground, so it is not worth doing work for it. 16638 app.adjType = "fixed"; 16639 app.adjSeq = mAdjSeq; 16640 app.curRawAdj = app.maxAdj; 16641 app.foregroundActivities = false; 16642 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16643 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16644 // System processes can do UI, and when they do we want to have 16645 // them trim their memory after the user leaves the UI. To 16646 // facilitate this, here we need to determine whether or not it 16647 // is currently showing UI. 16648 app.systemNoUi = true; 16649 if (app == TOP_APP) { 16650 app.systemNoUi = false; 16651 } else if (activitiesSize > 0) { 16652 for (int j = 0; j < activitiesSize; j++) { 16653 final ActivityRecord r = app.activities.get(j); 16654 if (r.visible) { 16655 app.systemNoUi = false; 16656 } 16657 } 16658 } 16659 if (!app.systemNoUi) { 16660 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16661 } 16662 return (app.curAdj=app.maxAdj); 16663 } 16664 16665 app.systemNoUi = false; 16666 16667 // Determine the importance of the process, starting with most 16668 // important to least, and assign an appropriate OOM adjustment. 16669 int adj; 16670 int schedGroup; 16671 int procState; 16672 boolean foregroundActivities = false; 16673 BroadcastQueue queue; 16674 if (app == TOP_APP) { 16675 // The last app on the list is the foreground app. 16676 adj = ProcessList.FOREGROUND_APP_ADJ; 16677 schedGroup = Process.THREAD_GROUP_DEFAULT; 16678 app.adjType = "top-activity"; 16679 foregroundActivities = true; 16680 procState = ActivityManager.PROCESS_STATE_TOP; 16681 } else if (app.instrumentationClass != null) { 16682 // Don't want to kill running instrumentation. 16683 adj = ProcessList.FOREGROUND_APP_ADJ; 16684 schedGroup = Process.THREAD_GROUP_DEFAULT; 16685 app.adjType = "instrumentation"; 16686 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16687 } else if ((queue = isReceivingBroadcast(app)) != null) { 16688 // An app that is currently receiving a broadcast also 16689 // counts as being in the foreground for OOM killer purposes. 16690 // It's placed in a sched group based on the nature of the 16691 // broadcast as reflected by which queue it's active in. 16692 adj = ProcessList.FOREGROUND_APP_ADJ; 16693 schedGroup = (queue == mFgBroadcastQueue) 16694 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16695 app.adjType = "broadcast"; 16696 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16697 } else if (app.executingServices.size() > 0) { 16698 // An app that is currently executing a service callback also 16699 // counts as being in the foreground. 16700 adj = ProcessList.FOREGROUND_APP_ADJ; 16701 schedGroup = app.execServicesFg ? 16702 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16703 app.adjType = "exec-service"; 16704 procState = ActivityManager.PROCESS_STATE_SERVICE; 16705 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16706 } else { 16707 // As far as we know the process is empty. We may change our mind later. 16708 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16709 // At this point we don't actually know the adjustment. Use the cached adj 16710 // value that the caller wants us to. 16711 adj = cachedAdj; 16712 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16713 app.cached = true; 16714 app.empty = true; 16715 app.adjType = "cch-empty"; 16716 } 16717 16718 // Examine all activities if not already foreground. 16719 if (!foregroundActivities && activitiesSize > 0) { 16720 for (int j = 0; j < activitiesSize; j++) { 16721 final ActivityRecord r = app.activities.get(j); 16722 if (r.app != app) { 16723 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16724 + app + "?!?"); 16725 continue; 16726 } 16727 if (r.visible) { 16728 // App has a visible activity; only upgrade adjustment. 16729 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16730 adj = ProcessList.VISIBLE_APP_ADJ; 16731 app.adjType = "visible"; 16732 } 16733 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16734 procState = ActivityManager.PROCESS_STATE_TOP; 16735 } 16736 schedGroup = Process.THREAD_GROUP_DEFAULT; 16737 app.cached = false; 16738 app.empty = false; 16739 foregroundActivities = true; 16740 break; 16741 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16742 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16743 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16744 app.adjType = "pausing"; 16745 } 16746 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16747 procState = ActivityManager.PROCESS_STATE_TOP; 16748 } 16749 schedGroup = Process.THREAD_GROUP_DEFAULT; 16750 app.cached = false; 16751 app.empty = false; 16752 foregroundActivities = true; 16753 } else if (r.state == ActivityState.STOPPING) { 16754 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16755 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16756 app.adjType = "stopping"; 16757 } 16758 // For the process state, we will at this point consider the 16759 // process to be cached. It will be cached either as an activity 16760 // or empty depending on whether the activity is finishing. We do 16761 // this so that we can treat the process as cached for purposes of 16762 // memory trimming (determing current memory level, trim command to 16763 // send to process) since there can be an arbitrary number of stopping 16764 // processes and they should soon all go into the cached state. 16765 if (!r.finishing) { 16766 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16767 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16768 } 16769 } 16770 app.cached = false; 16771 app.empty = false; 16772 foregroundActivities = true; 16773 } else { 16774 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16775 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16776 app.adjType = "cch-act"; 16777 } 16778 } 16779 } 16780 } 16781 16782 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16783 if (app.foregroundServices) { 16784 // The user is aware of this app, so make it visible. 16785 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16786 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16787 app.cached = false; 16788 app.adjType = "fg-service"; 16789 schedGroup = Process.THREAD_GROUP_DEFAULT; 16790 } else if (app.forcingToForeground != null) { 16791 // The user is aware of this app, so make it visible. 16792 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16793 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16794 app.cached = false; 16795 app.adjType = "force-fg"; 16796 app.adjSource = app.forcingToForeground; 16797 schedGroup = Process.THREAD_GROUP_DEFAULT; 16798 } 16799 } 16800 16801 if (app == mHeavyWeightProcess) { 16802 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16803 // We don't want to kill the current heavy-weight process. 16804 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16805 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16806 app.cached = false; 16807 app.adjType = "heavy"; 16808 } 16809 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16810 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16811 } 16812 } 16813 16814 if (app == mHomeProcess) { 16815 if (adj > ProcessList.HOME_APP_ADJ) { 16816 // This process is hosting what we currently consider to be the 16817 // home app, so we don't want to let it go into the background. 16818 adj = ProcessList.HOME_APP_ADJ; 16819 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16820 app.cached = false; 16821 app.adjType = "home"; 16822 } 16823 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16824 procState = ActivityManager.PROCESS_STATE_HOME; 16825 } 16826 } 16827 16828 if (app == mPreviousProcess && app.activities.size() > 0) { 16829 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16830 // This was the previous process that showed UI to the user. 16831 // We want to try to keep it around more aggressively, to give 16832 // a good experience around switching between two apps. 16833 adj = ProcessList.PREVIOUS_APP_ADJ; 16834 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16835 app.cached = false; 16836 app.adjType = "previous"; 16837 } 16838 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16839 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16840 } 16841 } 16842 16843 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16844 + " reason=" + app.adjType); 16845 16846 // By default, we use the computed adjustment. It may be changed if 16847 // there are applications dependent on our services or providers, but 16848 // this gives us a baseline and makes sure we don't get into an 16849 // infinite recursion. 16850 app.adjSeq = mAdjSeq; 16851 app.curRawAdj = adj; 16852 app.hasStartedServices = false; 16853 16854 if (mBackupTarget != null && app == mBackupTarget.app) { 16855 // If possible we want to avoid killing apps while they're being backed up 16856 if (adj > ProcessList.BACKUP_APP_ADJ) { 16857 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16858 adj = ProcessList.BACKUP_APP_ADJ; 16859 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16860 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16861 } 16862 app.adjType = "backup"; 16863 app.cached = false; 16864 } 16865 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16866 procState = ActivityManager.PROCESS_STATE_BACKUP; 16867 } 16868 } 16869 16870 boolean mayBeTop = false; 16871 16872 for (int is = app.services.size()-1; 16873 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16874 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16875 || procState > ActivityManager.PROCESS_STATE_TOP); 16876 is--) { 16877 ServiceRecord s = app.services.valueAt(is); 16878 if (s.startRequested) { 16879 app.hasStartedServices = true; 16880 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16881 procState = ActivityManager.PROCESS_STATE_SERVICE; 16882 } 16883 if (app.hasShownUi && app != mHomeProcess) { 16884 // If this process has shown some UI, let it immediately 16885 // go to the LRU list because it may be pretty heavy with 16886 // UI stuff. We'll tag it with a label just to help 16887 // debug and understand what is going on. 16888 if (adj > ProcessList.SERVICE_ADJ) { 16889 app.adjType = "cch-started-ui-services"; 16890 } 16891 } else { 16892 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16893 // This service has seen some activity within 16894 // recent memory, so we will keep its process ahead 16895 // of the background processes. 16896 if (adj > ProcessList.SERVICE_ADJ) { 16897 adj = ProcessList.SERVICE_ADJ; 16898 app.adjType = "started-services"; 16899 app.cached = false; 16900 } 16901 } 16902 // If we have let the service slide into the background 16903 // state, still have some text describing what it is doing 16904 // even though the service no longer has an impact. 16905 if (adj > ProcessList.SERVICE_ADJ) { 16906 app.adjType = "cch-started-services"; 16907 } 16908 } 16909 } 16910 for (int conni = s.connections.size()-1; 16911 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16912 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16913 || procState > ActivityManager.PROCESS_STATE_TOP); 16914 conni--) { 16915 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16916 for (int i = 0; 16917 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16918 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16919 || procState > ActivityManager.PROCESS_STATE_TOP); 16920 i++) { 16921 // XXX should compute this based on the max of 16922 // all connected clients. 16923 ConnectionRecord cr = clist.get(i); 16924 if (cr.binding.client == app) { 16925 // Binding to ourself is not interesting. 16926 continue; 16927 } 16928 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16929 ProcessRecord client = cr.binding.client; 16930 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16931 TOP_APP, doingAll, now); 16932 int clientProcState = client.curProcState; 16933 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16934 // If the other app is cached for any reason, for purposes here 16935 // we are going to consider it empty. The specific cached state 16936 // doesn't propagate except under certain conditions. 16937 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16938 } 16939 String adjType = null; 16940 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16941 // Not doing bind OOM management, so treat 16942 // this guy more like a started service. 16943 if (app.hasShownUi && app != mHomeProcess) { 16944 // If this process has shown some UI, let it immediately 16945 // go to the LRU list because it may be pretty heavy with 16946 // UI stuff. We'll tag it with a label just to help 16947 // debug and understand what is going on. 16948 if (adj > clientAdj) { 16949 adjType = "cch-bound-ui-services"; 16950 } 16951 app.cached = false; 16952 clientAdj = adj; 16953 clientProcState = procState; 16954 } else { 16955 if (now >= (s.lastActivity 16956 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16957 // This service has not seen activity within 16958 // recent memory, so allow it to drop to the 16959 // LRU list if there is no other reason to keep 16960 // it around. We'll also tag it with a label just 16961 // to help debug and undertand what is going on. 16962 if (adj > clientAdj) { 16963 adjType = "cch-bound-services"; 16964 } 16965 clientAdj = adj; 16966 } 16967 } 16968 } 16969 if (adj > clientAdj) { 16970 // If this process has recently shown UI, and 16971 // the process that is binding to it is less 16972 // important than being visible, then we don't 16973 // care about the binding as much as we care 16974 // about letting this process get into the LRU 16975 // list to be killed and restarted if needed for 16976 // memory. 16977 if (app.hasShownUi && app != mHomeProcess 16978 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16979 adjType = "cch-bound-ui-services"; 16980 } else { 16981 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16982 |Context.BIND_IMPORTANT)) != 0) { 16983 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16984 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16985 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16986 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16987 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16988 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16989 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16990 adj = clientAdj; 16991 } else { 16992 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16993 adj = ProcessList.VISIBLE_APP_ADJ; 16994 } 16995 } 16996 if (!client.cached) { 16997 app.cached = false; 16998 } 16999 adjType = "service"; 17000 } 17001 } 17002 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17003 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17004 schedGroup = Process.THREAD_GROUP_DEFAULT; 17005 } 17006 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17007 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17008 // Special handling of clients who are in the top state. 17009 // We *may* want to consider this process to be in the 17010 // top state as well, but only if there is not another 17011 // reason for it to be running. Being on the top is a 17012 // special state, meaning you are specifically running 17013 // for the current top app. If the process is already 17014 // running in the background for some other reason, it 17015 // is more important to continue considering it to be 17016 // in the background state. 17017 mayBeTop = true; 17018 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17019 } else { 17020 // Special handling for above-top states (persistent 17021 // processes). These should not bring the current process 17022 // into the top state, since they are not on top. Instead 17023 // give them the best state after that. 17024 clientProcState = 17025 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17026 } 17027 } 17028 } else { 17029 if (clientProcState < 17030 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17031 clientProcState = 17032 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17033 } 17034 } 17035 if (procState > clientProcState) { 17036 procState = clientProcState; 17037 } 17038 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17039 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17040 app.pendingUiClean = true; 17041 } 17042 if (adjType != null) { 17043 app.adjType = adjType; 17044 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17045 .REASON_SERVICE_IN_USE; 17046 app.adjSource = cr.binding.client; 17047 app.adjSourceProcState = clientProcState; 17048 app.adjTarget = s.name; 17049 } 17050 } 17051 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17052 app.treatLikeActivity = true; 17053 } 17054 final ActivityRecord a = cr.activity; 17055 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17056 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17057 (a.visible || a.state == ActivityState.RESUMED 17058 || a.state == ActivityState.PAUSING)) { 17059 adj = ProcessList.FOREGROUND_APP_ADJ; 17060 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17061 schedGroup = Process.THREAD_GROUP_DEFAULT; 17062 } 17063 app.cached = false; 17064 app.adjType = "service"; 17065 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17066 .REASON_SERVICE_IN_USE; 17067 app.adjSource = a; 17068 app.adjSourceProcState = procState; 17069 app.adjTarget = s.name; 17070 } 17071 } 17072 } 17073 } 17074 } 17075 17076 for (int provi = app.pubProviders.size()-1; 17077 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17078 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17079 || procState > ActivityManager.PROCESS_STATE_TOP); 17080 provi--) { 17081 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17082 for (int i = cpr.connections.size()-1; 17083 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17084 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17085 || procState > ActivityManager.PROCESS_STATE_TOP); 17086 i--) { 17087 ContentProviderConnection conn = cpr.connections.get(i); 17088 ProcessRecord client = conn.client; 17089 if (client == app) { 17090 // Being our own client is not interesting. 17091 continue; 17092 } 17093 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17094 int clientProcState = client.curProcState; 17095 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17096 // If the other app is cached for any reason, for purposes here 17097 // we are going to consider it empty. 17098 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17099 } 17100 if (adj > clientAdj) { 17101 if (app.hasShownUi && app != mHomeProcess 17102 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17103 app.adjType = "cch-ui-provider"; 17104 } else { 17105 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17106 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17107 app.adjType = "provider"; 17108 } 17109 app.cached &= client.cached; 17110 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17111 .REASON_PROVIDER_IN_USE; 17112 app.adjSource = client; 17113 app.adjSourceProcState = clientProcState; 17114 app.adjTarget = cpr.name; 17115 } 17116 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17117 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17118 // Special handling of clients who are in the top state. 17119 // We *may* want to consider this process to be in the 17120 // top state as well, but only if there is not another 17121 // reason for it to be running. Being on the top is a 17122 // special state, meaning you are specifically running 17123 // for the current top app. If the process is already 17124 // running in the background for some other reason, it 17125 // is more important to continue considering it to be 17126 // in the background state. 17127 mayBeTop = true; 17128 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17129 } else { 17130 // Special handling for above-top states (persistent 17131 // processes). These should not bring the current process 17132 // into the top state, since they are not on top. Instead 17133 // give them the best state after that. 17134 clientProcState = 17135 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17136 } 17137 } 17138 if (procState > clientProcState) { 17139 procState = clientProcState; 17140 } 17141 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17142 schedGroup = Process.THREAD_GROUP_DEFAULT; 17143 } 17144 } 17145 // If the provider has external (non-framework) process 17146 // dependencies, ensure that its adjustment is at least 17147 // FOREGROUND_APP_ADJ. 17148 if (cpr.hasExternalProcessHandles()) { 17149 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17150 adj = ProcessList.FOREGROUND_APP_ADJ; 17151 schedGroup = Process.THREAD_GROUP_DEFAULT; 17152 app.cached = false; 17153 app.adjType = "provider"; 17154 app.adjTarget = cpr.name; 17155 } 17156 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17157 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17158 } 17159 } 17160 } 17161 17162 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17163 // A client of one of our services or providers is in the top state. We 17164 // *may* want to be in the top state, but not if we are already running in 17165 // the background for some other reason. For the decision here, we are going 17166 // to pick out a few specific states that we want to remain in when a client 17167 // is top (states that tend to be longer-term) and otherwise allow it to go 17168 // to the top state. 17169 switch (procState) { 17170 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17171 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17172 case ActivityManager.PROCESS_STATE_SERVICE: 17173 // These all are longer-term states, so pull them up to the top 17174 // of the background states, but not all the way to the top state. 17175 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17176 break; 17177 default: 17178 // Otherwise, top is a better choice, so take it. 17179 procState = ActivityManager.PROCESS_STATE_TOP; 17180 break; 17181 } 17182 } 17183 17184 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17185 if (app.hasClientActivities) { 17186 // This is a cached process, but with client activities. Mark it so. 17187 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17188 app.adjType = "cch-client-act"; 17189 } else if (app.treatLikeActivity) { 17190 // This is a cached process, but somebody wants us to treat it like it has 17191 // an activity, okay! 17192 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17193 app.adjType = "cch-as-act"; 17194 } 17195 } 17196 17197 if (adj == ProcessList.SERVICE_ADJ) { 17198 if (doingAll) { 17199 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17200 mNewNumServiceProcs++; 17201 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17202 if (!app.serviceb) { 17203 // This service isn't far enough down on the LRU list to 17204 // normally be a B service, but if we are low on RAM and it 17205 // is large we want to force it down since we would prefer to 17206 // keep launcher over it. 17207 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17208 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17209 app.serviceHighRam = true; 17210 app.serviceb = true; 17211 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17212 } else { 17213 mNewNumAServiceProcs++; 17214 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17215 } 17216 } else { 17217 app.serviceHighRam = false; 17218 } 17219 } 17220 if (app.serviceb) { 17221 adj = ProcessList.SERVICE_B_ADJ; 17222 } 17223 } 17224 17225 app.curRawAdj = adj; 17226 17227 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17228 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17229 if (adj > app.maxAdj) { 17230 adj = app.maxAdj; 17231 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17232 schedGroup = Process.THREAD_GROUP_DEFAULT; 17233 } 17234 } 17235 17236 // Do final modification to adj. Everything we do between here and applying 17237 // the final setAdj must be done in this function, because we will also use 17238 // it when computing the final cached adj later. Note that we don't need to 17239 // worry about this for max adj above, since max adj will always be used to 17240 // keep it out of the cached vaues. 17241 app.curAdj = app.modifyRawOomAdj(adj); 17242 app.curSchedGroup = schedGroup; 17243 app.curProcState = procState; 17244 app.foregroundActivities = foregroundActivities; 17245 17246 return app.curRawAdj; 17247 } 17248 17249 /** 17250 * Schedule PSS collection of a process. 17251 */ 17252 void requestPssLocked(ProcessRecord proc, int procState) { 17253 if (mPendingPssProcesses.contains(proc)) { 17254 return; 17255 } 17256 if (mPendingPssProcesses.size() == 0) { 17257 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17258 } 17259 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17260 proc.pssProcState = procState; 17261 mPendingPssProcesses.add(proc); 17262 } 17263 17264 /** 17265 * Schedule PSS collection of all processes. 17266 */ 17267 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17268 if (!always) { 17269 if (now < (mLastFullPssTime + 17270 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17271 return; 17272 } 17273 } 17274 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17275 mLastFullPssTime = now; 17276 mFullPssPending = true; 17277 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17278 mPendingPssProcesses.clear(); 17279 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17280 ProcessRecord app = mLruProcesses.get(i); 17281 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17282 app.pssProcState = app.setProcState; 17283 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17284 isSleeping(), now); 17285 mPendingPssProcesses.add(app); 17286 } 17287 } 17288 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17289 } 17290 17291 /** 17292 * Ask a given process to GC right now. 17293 */ 17294 final void performAppGcLocked(ProcessRecord app) { 17295 try { 17296 app.lastRequestedGc = SystemClock.uptimeMillis(); 17297 if (app.thread != null) { 17298 if (app.reportLowMemory) { 17299 app.reportLowMemory = false; 17300 app.thread.scheduleLowMemory(); 17301 } else { 17302 app.thread.processInBackground(); 17303 } 17304 } 17305 } catch (Exception e) { 17306 // whatever. 17307 } 17308 } 17309 17310 /** 17311 * Returns true if things are idle enough to perform GCs. 17312 */ 17313 private final boolean canGcNowLocked() { 17314 boolean processingBroadcasts = false; 17315 for (BroadcastQueue q : mBroadcastQueues) { 17316 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17317 processingBroadcasts = true; 17318 } 17319 } 17320 return !processingBroadcasts 17321 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17322 } 17323 17324 /** 17325 * Perform GCs on all processes that are waiting for it, but only 17326 * if things are idle. 17327 */ 17328 final void performAppGcsLocked() { 17329 final int N = mProcessesToGc.size(); 17330 if (N <= 0) { 17331 return; 17332 } 17333 if (canGcNowLocked()) { 17334 while (mProcessesToGc.size() > 0) { 17335 ProcessRecord proc = mProcessesToGc.remove(0); 17336 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17337 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17338 <= SystemClock.uptimeMillis()) { 17339 // To avoid spamming the system, we will GC processes one 17340 // at a time, waiting a few seconds between each. 17341 performAppGcLocked(proc); 17342 scheduleAppGcsLocked(); 17343 return; 17344 } else { 17345 // It hasn't been long enough since we last GCed this 17346 // process... put it in the list to wait for its time. 17347 addProcessToGcListLocked(proc); 17348 break; 17349 } 17350 } 17351 } 17352 17353 scheduleAppGcsLocked(); 17354 } 17355 } 17356 17357 /** 17358 * If all looks good, perform GCs on all processes waiting for them. 17359 */ 17360 final void performAppGcsIfAppropriateLocked() { 17361 if (canGcNowLocked()) { 17362 performAppGcsLocked(); 17363 return; 17364 } 17365 // Still not idle, wait some more. 17366 scheduleAppGcsLocked(); 17367 } 17368 17369 /** 17370 * Schedule the execution of all pending app GCs. 17371 */ 17372 final void scheduleAppGcsLocked() { 17373 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17374 17375 if (mProcessesToGc.size() > 0) { 17376 // Schedule a GC for the time to the next process. 17377 ProcessRecord proc = mProcessesToGc.get(0); 17378 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17379 17380 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17381 long now = SystemClock.uptimeMillis(); 17382 if (when < (now+GC_TIMEOUT)) { 17383 when = now + GC_TIMEOUT; 17384 } 17385 mHandler.sendMessageAtTime(msg, when); 17386 } 17387 } 17388 17389 /** 17390 * Add a process to the array of processes waiting to be GCed. Keeps the 17391 * list in sorted order by the last GC time. The process can't already be 17392 * on the list. 17393 */ 17394 final void addProcessToGcListLocked(ProcessRecord proc) { 17395 boolean added = false; 17396 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17397 if (mProcessesToGc.get(i).lastRequestedGc < 17398 proc.lastRequestedGc) { 17399 added = true; 17400 mProcessesToGc.add(i+1, proc); 17401 break; 17402 } 17403 } 17404 if (!added) { 17405 mProcessesToGc.add(0, proc); 17406 } 17407 } 17408 17409 /** 17410 * Set up to ask a process to GC itself. This will either do it 17411 * immediately, or put it on the list of processes to gc the next 17412 * time things are idle. 17413 */ 17414 final void scheduleAppGcLocked(ProcessRecord app) { 17415 long now = SystemClock.uptimeMillis(); 17416 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17417 return; 17418 } 17419 if (!mProcessesToGc.contains(app)) { 17420 addProcessToGcListLocked(app); 17421 scheduleAppGcsLocked(); 17422 } 17423 } 17424 17425 final void checkExcessivePowerUsageLocked(boolean doKills) { 17426 updateCpuStatsNow(); 17427 17428 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17429 boolean doWakeKills = doKills; 17430 boolean doCpuKills = doKills; 17431 if (mLastPowerCheckRealtime == 0) { 17432 doWakeKills = false; 17433 } 17434 if (mLastPowerCheckUptime == 0) { 17435 doCpuKills = false; 17436 } 17437 if (stats.isScreenOn()) { 17438 doWakeKills = false; 17439 } 17440 final long curRealtime = SystemClock.elapsedRealtime(); 17441 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17442 final long curUptime = SystemClock.uptimeMillis(); 17443 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17444 mLastPowerCheckRealtime = curRealtime; 17445 mLastPowerCheckUptime = curUptime; 17446 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17447 doWakeKills = false; 17448 } 17449 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17450 doCpuKills = false; 17451 } 17452 int i = mLruProcesses.size(); 17453 while (i > 0) { 17454 i--; 17455 ProcessRecord app = mLruProcesses.get(i); 17456 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17457 long wtime; 17458 synchronized (stats) { 17459 wtime = stats.getProcessWakeTime(app.info.uid, 17460 app.pid, curRealtime); 17461 } 17462 long wtimeUsed = wtime - app.lastWakeTime; 17463 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17464 if (DEBUG_POWER) { 17465 StringBuilder sb = new StringBuilder(128); 17466 sb.append("Wake for "); 17467 app.toShortString(sb); 17468 sb.append(": over "); 17469 TimeUtils.formatDuration(realtimeSince, sb); 17470 sb.append(" used "); 17471 TimeUtils.formatDuration(wtimeUsed, sb); 17472 sb.append(" ("); 17473 sb.append((wtimeUsed*100)/realtimeSince); 17474 sb.append("%)"); 17475 Slog.i(TAG, sb.toString()); 17476 sb.setLength(0); 17477 sb.append("CPU for "); 17478 app.toShortString(sb); 17479 sb.append(": over "); 17480 TimeUtils.formatDuration(uptimeSince, sb); 17481 sb.append(" used "); 17482 TimeUtils.formatDuration(cputimeUsed, sb); 17483 sb.append(" ("); 17484 sb.append((cputimeUsed*100)/uptimeSince); 17485 sb.append("%)"); 17486 Slog.i(TAG, sb.toString()); 17487 } 17488 // If a process has held a wake lock for more 17489 // than 50% of the time during this period, 17490 // that sounds bad. Kill! 17491 if (doWakeKills && realtimeSince > 0 17492 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17493 synchronized (stats) { 17494 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17495 realtimeSince, wtimeUsed); 17496 } 17497 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17498 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17499 } else if (doCpuKills && uptimeSince > 0 17500 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17501 synchronized (stats) { 17502 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17503 uptimeSince, cputimeUsed); 17504 } 17505 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17506 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17507 } else { 17508 app.lastWakeTime = wtime; 17509 app.lastCpuTime = app.curCpuTime; 17510 } 17511 } 17512 } 17513 } 17514 17515 private final boolean applyOomAdjLocked(ProcessRecord app, 17516 ProcessRecord TOP_APP, boolean doingAll, long now) { 17517 boolean success = true; 17518 17519 if (app.curRawAdj != app.setRawAdj) { 17520 app.setRawAdj = app.curRawAdj; 17521 } 17522 17523 int changes = 0; 17524 17525 if (app.curAdj != app.setAdj) { 17526 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17527 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17528 TAG, "Set " + app.pid + " " + app.processName + 17529 " adj " + app.curAdj + ": " + app.adjType); 17530 app.setAdj = app.curAdj; 17531 } 17532 17533 if (app.setSchedGroup != app.curSchedGroup) { 17534 app.setSchedGroup = app.curSchedGroup; 17535 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17536 "Setting process group of " + app.processName 17537 + " to " + app.curSchedGroup); 17538 if (app.waitingToKill != null && 17539 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17540 app.kill(app.waitingToKill, true); 17541 success = false; 17542 } else { 17543 if (true) { 17544 long oldId = Binder.clearCallingIdentity(); 17545 try { 17546 Process.setProcessGroup(app.pid, app.curSchedGroup); 17547 } catch (Exception e) { 17548 Slog.w(TAG, "Failed setting process group of " + app.pid 17549 + " to " + app.curSchedGroup); 17550 e.printStackTrace(); 17551 } finally { 17552 Binder.restoreCallingIdentity(oldId); 17553 } 17554 } else { 17555 if (app.thread != null) { 17556 try { 17557 app.thread.setSchedulingGroup(app.curSchedGroup); 17558 } catch (RemoteException e) { 17559 } 17560 } 17561 } 17562 Process.setSwappiness(app.pid, 17563 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17564 } 17565 } 17566 if (app.repForegroundActivities != app.foregroundActivities) { 17567 app.repForegroundActivities = app.foregroundActivities; 17568 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17569 } 17570 if (app.repProcState != app.curProcState) { 17571 app.repProcState = app.curProcState; 17572 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17573 if (app.thread != null) { 17574 try { 17575 if (false) { 17576 //RuntimeException h = new RuntimeException("here"); 17577 Slog.i(TAG, "Sending new process state " + app.repProcState 17578 + " to " + app /*, h*/); 17579 } 17580 app.thread.setProcessState(app.repProcState); 17581 } catch (RemoteException e) { 17582 } 17583 } 17584 } 17585 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17586 app.setProcState)) { 17587 app.lastStateTime = now; 17588 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17589 isSleeping(), now); 17590 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17591 + ProcessList.makeProcStateString(app.setProcState) + " to " 17592 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17593 + (app.nextPssTime-now) + ": " + app); 17594 } else { 17595 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17596 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17597 requestPssLocked(app, app.setProcState); 17598 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17599 isSleeping(), now); 17600 } else if (false && DEBUG_PSS) { 17601 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17602 } 17603 } 17604 if (app.setProcState != app.curProcState) { 17605 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17606 "Proc state change of " + app.processName 17607 + " to " + app.curProcState); 17608 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17609 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17610 if (setImportant && !curImportant) { 17611 // This app is no longer something we consider important enough to allow to 17612 // use arbitrary amounts of battery power. Note 17613 // its current wake lock time to later know to kill it if 17614 // it is not behaving well. 17615 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17616 synchronized (stats) { 17617 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17618 app.pid, SystemClock.elapsedRealtime()); 17619 } 17620 app.lastCpuTime = app.curCpuTime; 17621 17622 } 17623 app.setProcState = app.curProcState; 17624 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17625 app.notCachedSinceIdle = false; 17626 } 17627 if (!doingAll) { 17628 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17629 } else { 17630 app.procStateChanged = true; 17631 } 17632 } 17633 17634 if (changes != 0) { 17635 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17636 int i = mPendingProcessChanges.size()-1; 17637 ProcessChangeItem item = null; 17638 while (i >= 0) { 17639 item = mPendingProcessChanges.get(i); 17640 if (item.pid == app.pid) { 17641 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17642 break; 17643 } 17644 i--; 17645 } 17646 if (i < 0) { 17647 // No existing item in pending changes; need a new one. 17648 final int NA = mAvailProcessChanges.size(); 17649 if (NA > 0) { 17650 item = mAvailProcessChanges.remove(NA-1); 17651 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17652 } else { 17653 item = new ProcessChangeItem(); 17654 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17655 } 17656 item.changes = 0; 17657 item.pid = app.pid; 17658 item.uid = app.info.uid; 17659 if (mPendingProcessChanges.size() == 0) { 17660 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17661 "*** Enqueueing dispatch processes changed!"); 17662 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17663 } 17664 mPendingProcessChanges.add(item); 17665 } 17666 item.changes |= changes; 17667 item.processState = app.repProcState; 17668 item.foregroundActivities = app.repForegroundActivities; 17669 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17670 + Integer.toHexString(System.identityHashCode(item)) 17671 + " " + app.toShortString() + ": changes=" + item.changes 17672 + " procState=" + item.processState 17673 + " foreground=" + item.foregroundActivities 17674 + " type=" + app.adjType + " source=" + app.adjSource 17675 + " target=" + app.adjTarget); 17676 } 17677 17678 return success; 17679 } 17680 17681 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17682 if (proc.thread != null) { 17683 if (proc.baseProcessTracker != null) { 17684 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17685 } 17686 if (proc.repProcState >= 0) { 17687 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17688 proc.repProcState); 17689 } 17690 } 17691 } 17692 17693 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17694 ProcessRecord TOP_APP, boolean doingAll, long now) { 17695 if (app.thread == null) { 17696 return false; 17697 } 17698 17699 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17700 17701 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17702 } 17703 17704 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17705 boolean oomAdj) { 17706 if (isForeground != proc.foregroundServices) { 17707 proc.foregroundServices = isForeground; 17708 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17709 proc.info.uid); 17710 if (isForeground) { 17711 if (curProcs == null) { 17712 curProcs = new ArrayList<ProcessRecord>(); 17713 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17714 } 17715 if (!curProcs.contains(proc)) { 17716 curProcs.add(proc); 17717 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17718 proc.info.packageName, proc.info.uid); 17719 } 17720 } else { 17721 if (curProcs != null) { 17722 if (curProcs.remove(proc)) { 17723 mBatteryStatsService.noteEvent( 17724 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17725 proc.info.packageName, proc.info.uid); 17726 if (curProcs.size() <= 0) { 17727 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17728 } 17729 } 17730 } 17731 } 17732 if (oomAdj) { 17733 updateOomAdjLocked(); 17734 } 17735 } 17736 } 17737 17738 private final ActivityRecord resumedAppLocked() { 17739 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17740 String pkg; 17741 int uid; 17742 if (act != null) { 17743 pkg = act.packageName; 17744 uid = act.info.applicationInfo.uid; 17745 } else { 17746 pkg = null; 17747 uid = -1; 17748 } 17749 // Has the UID or resumed package name changed? 17750 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17751 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17752 if (mCurResumedPackage != null) { 17753 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17754 mCurResumedPackage, mCurResumedUid); 17755 } 17756 mCurResumedPackage = pkg; 17757 mCurResumedUid = uid; 17758 if (mCurResumedPackage != null) { 17759 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17760 mCurResumedPackage, mCurResumedUid); 17761 } 17762 } 17763 return act; 17764 } 17765 17766 final boolean updateOomAdjLocked(ProcessRecord app) { 17767 final ActivityRecord TOP_ACT = resumedAppLocked(); 17768 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17769 final boolean wasCached = app.cached; 17770 17771 mAdjSeq++; 17772 17773 // This is the desired cached adjusment we want to tell it to use. 17774 // If our app is currently cached, we know it, and that is it. Otherwise, 17775 // we don't know it yet, and it needs to now be cached we will then 17776 // need to do a complete oom adj. 17777 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17778 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17779 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17780 SystemClock.uptimeMillis()); 17781 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17782 // Changed to/from cached state, so apps after it in the LRU 17783 // list may also be changed. 17784 updateOomAdjLocked(); 17785 } 17786 return success; 17787 } 17788 17789 final void updateOomAdjLocked() { 17790 final ActivityRecord TOP_ACT = resumedAppLocked(); 17791 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17792 final long now = SystemClock.uptimeMillis(); 17793 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17794 final int N = mLruProcesses.size(); 17795 17796 if (false) { 17797 RuntimeException e = new RuntimeException(); 17798 e.fillInStackTrace(); 17799 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17800 } 17801 17802 mAdjSeq++; 17803 mNewNumServiceProcs = 0; 17804 mNewNumAServiceProcs = 0; 17805 17806 final int emptyProcessLimit; 17807 final int cachedProcessLimit; 17808 if (mProcessLimit <= 0) { 17809 emptyProcessLimit = cachedProcessLimit = 0; 17810 } else if (mProcessLimit == 1) { 17811 emptyProcessLimit = 1; 17812 cachedProcessLimit = 0; 17813 } else { 17814 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17815 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17816 } 17817 17818 // Let's determine how many processes we have running vs. 17819 // how many slots we have for background processes; we may want 17820 // to put multiple processes in a slot of there are enough of 17821 // them. 17822 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17823 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17824 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17825 if (numEmptyProcs > cachedProcessLimit) { 17826 // If there are more empty processes than our limit on cached 17827 // processes, then use the cached process limit for the factor. 17828 // This ensures that the really old empty processes get pushed 17829 // down to the bottom, so if we are running low on memory we will 17830 // have a better chance at keeping around more cached processes 17831 // instead of a gazillion empty processes. 17832 numEmptyProcs = cachedProcessLimit; 17833 } 17834 int emptyFactor = numEmptyProcs/numSlots; 17835 if (emptyFactor < 1) emptyFactor = 1; 17836 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17837 if (cachedFactor < 1) cachedFactor = 1; 17838 int stepCached = 0; 17839 int stepEmpty = 0; 17840 int numCached = 0; 17841 int numEmpty = 0; 17842 int numTrimming = 0; 17843 17844 mNumNonCachedProcs = 0; 17845 mNumCachedHiddenProcs = 0; 17846 17847 // First update the OOM adjustment for each of the 17848 // application processes based on their current state. 17849 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17850 int nextCachedAdj = curCachedAdj+1; 17851 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17852 int nextEmptyAdj = curEmptyAdj+2; 17853 for (int i=N-1; i>=0; i--) { 17854 ProcessRecord app = mLruProcesses.get(i); 17855 if (!app.killedByAm && app.thread != null) { 17856 app.procStateChanged = false; 17857 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17858 17859 // If we haven't yet assigned the final cached adj 17860 // to the process, do that now. 17861 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17862 switch (app.curProcState) { 17863 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17864 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17865 // This process is a cached process holding activities... 17866 // assign it the next cached value for that type, and then 17867 // step that cached level. 17868 app.curRawAdj = curCachedAdj; 17869 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17870 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17871 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17872 + ")"); 17873 if (curCachedAdj != nextCachedAdj) { 17874 stepCached++; 17875 if (stepCached >= cachedFactor) { 17876 stepCached = 0; 17877 curCachedAdj = nextCachedAdj; 17878 nextCachedAdj += 2; 17879 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17880 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17881 } 17882 } 17883 } 17884 break; 17885 default: 17886 // For everything else, assign next empty cached process 17887 // level and bump that up. Note that this means that 17888 // long-running services that have dropped down to the 17889 // cached level will be treated as empty (since their process 17890 // state is still as a service), which is what we want. 17891 app.curRawAdj = curEmptyAdj; 17892 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17893 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17894 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17895 + ")"); 17896 if (curEmptyAdj != nextEmptyAdj) { 17897 stepEmpty++; 17898 if (stepEmpty >= emptyFactor) { 17899 stepEmpty = 0; 17900 curEmptyAdj = nextEmptyAdj; 17901 nextEmptyAdj += 2; 17902 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17903 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17904 } 17905 } 17906 } 17907 break; 17908 } 17909 } 17910 17911 applyOomAdjLocked(app, TOP_APP, true, now); 17912 17913 // Count the number of process types. 17914 switch (app.curProcState) { 17915 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17916 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17917 mNumCachedHiddenProcs++; 17918 numCached++; 17919 if (numCached > cachedProcessLimit) { 17920 app.kill("cached #" + numCached, true); 17921 } 17922 break; 17923 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17924 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17925 && app.lastActivityTime < oldTime) { 17926 app.kill("empty for " 17927 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17928 / 1000) + "s", true); 17929 } else { 17930 numEmpty++; 17931 if (numEmpty > emptyProcessLimit) { 17932 app.kill("empty #" + numEmpty, true); 17933 } 17934 } 17935 break; 17936 default: 17937 mNumNonCachedProcs++; 17938 break; 17939 } 17940 17941 if (app.isolated && app.services.size() <= 0) { 17942 // If this is an isolated process, and there are no 17943 // services running in it, then the process is no longer 17944 // needed. We agressively kill these because we can by 17945 // definition not re-use the same process again, and it is 17946 // good to avoid having whatever code was running in them 17947 // left sitting around after no longer needed. 17948 app.kill("isolated not needed", true); 17949 } 17950 17951 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17952 && !app.killedByAm) { 17953 numTrimming++; 17954 } 17955 } 17956 } 17957 17958 mNumServiceProcs = mNewNumServiceProcs; 17959 17960 // Now determine the memory trimming level of background processes. 17961 // Unfortunately we need to start at the back of the list to do this 17962 // properly. We only do this if the number of background apps we 17963 // are managing to keep around is less than half the maximum we desire; 17964 // if we are keeping a good number around, we'll let them use whatever 17965 // memory they want. 17966 final int numCachedAndEmpty = numCached + numEmpty; 17967 int memFactor; 17968 if (numCached <= ProcessList.TRIM_CACHED_APPS 17969 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17970 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17971 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17972 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17973 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17974 } else { 17975 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17976 } 17977 } else { 17978 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17979 } 17980 // We always allow the memory level to go up (better). We only allow it to go 17981 // down if we are in a state where that is allowed, *and* the total number of processes 17982 // has gone down since last time. 17983 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17984 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17985 + " last=" + mLastNumProcesses); 17986 if (memFactor > mLastMemoryLevel) { 17987 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17988 memFactor = mLastMemoryLevel; 17989 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17990 } 17991 } 17992 mLastMemoryLevel = memFactor; 17993 mLastNumProcesses = mLruProcesses.size(); 17994 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17995 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17996 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17997 if (mLowRamStartTime == 0) { 17998 mLowRamStartTime = now; 17999 } 18000 int step = 0; 18001 int fgTrimLevel; 18002 switch (memFactor) { 18003 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18004 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18005 break; 18006 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18007 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18008 break; 18009 default: 18010 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18011 break; 18012 } 18013 int factor = numTrimming/3; 18014 int minFactor = 2; 18015 if (mHomeProcess != null) minFactor++; 18016 if (mPreviousProcess != null) minFactor++; 18017 if (factor < minFactor) factor = minFactor; 18018 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18019 for (int i=N-1; i>=0; i--) { 18020 ProcessRecord app = mLruProcesses.get(i); 18021 if (allChanged || app.procStateChanged) { 18022 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18023 app.procStateChanged = false; 18024 } 18025 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18026 && !app.killedByAm) { 18027 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18028 try { 18029 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18030 "Trimming memory of " + app.processName 18031 + " to " + curLevel); 18032 app.thread.scheduleTrimMemory(curLevel); 18033 } catch (RemoteException e) { 18034 } 18035 if (false) { 18036 // For now we won't do this; our memory trimming seems 18037 // to be good enough at this point that destroying 18038 // activities causes more harm than good. 18039 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18040 && app != mHomeProcess && app != mPreviousProcess) { 18041 // Need to do this on its own message because the stack may not 18042 // be in a consistent state at this point. 18043 // For these apps we will also finish their activities 18044 // to help them free memory. 18045 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18046 } 18047 } 18048 } 18049 app.trimMemoryLevel = curLevel; 18050 step++; 18051 if (step >= factor) { 18052 step = 0; 18053 switch (curLevel) { 18054 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18055 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18056 break; 18057 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18058 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18059 break; 18060 } 18061 } 18062 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18063 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18064 && app.thread != null) { 18065 try { 18066 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18067 "Trimming memory of heavy-weight " + app.processName 18068 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18069 app.thread.scheduleTrimMemory( 18070 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18071 } catch (RemoteException e) { 18072 } 18073 } 18074 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18075 } else { 18076 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18077 || app.systemNoUi) && app.pendingUiClean) { 18078 // If this application is now in the background and it 18079 // had done UI, then give it the special trim level to 18080 // have it free UI resources. 18081 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18082 if (app.trimMemoryLevel < level && app.thread != null) { 18083 try { 18084 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18085 "Trimming memory of bg-ui " + app.processName 18086 + " to " + level); 18087 app.thread.scheduleTrimMemory(level); 18088 } catch (RemoteException e) { 18089 } 18090 } 18091 app.pendingUiClean = false; 18092 } 18093 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18094 try { 18095 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18096 "Trimming memory of fg " + app.processName 18097 + " to " + fgTrimLevel); 18098 app.thread.scheduleTrimMemory(fgTrimLevel); 18099 } catch (RemoteException e) { 18100 } 18101 } 18102 app.trimMemoryLevel = fgTrimLevel; 18103 } 18104 } 18105 } else { 18106 if (mLowRamStartTime != 0) { 18107 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18108 mLowRamStartTime = 0; 18109 } 18110 for (int i=N-1; i>=0; i--) { 18111 ProcessRecord app = mLruProcesses.get(i); 18112 if (allChanged || app.procStateChanged) { 18113 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18114 app.procStateChanged = false; 18115 } 18116 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18117 || app.systemNoUi) && app.pendingUiClean) { 18118 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18119 && app.thread != null) { 18120 try { 18121 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18122 "Trimming memory of ui hidden " + app.processName 18123 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18124 app.thread.scheduleTrimMemory( 18125 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18126 } catch (RemoteException e) { 18127 } 18128 } 18129 app.pendingUiClean = false; 18130 } 18131 app.trimMemoryLevel = 0; 18132 } 18133 } 18134 18135 if (mAlwaysFinishActivities) { 18136 // Need to do this on its own message because the stack may not 18137 // be in a consistent state at this point. 18138 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18139 } 18140 18141 if (allChanged) { 18142 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18143 } 18144 18145 if (mProcessStats.shouldWriteNowLocked(now)) { 18146 mHandler.post(new Runnable() { 18147 @Override public void run() { 18148 synchronized (ActivityManagerService.this) { 18149 mProcessStats.writeStateAsyncLocked(); 18150 } 18151 } 18152 }); 18153 } 18154 18155 if (DEBUG_OOM_ADJ) { 18156 if (false) { 18157 RuntimeException here = new RuntimeException("here"); 18158 here.fillInStackTrace(); 18159 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18160 } else { 18161 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18162 } 18163 } 18164 } 18165 18166 final void trimApplications() { 18167 synchronized (this) { 18168 int i; 18169 18170 // First remove any unused application processes whose package 18171 // has been removed. 18172 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18173 final ProcessRecord app = mRemovedProcesses.get(i); 18174 if (app.activities.size() == 0 18175 && app.curReceiver == null && app.services.size() == 0) { 18176 Slog.i( 18177 TAG, "Exiting empty application process " 18178 + app.processName + " (" 18179 + (app.thread != null ? app.thread.asBinder() : null) 18180 + ")\n"); 18181 if (app.pid > 0 && app.pid != MY_PID) { 18182 app.kill("empty", false); 18183 } else { 18184 try { 18185 app.thread.scheduleExit(); 18186 } catch (Exception e) { 18187 // Ignore exceptions. 18188 } 18189 } 18190 cleanUpApplicationRecordLocked(app, false, true, -1); 18191 mRemovedProcesses.remove(i); 18192 18193 if (app.persistent) { 18194 addAppLocked(app.info, false, null /* ABI override */); 18195 } 18196 } 18197 } 18198 18199 // Now update the oom adj for all processes. 18200 updateOomAdjLocked(); 18201 } 18202 } 18203 18204 /** This method sends the specified signal to each of the persistent apps */ 18205 public void signalPersistentProcesses(int sig) throws RemoteException { 18206 if (sig != Process.SIGNAL_USR1) { 18207 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18208 } 18209 18210 synchronized (this) { 18211 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18212 != PackageManager.PERMISSION_GRANTED) { 18213 throw new SecurityException("Requires permission " 18214 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18215 } 18216 18217 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18218 ProcessRecord r = mLruProcesses.get(i); 18219 if (r.thread != null && r.persistent) { 18220 Process.sendSignal(r.pid, sig); 18221 } 18222 } 18223 } 18224 } 18225 18226 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18227 if (proc == null || proc == mProfileProc) { 18228 proc = mProfileProc; 18229 profileType = mProfileType; 18230 clearProfilerLocked(); 18231 } 18232 if (proc == null) { 18233 return; 18234 } 18235 try { 18236 proc.thread.profilerControl(false, null, profileType); 18237 } catch (RemoteException e) { 18238 throw new IllegalStateException("Process disappeared"); 18239 } 18240 } 18241 18242 private void clearProfilerLocked() { 18243 if (mProfileFd != null) { 18244 try { 18245 mProfileFd.close(); 18246 } catch (IOException e) { 18247 } 18248 } 18249 mProfileApp = null; 18250 mProfileProc = null; 18251 mProfileFile = null; 18252 mProfileType = 0; 18253 mAutoStopProfiler = false; 18254 mSamplingInterval = 0; 18255 } 18256 18257 public boolean profileControl(String process, int userId, boolean start, 18258 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18259 18260 try { 18261 synchronized (this) { 18262 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18263 // its own permission. 18264 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18265 != PackageManager.PERMISSION_GRANTED) { 18266 throw new SecurityException("Requires permission " 18267 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18268 } 18269 18270 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18271 throw new IllegalArgumentException("null profile info or fd"); 18272 } 18273 18274 ProcessRecord proc = null; 18275 if (process != null) { 18276 proc = findProcessLocked(process, userId, "profileControl"); 18277 } 18278 18279 if (start && (proc == null || proc.thread == null)) { 18280 throw new IllegalArgumentException("Unknown process: " + process); 18281 } 18282 18283 if (start) { 18284 stopProfilerLocked(null, 0); 18285 setProfileApp(proc.info, proc.processName, profilerInfo); 18286 mProfileProc = proc; 18287 mProfileType = profileType; 18288 ParcelFileDescriptor fd = profilerInfo.profileFd; 18289 try { 18290 fd = fd.dup(); 18291 } catch (IOException e) { 18292 fd = null; 18293 } 18294 profilerInfo.profileFd = fd; 18295 proc.thread.profilerControl(start, profilerInfo, profileType); 18296 fd = null; 18297 mProfileFd = null; 18298 } else { 18299 stopProfilerLocked(proc, profileType); 18300 if (profilerInfo != null && profilerInfo.profileFd != null) { 18301 try { 18302 profilerInfo.profileFd.close(); 18303 } catch (IOException e) { 18304 } 18305 } 18306 } 18307 18308 return true; 18309 } 18310 } catch (RemoteException e) { 18311 throw new IllegalStateException("Process disappeared"); 18312 } finally { 18313 if (profilerInfo != null && profilerInfo.profileFd != null) { 18314 try { 18315 profilerInfo.profileFd.close(); 18316 } catch (IOException e) { 18317 } 18318 } 18319 } 18320 } 18321 18322 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18323 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18324 userId, true, ALLOW_FULL_ONLY, callName, null); 18325 ProcessRecord proc = null; 18326 try { 18327 int pid = Integer.parseInt(process); 18328 synchronized (mPidsSelfLocked) { 18329 proc = mPidsSelfLocked.get(pid); 18330 } 18331 } catch (NumberFormatException e) { 18332 } 18333 18334 if (proc == null) { 18335 ArrayMap<String, SparseArray<ProcessRecord>> all 18336 = mProcessNames.getMap(); 18337 SparseArray<ProcessRecord> procs = all.get(process); 18338 if (procs != null && procs.size() > 0) { 18339 proc = procs.valueAt(0); 18340 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18341 for (int i=1; i<procs.size(); i++) { 18342 ProcessRecord thisProc = procs.valueAt(i); 18343 if (thisProc.userId == userId) { 18344 proc = thisProc; 18345 break; 18346 } 18347 } 18348 } 18349 } 18350 } 18351 18352 return proc; 18353 } 18354 18355 public boolean dumpHeap(String process, int userId, boolean managed, 18356 String path, ParcelFileDescriptor fd) throws RemoteException { 18357 18358 try { 18359 synchronized (this) { 18360 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18361 // its own permission (same as profileControl). 18362 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18363 != PackageManager.PERMISSION_GRANTED) { 18364 throw new SecurityException("Requires permission " 18365 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18366 } 18367 18368 if (fd == null) { 18369 throw new IllegalArgumentException("null fd"); 18370 } 18371 18372 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18373 if (proc == null || proc.thread == null) { 18374 throw new IllegalArgumentException("Unknown process: " + process); 18375 } 18376 18377 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18378 if (!isDebuggable) { 18379 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18380 throw new SecurityException("Process not debuggable: " + proc); 18381 } 18382 } 18383 18384 proc.thread.dumpHeap(managed, path, fd); 18385 fd = null; 18386 return true; 18387 } 18388 } catch (RemoteException e) { 18389 throw new IllegalStateException("Process disappeared"); 18390 } finally { 18391 if (fd != null) { 18392 try { 18393 fd.close(); 18394 } catch (IOException e) { 18395 } 18396 } 18397 } 18398 } 18399 18400 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18401 public void monitor() { 18402 synchronized (this) { } 18403 } 18404 18405 void onCoreSettingsChange(Bundle settings) { 18406 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18407 ProcessRecord processRecord = mLruProcesses.get(i); 18408 try { 18409 if (processRecord.thread != null) { 18410 processRecord.thread.setCoreSettings(settings); 18411 } 18412 } catch (RemoteException re) { 18413 /* ignore */ 18414 } 18415 } 18416 } 18417 18418 // Multi-user methods 18419 18420 /** 18421 * Start user, if its not already running, but don't bring it to foreground. 18422 */ 18423 @Override 18424 public boolean startUserInBackground(final int userId) { 18425 return startUser(userId, /* foreground */ false); 18426 } 18427 18428 /** 18429 * Start user, if its not already running, and bring it to foreground. 18430 */ 18431 boolean startUserInForeground(final int userId, Dialog dlg) { 18432 boolean result = startUser(userId, /* foreground */ true); 18433 dlg.dismiss(); 18434 return result; 18435 } 18436 18437 /** 18438 * Refreshes the list of users related to the current user when either a 18439 * user switch happens or when a new related user is started in the 18440 * background. 18441 */ 18442 private void updateCurrentProfileIdsLocked() { 18443 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18444 mCurrentUserId, false /* enabledOnly */); 18445 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18446 for (int i = 0; i < currentProfileIds.length; i++) { 18447 currentProfileIds[i] = profiles.get(i).id; 18448 } 18449 mCurrentProfileIds = currentProfileIds; 18450 18451 synchronized (mUserProfileGroupIdsSelfLocked) { 18452 mUserProfileGroupIdsSelfLocked.clear(); 18453 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18454 for (int i = 0; i < users.size(); i++) { 18455 UserInfo user = users.get(i); 18456 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18457 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18458 } 18459 } 18460 } 18461 } 18462 18463 private Set getProfileIdsLocked(int userId) { 18464 Set userIds = new HashSet<Integer>(); 18465 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18466 userId, false /* enabledOnly */); 18467 for (UserInfo user : profiles) { 18468 userIds.add(Integer.valueOf(user.id)); 18469 } 18470 return userIds; 18471 } 18472 18473 @Override 18474 public boolean switchUser(final int userId) { 18475 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18476 String userName; 18477 synchronized (this) { 18478 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18479 if (userInfo == null) { 18480 Slog.w(TAG, "No user info for user #" + userId); 18481 return false; 18482 } 18483 if (userInfo.isManagedProfile()) { 18484 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18485 return false; 18486 } 18487 userName = userInfo.name; 18488 mTargetUserId = userId; 18489 } 18490 mHandler.removeMessages(START_USER_SWITCH_MSG); 18491 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18492 return true; 18493 } 18494 18495 private void showUserSwitchDialog(int userId, String userName) { 18496 // The dialog will show and then initiate the user switch by calling startUserInForeground 18497 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18498 true /* above system */); 18499 d.show(); 18500 } 18501 18502 private boolean startUser(final int userId, final boolean foreground) { 18503 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18504 != PackageManager.PERMISSION_GRANTED) { 18505 String msg = "Permission Denial: switchUser() from pid=" 18506 + Binder.getCallingPid() 18507 + ", uid=" + Binder.getCallingUid() 18508 + " requires " + INTERACT_ACROSS_USERS_FULL; 18509 Slog.w(TAG, msg); 18510 throw new SecurityException(msg); 18511 } 18512 18513 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18514 18515 final long ident = Binder.clearCallingIdentity(); 18516 try { 18517 synchronized (this) { 18518 final int oldUserId = mCurrentUserId; 18519 if (oldUserId == userId) { 18520 return true; 18521 } 18522 18523 mStackSupervisor.setLockTaskModeLocked(null, false); 18524 18525 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18526 if (userInfo == null) { 18527 Slog.w(TAG, "No user info for user #" + userId); 18528 return false; 18529 } 18530 if (foreground && userInfo.isManagedProfile()) { 18531 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18532 return false; 18533 } 18534 18535 if (foreground) { 18536 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18537 R.anim.screen_user_enter); 18538 } 18539 18540 boolean needStart = false; 18541 18542 // If the user we are switching to is not currently started, then 18543 // we need to start it now. 18544 if (mStartedUsers.get(userId) == null) { 18545 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18546 updateStartedUserArrayLocked(); 18547 needStart = true; 18548 } 18549 18550 final Integer userIdInt = Integer.valueOf(userId); 18551 mUserLru.remove(userIdInt); 18552 mUserLru.add(userIdInt); 18553 18554 if (foreground) { 18555 mCurrentUserId = userId; 18556 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18557 updateCurrentProfileIdsLocked(); 18558 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18559 // Once the internal notion of the active user has switched, we lock the device 18560 // with the option to show the user switcher on the keyguard. 18561 mWindowManager.lockNow(null); 18562 } else { 18563 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18564 updateCurrentProfileIdsLocked(); 18565 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18566 mUserLru.remove(currentUserIdInt); 18567 mUserLru.add(currentUserIdInt); 18568 } 18569 18570 final UserStartedState uss = mStartedUsers.get(userId); 18571 18572 // Make sure user is in the started state. If it is currently 18573 // stopping, we need to knock that off. 18574 if (uss.mState == UserStartedState.STATE_STOPPING) { 18575 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18576 // so we can just fairly silently bring the user back from 18577 // the almost-dead. 18578 uss.mState = UserStartedState.STATE_RUNNING; 18579 updateStartedUserArrayLocked(); 18580 needStart = true; 18581 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18582 // This means ACTION_SHUTDOWN has been sent, so we will 18583 // need to treat this as a new boot of the user. 18584 uss.mState = UserStartedState.STATE_BOOTING; 18585 updateStartedUserArrayLocked(); 18586 needStart = true; 18587 } 18588 18589 if (uss.mState == UserStartedState.STATE_BOOTING) { 18590 // Booting up a new user, need to tell system services about it. 18591 // Note that this is on the same handler as scheduling of broadcasts, 18592 // which is important because it needs to go first. 18593 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18594 } 18595 18596 if (foreground) { 18597 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18598 oldUserId)); 18599 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18600 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18601 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18602 oldUserId, userId, uss)); 18603 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18604 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18605 } 18606 18607 if (needStart) { 18608 // Send USER_STARTED broadcast 18609 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18610 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18611 | Intent.FLAG_RECEIVER_FOREGROUND); 18612 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18613 broadcastIntentLocked(null, null, intent, 18614 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18615 false, false, MY_PID, Process.SYSTEM_UID, userId); 18616 } 18617 18618 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18619 if (userId != UserHandle.USER_OWNER) { 18620 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18621 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18622 broadcastIntentLocked(null, null, intent, null, 18623 new IIntentReceiver.Stub() { 18624 public void performReceive(Intent intent, int resultCode, 18625 String data, Bundle extras, boolean ordered, 18626 boolean sticky, int sendingUser) { 18627 onUserInitialized(uss, foreground, oldUserId, userId); 18628 } 18629 }, 0, null, null, null, AppOpsManager.OP_NONE, 18630 true, false, MY_PID, Process.SYSTEM_UID, 18631 userId); 18632 uss.initializing = true; 18633 } else { 18634 getUserManagerLocked().makeInitialized(userInfo.id); 18635 } 18636 } 18637 18638 if (foreground) { 18639 if (!uss.initializing) { 18640 moveUserToForeground(uss, oldUserId, userId); 18641 } 18642 } else { 18643 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18644 } 18645 18646 if (needStart) { 18647 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18648 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18649 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18650 broadcastIntentLocked(null, null, intent, 18651 null, new IIntentReceiver.Stub() { 18652 @Override 18653 public void performReceive(Intent intent, int resultCode, String data, 18654 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18655 throws RemoteException { 18656 } 18657 }, 0, null, null, 18658 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18659 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18660 } 18661 } 18662 } finally { 18663 Binder.restoreCallingIdentity(ident); 18664 } 18665 18666 return true; 18667 } 18668 18669 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18670 long ident = Binder.clearCallingIdentity(); 18671 try { 18672 Intent intent; 18673 if (oldUserId >= 0) { 18674 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18675 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18676 int count = profiles.size(); 18677 for (int i = 0; i < count; i++) { 18678 int profileUserId = profiles.get(i).id; 18679 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18680 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18681 | Intent.FLAG_RECEIVER_FOREGROUND); 18682 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18683 broadcastIntentLocked(null, null, intent, 18684 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18685 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18686 } 18687 } 18688 if (newUserId >= 0) { 18689 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18690 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18691 int count = profiles.size(); 18692 for (int i = 0; i < count; i++) { 18693 int profileUserId = profiles.get(i).id; 18694 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18695 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18696 | Intent.FLAG_RECEIVER_FOREGROUND); 18697 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18698 broadcastIntentLocked(null, null, intent, 18699 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18700 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18701 } 18702 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18703 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18704 | Intent.FLAG_RECEIVER_FOREGROUND); 18705 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18706 broadcastIntentLocked(null, null, intent, 18707 null, null, 0, null, null, 18708 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18709 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18710 } 18711 } finally { 18712 Binder.restoreCallingIdentity(ident); 18713 } 18714 } 18715 18716 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18717 final int newUserId) { 18718 final int N = mUserSwitchObservers.beginBroadcast(); 18719 if (N > 0) { 18720 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18721 int mCount = 0; 18722 @Override 18723 public void sendResult(Bundle data) throws RemoteException { 18724 synchronized (ActivityManagerService.this) { 18725 if (mCurUserSwitchCallback == this) { 18726 mCount++; 18727 if (mCount == N) { 18728 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18729 } 18730 } 18731 } 18732 } 18733 }; 18734 synchronized (this) { 18735 uss.switching = true; 18736 mCurUserSwitchCallback = callback; 18737 } 18738 for (int i=0; i<N; i++) { 18739 try { 18740 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18741 newUserId, callback); 18742 } catch (RemoteException e) { 18743 } 18744 } 18745 } else { 18746 synchronized (this) { 18747 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18748 } 18749 } 18750 mUserSwitchObservers.finishBroadcast(); 18751 } 18752 18753 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18754 synchronized (this) { 18755 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18756 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18757 } 18758 } 18759 18760 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18761 mCurUserSwitchCallback = null; 18762 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18763 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18764 oldUserId, newUserId, uss)); 18765 } 18766 18767 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18768 synchronized (this) { 18769 if (foreground) { 18770 moveUserToForeground(uss, oldUserId, newUserId); 18771 } 18772 } 18773 18774 completeSwitchAndInitalize(uss, newUserId, true, false); 18775 } 18776 18777 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18778 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18779 if (homeInFront) { 18780 startHomeActivityLocked(newUserId); 18781 } else { 18782 mStackSupervisor.resumeTopActivitiesLocked(); 18783 } 18784 EventLogTags.writeAmSwitchUser(newUserId); 18785 getUserManagerLocked().userForeground(newUserId); 18786 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18787 } 18788 18789 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18790 completeSwitchAndInitalize(uss, newUserId, false, true); 18791 } 18792 18793 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18794 boolean clearInitializing, boolean clearSwitching) { 18795 boolean unfrozen = false; 18796 synchronized (this) { 18797 if (clearInitializing) { 18798 uss.initializing = false; 18799 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18800 } 18801 if (clearSwitching) { 18802 uss.switching = false; 18803 } 18804 if (!uss.switching && !uss.initializing) { 18805 mWindowManager.stopFreezingScreen(); 18806 unfrozen = true; 18807 } 18808 } 18809 if (unfrozen) { 18810 final int N = mUserSwitchObservers.beginBroadcast(); 18811 for (int i=0; i<N; i++) { 18812 try { 18813 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18814 } catch (RemoteException e) { 18815 } 18816 } 18817 mUserSwitchObservers.finishBroadcast(); 18818 } 18819 } 18820 18821 void scheduleStartProfilesLocked() { 18822 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18823 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18824 DateUtils.SECOND_IN_MILLIS); 18825 } 18826 } 18827 18828 void startProfilesLocked() { 18829 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18830 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18831 mCurrentUserId, false /* enabledOnly */); 18832 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18833 for (UserInfo user : profiles) { 18834 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18835 && user.id != mCurrentUserId) { 18836 toStart.add(user); 18837 } 18838 } 18839 final int n = toStart.size(); 18840 int i = 0; 18841 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18842 startUserInBackground(toStart.get(i).id); 18843 } 18844 if (i < n) { 18845 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18846 } 18847 } 18848 18849 void finishUserBoot(UserStartedState uss) { 18850 synchronized (this) { 18851 if (uss.mState == UserStartedState.STATE_BOOTING 18852 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18853 uss.mState = UserStartedState.STATE_RUNNING; 18854 final int userId = uss.mHandle.getIdentifier(); 18855 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18856 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18857 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18858 broadcastIntentLocked(null, null, intent, 18859 null, null, 0, null, null, 18860 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18861 true, false, MY_PID, Process.SYSTEM_UID, userId); 18862 } 18863 } 18864 } 18865 18866 void finishUserSwitch(UserStartedState uss) { 18867 synchronized (this) { 18868 finishUserBoot(uss); 18869 18870 startProfilesLocked(); 18871 18872 int num = mUserLru.size(); 18873 int i = 0; 18874 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18875 Integer oldUserId = mUserLru.get(i); 18876 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18877 if (oldUss == null) { 18878 // Shouldn't happen, but be sane if it does. 18879 mUserLru.remove(i); 18880 num--; 18881 continue; 18882 } 18883 if (oldUss.mState == UserStartedState.STATE_STOPPING 18884 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18885 // This user is already stopping, doesn't count. 18886 num--; 18887 i++; 18888 continue; 18889 } 18890 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18891 // Owner and current can't be stopped, but count as running. 18892 i++; 18893 continue; 18894 } 18895 // This is a user to be stopped. 18896 stopUserLocked(oldUserId, null); 18897 num--; 18898 i++; 18899 } 18900 } 18901 } 18902 18903 @Override 18904 public int stopUser(final int userId, final IStopUserCallback callback) { 18905 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18906 != PackageManager.PERMISSION_GRANTED) { 18907 String msg = "Permission Denial: switchUser() from pid=" 18908 + Binder.getCallingPid() 18909 + ", uid=" + Binder.getCallingUid() 18910 + " requires " + INTERACT_ACROSS_USERS_FULL; 18911 Slog.w(TAG, msg); 18912 throw new SecurityException(msg); 18913 } 18914 if (userId <= 0) { 18915 throw new IllegalArgumentException("Can't stop primary user " + userId); 18916 } 18917 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18918 synchronized (this) { 18919 return stopUserLocked(userId, callback); 18920 } 18921 } 18922 18923 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18924 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18925 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18926 return ActivityManager.USER_OP_IS_CURRENT; 18927 } 18928 18929 final UserStartedState uss = mStartedUsers.get(userId); 18930 if (uss == null) { 18931 // User is not started, nothing to do... but we do need to 18932 // callback if requested. 18933 if (callback != null) { 18934 mHandler.post(new Runnable() { 18935 @Override 18936 public void run() { 18937 try { 18938 callback.userStopped(userId); 18939 } catch (RemoteException e) { 18940 } 18941 } 18942 }); 18943 } 18944 return ActivityManager.USER_OP_SUCCESS; 18945 } 18946 18947 if (callback != null) { 18948 uss.mStopCallbacks.add(callback); 18949 } 18950 18951 if (uss.mState != UserStartedState.STATE_STOPPING 18952 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18953 uss.mState = UserStartedState.STATE_STOPPING; 18954 updateStartedUserArrayLocked(); 18955 18956 long ident = Binder.clearCallingIdentity(); 18957 try { 18958 // We are going to broadcast ACTION_USER_STOPPING and then 18959 // once that is done send a final ACTION_SHUTDOWN and then 18960 // stop the user. 18961 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18962 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18963 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18964 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18965 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18966 // This is the result receiver for the final shutdown broadcast. 18967 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18968 @Override 18969 public void performReceive(Intent intent, int resultCode, String data, 18970 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18971 finishUserStop(uss); 18972 } 18973 }; 18974 // This is the result receiver for the initial stopping broadcast. 18975 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18976 @Override 18977 public void performReceive(Intent intent, int resultCode, String data, 18978 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18979 // On to the next. 18980 synchronized (ActivityManagerService.this) { 18981 if (uss.mState != UserStartedState.STATE_STOPPING) { 18982 // Whoops, we are being started back up. Abort, abort! 18983 return; 18984 } 18985 uss.mState = UserStartedState.STATE_SHUTDOWN; 18986 } 18987 mBatteryStatsService.noteEvent( 18988 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18989 Integer.toString(userId), userId); 18990 mSystemServiceManager.stopUser(userId); 18991 broadcastIntentLocked(null, null, shutdownIntent, 18992 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18993 true, false, MY_PID, Process.SYSTEM_UID, userId); 18994 } 18995 }; 18996 // Kick things off. 18997 broadcastIntentLocked(null, null, stoppingIntent, 18998 null, stoppingReceiver, 0, null, null, 18999 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19000 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19001 } finally { 19002 Binder.restoreCallingIdentity(ident); 19003 } 19004 } 19005 19006 return ActivityManager.USER_OP_SUCCESS; 19007 } 19008 19009 void finishUserStop(UserStartedState uss) { 19010 final int userId = uss.mHandle.getIdentifier(); 19011 boolean stopped; 19012 ArrayList<IStopUserCallback> callbacks; 19013 synchronized (this) { 19014 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19015 if (mStartedUsers.get(userId) != uss) { 19016 stopped = false; 19017 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19018 stopped = false; 19019 } else { 19020 stopped = true; 19021 // User can no longer run. 19022 mStartedUsers.remove(userId); 19023 mUserLru.remove(Integer.valueOf(userId)); 19024 updateStartedUserArrayLocked(); 19025 19026 // Clean up all state and processes associated with the user. 19027 // Kill all the processes for the user. 19028 forceStopUserLocked(userId, "finish user"); 19029 } 19030 19031 // Explicitly remove the old information in mRecentTasks. 19032 removeRecentTasksForUserLocked(userId); 19033 } 19034 19035 for (int i=0; i<callbacks.size(); i++) { 19036 try { 19037 if (stopped) callbacks.get(i).userStopped(userId); 19038 else callbacks.get(i).userStopAborted(userId); 19039 } catch (RemoteException e) { 19040 } 19041 } 19042 19043 if (stopped) { 19044 mSystemServiceManager.cleanupUser(userId); 19045 synchronized (this) { 19046 mStackSupervisor.removeUserLocked(userId); 19047 } 19048 } 19049 } 19050 19051 @Override 19052 public UserInfo getCurrentUser() { 19053 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19054 != PackageManager.PERMISSION_GRANTED) && ( 19055 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19056 != PackageManager.PERMISSION_GRANTED)) { 19057 String msg = "Permission Denial: getCurrentUser() from pid=" 19058 + Binder.getCallingPid() 19059 + ", uid=" + Binder.getCallingUid() 19060 + " requires " + INTERACT_ACROSS_USERS; 19061 Slog.w(TAG, msg); 19062 throw new SecurityException(msg); 19063 } 19064 synchronized (this) { 19065 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19066 return getUserManagerLocked().getUserInfo(userId); 19067 } 19068 } 19069 19070 int getCurrentUserIdLocked() { 19071 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19072 } 19073 19074 @Override 19075 public boolean isUserRunning(int userId, boolean orStopped) { 19076 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19077 != PackageManager.PERMISSION_GRANTED) { 19078 String msg = "Permission Denial: isUserRunning() from pid=" 19079 + Binder.getCallingPid() 19080 + ", uid=" + Binder.getCallingUid() 19081 + " requires " + INTERACT_ACROSS_USERS; 19082 Slog.w(TAG, msg); 19083 throw new SecurityException(msg); 19084 } 19085 synchronized (this) { 19086 return isUserRunningLocked(userId, orStopped); 19087 } 19088 } 19089 19090 boolean isUserRunningLocked(int userId, boolean orStopped) { 19091 UserStartedState state = mStartedUsers.get(userId); 19092 if (state == null) { 19093 return false; 19094 } 19095 if (orStopped) { 19096 return true; 19097 } 19098 return state.mState != UserStartedState.STATE_STOPPING 19099 && state.mState != UserStartedState.STATE_SHUTDOWN; 19100 } 19101 19102 @Override 19103 public int[] getRunningUserIds() { 19104 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19105 != PackageManager.PERMISSION_GRANTED) { 19106 String msg = "Permission Denial: isUserRunning() from pid=" 19107 + Binder.getCallingPid() 19108 + ", uid=" + Binder.getCallingUid() 19109 + " requires " + INTERACT_ACROSS_USERS; 19110 Slog.w(TAG, msg); 19111 throw new SecurityException(msg); 19112 } 19113 synchronized (this) { 19114 return mStartedUserArray; 19115 } 19116 } 19117 19118 private void updateStartedUserArrayLocked() { 19119 int num = 0; 19120 for (int i=0; i<mStartedUsers.size(); i++) { 19121 UserStartedState uss = mStartedUsers.valueAt(i); 19122 // This list does not include stopping users. 19123 if (uss.mState != UserStartedState.STATE_STOPPING 19124 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19125 num++; 19126 } 19127 } 19128 mStartedUserArray = new int[num]; 19129 num = 0; 19130 for (int i=0; i<mStartedUsers.size(); i++) { 19131 UserStartedState uss = mStartedUsers.valueAt(i); 19132 if (uss.mState != UserStartedState.STATE_STOPPING 19133 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19134 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19135 num++; 19136 } 19137 } 19138 } 19139 19140 @Override 19141 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19142 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19143 != PackageManager.PERMISSION_GRANTED) { 19144 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19145 + Binder.getCallingPid() 19146 + ", uid=" + Binder.getCallingUid() 19147 + " requires " + INTERACT_ACROSS_USERS_FULL; 19148 Slog.w(TAG, msg); 19149 throw new SecurityException(msg); 19150 } 19151 19152 mUserSwitchObservers.register(observer); 19153 } 19154 19155 @Override 19156 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19157 mUserSwitchObservers.unregister(observer); 19158 } 19159 19160 private boolean userExists(int userId) { 19161 if (userId == 0) { 19162 return true; 19163 } 19164 UserManagerService ums = getUserManagerLocked(); 19165 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19166 } 19167 19168 int[] getUsersLocked() { 19169 UserManagerService ums = getUserManagerLocked(); 19170 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19171 } 19172 19173 UserManagerService getUserManagerLocked() { 19174 if (mUserManager == null) { 19175 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19176 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19177 } 19178 return mUserManager; 19179 } 19180 19181 private int applyUserId(int uid, int userId) { 19182 return UserHandle.getUid(userId, uid); 19183 } 19184 19185 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19186 if (info == null) return null; 19187 ApplicationInfo newInfo = new ApplicationInfo(info); 19188 newInfo.uid = applyUserId(info.uid, userId); 19189 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19190 + info.packageName; 19191 return newInfo; 19192 } 19193 19194 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19195 if (aInfo == null 19196 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19197 return aInfo; 19198 } 19199 19200 ActivityInfo info = new ActivityInfo(aInfo); 19201 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19202 return info; 19203 } 19204 19205 private final class LocalService extends ActivityManagerInternal { 19206 @Override 19207 public void goingToSleep() { 19208 ActivityManagerService.this.goingToSleep(); 19209 } 19210 19211 @Override 19212 public void wakingUp() { 19213 ActivityManagerService.this.wakingUp(); 19214 } 19215 19216 @Override 19217 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19218 String processName, String abiOverride, int uid, Runnable crashHandler) { 19219 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19220 processName, abiOverride, uid, crashHandler); 19221 } 19222 } 19223 19224 /** 19225 * An implementation of IAppTask, that allows an app to manage its own tasks via 19226 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19227 * only the process that calls getAppTasks() can call the AppTask methods. 19228 */ 19229 class AppTaskImpl extends IAppTask.Stub { 19230 private int mTaskId; 19231 private int mCallingUid; 19232 19233 public AppTaskImpl(int taskId, int callingUid) { 19234 mTaskId = taskId; 19235 mCallingUid = callingUid; 19236 } 19237 19238 private void checkCaller() { 19239 if (mCallingUid != Binder.getCallingUid()) { 19240 throw new SecurityException("Caller " + mCallingUid 19241 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19242 } 19243 } 19244 19245 @Override 19246 public void finishAndRemoveTask() { 19247 checkCaller(); 19248 19249 synchronized (ActivityManagerService.this) { 19250 long origId = Binder.clearCallingIdentity(); 19251 try { 19252 if (!removeTaskByIdLocked(mTaskId, false)) { 19253 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19254 } 19255 } finally { 19256 Binder.restoreCallingIdentity(origId); 19257 } 19258 } 19259 } 19260 19261 @Override 19262 public ActivityManager.RecentTaskInfo getTaskInfo() { 19263 checkCaller(); 19264 19265 synchronized (ActivityManagerService.this) { 19266 long origId = Binder.clearCallingIdentity(); 19267 try { 19268 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19269 if (tr == null) { 19270 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19271 } 19272 return createRecentTaskInfoFromTaskRecord(tr); 19273 } finally { 19274 Binder.restoreCallingIdentity(origId); 19275 } 19276 } 19277 } 19278 19279 @Override 19280 public void moveToFront() { 19281 checkCaller(); 19282 19283 final TaskRecord tr; 19284 synchronized (ActivityManagerService.this) { 19285 tr = recentTaskForIdLocked(mTaskId); 19286 if (tr == null) { 19287 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19288 } 19289 if (tr.getRootActivity() != null) { 19290 moveTaskToFrontLocked(tr.taskId, 0, null); 19291 return; 19292 } 19293 } 19294 19295 startActivityFromRecentsInner(tr.taskId, null); 19296 } 19297 19298 @Override 19299 public int startActivity(IBinder whoThread, String callingPackage, 19300 Intent intent, String resolvedType, Bundle options) { 19301 checkCaller(); 19302 19303 int callingUser = UserHandle.getCallingUserId(); 19304 TaskRecord tr; 19305 IApplicationThread appThread; 19306 synchronized (ActivityManagerService.this) { 19307 tr = recentTaskForIdLocked(mTaskId); 19308 if (tr == null) { 19309 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19310 } 19311 appThread = ApplicationThreadNative.asInterface(whoThread); 19312 if (appThread == null) { 19313 throw new IllegalArgumentException("Bad app thread " + appThread); 19314 } 19315 } 19316 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19317 resolvedType, null, null, null, null, 0, 0, null, null, 19318 null, options, callingUser, null, tr); 19319 } 19320 19321 @Override 19322 public void setExcludeFromRecents(boolean exclude) { 19323 checkCaller(); 19324 19325 synchronized (ActivityManagerService.this) { 19326 long origId = Binder.clearCallingIdentity(); 19327 try { 19328 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19329 if (tr == null) { 19330 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19331 } 19332 Intent intent = tr.getBaseIntent(); 19333 if (exclude) { 19334 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19335 } else { 19336 intent.setFlags(intent.getFlags() 19337 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19338 } 19339 } finally { 19340 Binder.restoreCallingIdentity(origId); 19341 } 19342 } 19343 } 19344 } 19345} 19346