ActivityManagerService.java revision 465e996776d916d8d1b62c539142827bd96a42bc
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 return toString().hashCode(); 799 } 800 801 @Override 802 public boolean equals(Object o) { 803 if (o instanceof GrantUri) { 804 GrantUri other = (GrantUri) o; 805 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 806 && prefix == other.prefix; 807 } 808 return false; 809 } 810 811 @Override 812 public String toString() { 813 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 814 if (prefix) result += " [prefix]"; 815 return result; 816 } 817 818 public String toSafeString() { 819 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 820 if (prefix) result += " [prefix]"; 821 return result; 822 } 823 824 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 825 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 826 ContentProvider.getUriWithoutUserId(uri), false); 827 } 828 } 829 830 CoreSettingsObserver mCoreSettingsObserver; 831 832 /** 833 * Thread-local storage used to carry caller permissions over through 834 * indirect content-provider access. 835 */ 836 private class Identity { 837 public int pid; 838 public int uid; 839 840 Identity(int _pid, int _uid) { 841 pid = _pid; 842 uid = _uid; 843 } 844 } 845 846 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 847 848 /** 849 * All information we have collected about the runtime performance of 850 * any user id that can impact battery performance. 851 */ 852 final BatteryStatsService mBatteryStatsService; 853 854 /** 855 * Information about component usage 856 */ 857 UsageStatsManagerInternal mUsageStatsService; 858 859 /** 860 * Information about and control over application operations 861 */ 862 final AppOpsService mAppOpsService; 863 864 /** 865 * Save recent tasks information across reboots. 866 */ 867 final TaskPersister mTaskPersister; 868 869 /** 870 * Current configuration information. HistoryRecord objects are given 871 * a reference to this object to indicate which configuration they are 872 * currently running in, so this object must be kept immutable. 873 */ 874 Configuration mConfiguration = new Configuration(); 875 876 /** 877 * Current sequencing integer of the configuration, for skipping old 878 * configurations. 879 */ 880 int mConfigurationSeq = 0; 881 882 /** 883 * Hardware-reported OpenGLES version. 884 */ 885 final int GL_ES_VERSION; 886 887 /** 888 * List of initialization arguments to pass to all processes when binding applications to them. 889 * For example, references to the commonly used services. 890 */ 891 HashMap<String, IBinder> mAppBindArgs; 892 893 /** 894 * Temporary to avoid allocations. Protected by main lock. 895 */ 896 final StringBuilder mStringBuilder = new StringBuilder(256); 897 898 /** 899 * Used to control how we initialize the service. 900 */ 901 ComponentName mTopComponent; 902 String mTopAction = Intent.ACTION_MAIN; 903 String mTopData; 904 boolean mProcessesReady = false; 905 boolean mSystemReady = false; 906 boolean mBooting = false; 907 boolean mCallFinishBooting = false; 908 boolean mBootAnimationComplete = false; 909 boolean mWaitingUpdate = false; 910 boolean mDidUpdate = false; 911 boolean mOnBattery = false; 912 boolean mLaunchWarningShown = false; 913 914 Context mContext; 915 916 int mFactoryTest; 917 918 boolean mCheckedForSetup; 919 920 /** 921 * The time at which we will allow normal application switches again, 922 * after a call to {@link #stopAppSwitches()}. 923 */ 924 long mAppSwitchesAllowedTime; 925 926 /** 927 * This is set to true after the first switch after mAppSwitchesAllowedTime 928 * is set; any switches after that will clear the time. 929 */ 930 boolean mDidAppSwitch; 931 932 /** 933 * Last time (in realtime) at which we checked for power usage. 934 */ 935 long mLastPowerCheckRealtime; 936 937 /** 938 * Last time (in uptime) at which we checked for power usage. 939 */ 940 long mLastPowerCheckUptime; 941 942 /** 943 * Set while we are wanting to sleep, to prevent any 944 * activities from being started/resumed. 945 */ 946 private boolean mSleeping = false; 947 948 /** 949 * Set while we are running a voice interaction. This overrides 950 * sleeping while it is active. 951 */ 952 private boolean mRunningVoice = false; 953 954 /** 955 * State of external calls telling us if the device is asleep. 956 */ 957 private boolean mWentToSleep = false; 958 959 static final int LOCK_SCREEN_HIDDEN = 0; 960 static final int LOCK_SCREEN_LEAVING = 1; 961 static final int LOCK_SCREEN_SHOWN = 2; 962 /** 963 * State of external call telling us if the lock screen is shown. 964 */ 965 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 966 967 /** 968 * Set if we are shutting down the system, similar to sleeping. 969 */ 970 boolean mShuttingDown = false; 971 972 /** 973 * Current sequence id for oom_adj computation traversal. 974 */ 975 int mAdjSeq = 0; 976 977 /** 978 * Current sequence id for process LRU updating. 979 */ 980 int mLruSeq = 0; 981 982 /** 983 * Keep track of the non-cached/empty process we last found, to help 984 * determine how to distribute cached/empty processes next time. 985 */ 986 int mNumNonCachedProcs = 0; 987 988 /** 989 * Keep track of the number of cached hidden procs, to balance oom adj 990 * distribution between those and empty procs. 991 */ 992 int mNumCachedHiddenProcs = 0; 993 994 /** 995 * Keep track of the number of service processes we last found, to 996 * determine on the next iteration which should be B services. 997 */ 998 int mNumServiceProcs = 0; 999 int mNewNumAServiceProcs = 0; 1000 int mNewNumServiceProcs = 0; 1001 1002 /** 1003 * Allow the current computed overall memory level of the system to go down? 1004 * This is set to false when we are killing processes for reasons other than 1005 * memory management, so that the now smaller process list will not be taken as 1006 * an indication that memory is tighter. 1007 */ 1008 boolean mAllowLowerMemLevel = false; 1009 1010 /** 1011 * The last computed memory level, for holding when we are in a state that 1012 * processes are going away for other reasons. 1013 */ 1014 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1015 1016 /** 1017 * The last total number of process we have, to determine if changes actually look 1018 * like a shrinking number of process due to lower RAM. 1019 */ 1020 int mLastNumProcesses; 1021 1022 /** 1023 * The uptime of the last time we performed idle maintenance. 1024 */ 1025 long mLastIdleTime = SystemClock.uptimeMillis(); 1026 1027 /** 1028 * Total time spent with RAM that has been added in the past since the last idle time. 1029 */ 1030 long mLowRamTimeSinceLastIdle = 0; 1031 1032 /** 1033 * If RAM is currently low, when that horrible situation started. 1034 */ 1035 long mLowRamStartTime = 0; 1036 1037 /** 1038 * For reporting to battery stats the current top application. 1039 */ 1040 private String mCurResumedPackage = null; 1041 private int mCurResumedUid = -1; 1042 1043 /** 1044 * For reporting to battery stats the apps currently running foreground 1045 * service. The ProcessMap is package/uid tuples; each of these contain 1046 * an array of the currently foreground processes. 1047 */ 1048 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1049 = new ProcessMap<ArrayList<ProcessRecord>>(); 1050 1051 /** 1052 * This is set if we had to do a delayed dexopt of an app before launching 1053 * it, to increase the ANR timeouts in that case. 1054 */ 1055 boolean mDidDexOpt; 1056 1057 /** 1058 * Set if the systemServer made a call to enterSafeMode. 1059 */ 1060 boolean mSafeMode; 1061 1062 String mDebugApp = null; 1063 boolean mWaitForDebugger = false; 1064 boolean mDebugTransient = false; 1065 String mOrigDebugApp = null; 1066 boolean mOrigWaitForDebugger = false; 1067 boolean mAlwaysFinishActivities = false; 1068 IActivityController mController = null; 1069 String mProfileApp = null; 1070 ProcessRecord mProfileProc = null; 1071 String mProfileFile; 1072 ParcelFileDescriptor mProfileFd; 1073 int mSamplingInterval = 0; 1074 boolean mAutoStopProfiler = false; 1075 int mProfileType = 0; 1076 String mOpenGlTraceApp = null; 1077 1078 static class ProcessChangeItem { 1079 static final int CHANGE_ACTIVITIES = 1<<0; 1080 static final int CHANGE_PROCESS_STATE = 1<<1; 1081 int changes; 1082 int uid; 1083 int pid; 1084 int processState; 1085 boolean foregroundActivities; 1086 } 1087 1088 final RemoteCallbackList<IProcessObserver> mProcessObservers 1089 = new RemoteCallbackList<IProcessObserver>(); 1090 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1091 1092 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1093 = new ArrayList<ProcessChangeItem>(); 1094 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1095 = new ArrayList<ProcessChangeItem>(); 1096 1097 /** 1098 * Runtime CPU use collection thread. This object's lock is used to 1099 * perform synchronization with the thread (notifying it to run). 1100 */ 1101 final Thread mProcessCpuThread; 1102 1103 /** 1104 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1105 * Must acquire this object's lock when accessing it. 1106 * NOTE: this lock will be held while doing long operations (trawling 1107 * through all processes in /proc), so it should never be acquired by 1108 * any critical paths such as when holding the main activity manager lock. 1109 */ 1110 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1111 MONITOR_THREAD_CPU_USAGE); 1112 final AtomicLong mLastCpuTime = new AtomicLong(0); 1113 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1114 1115 long mLastWriteTime = 0; 1116 1117 /** 1118 * Used to retain an update lock when the foreground activity is in 1119 * immersive mode. 1120 */ 1121 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1122 1123 /** 1124 * Set to true after the system has finished booting. 1125 */ 1126 boolean mBooted = false; 1127 1128 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1129 int mProcessLimitOverride = -1; 1130 1131 WindowManagerService mWindowManager; 1132 1133 final ActivityThread mSystemThread; 1134 1135 // Holds the current foreground user's id 1136 int mCurrentUserId = 0; 1137 // Holds the target user's id during a user switch 1138 int mTargetUserId = UserHandle.USER_NULL; 1139 // If there are multiple profiles for the current user, their ids are here 1140 // Currently only the primary user can have managed profiles 1141 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1142 1143 /** 1144 * Mapping from each known user ID to the profile group ID it is associated with. 1145 */ 1146 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1147 1148 private UserManagerService mUserManager; 1149 1150 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1151 final ProcessRecord mApp; 1152 final int mPid; 1153 final IApplicationThread mAppThread; 1154 1155 AppDeathRecipient(ProcessRecord app, int pid, 1156 IApplicationThread thread) { 1157 if (localLOGV) Slog.v( 1158 TAG, "New death recipient " + this 1159 + " for thread " + thread.asBinder()); 1160 mApp = app; 1161 mPid = pid; 1162 mAppThread = thread; 1163 } 1164 1165 @Override 1166 public void binderDied() { 1167 if (localLOGV) Slog.v( 1168 TAG, "Death received in " + this 1169 + " for thread " + mAppThread.asBinder()); 1170 synchronized(ActivityManagerService.this) { 1171 appDiedLocked(mApp, mPid, mAppThread); 1172 } 1173 } 1174 } 1175 1176 static final int SHOW_ERROR_MSG = 1; 1177 static final int SHOW_NOT_RESPONDING_MSG = 2; 1178 static final int SHOW_FACTORY_ERROR_MSG = 3; 1179 static final int UPDATE_CONFIGURATION_MSG = 4; 1180 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1181 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1182 static final int SERVICE_TIMEOUT_MSG = 12; 1183 static final int UPDATE_TIME_ZONE = 13; 1184 static final int SHOW_UID_ERROR_MSG = 14; 1185 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1186 static final int PROC_START_TIMEOUT_MSG = 20; 1187 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1188 static final int KILL_APPLICATION_MSG = 22; 1189 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1190 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1191 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1192 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1193 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1194 static final int CLEAR_DNS_CACHE_MSG = 28; 1195 static final int UPDATE_HTTP_PROXY_MSG = 29; 1196 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1197 static final int DISPATCH_PROCESSES_CHANGED = 31; 1198 static final int DISPATCH_PROCESS_DIED = 32; 1199 static final int REPORT_MEM_USAGE_MSG = 33; 1200 static final int REPORT_USER_SWITCH_MSG = 34; 1201 static final int CONTINUE_USER_SWITCH_MSG = 35; 1202 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1203 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1204 static final int PERSIST_URI_GRANTS_MSG = 38; 1205 static final int REQUEST_ALL_PSS_MSG = 39; 1206 static final int START_PROFILES_MSG = 40; 1207 static final int UPDATE_TIME = 41; 1208 static final int SYSTEM_USER_START_MSG = 42; 1209 static final int SYSTEM_USER_CURRENT_MSG = 43; 1210 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1211 static final int FINISH_BOOTING_MSG = 45; 1212 static final int START_USER_SWITCH_MSG = 46; 1213 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1214 static final int DISMISS_DIALOG_MSG = 48; 1215 1216 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1217 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1218 static final int FIRST_COMPAT_MODE_MSG = 300; 1219 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1220 1221 CompatModeDialog mCompatModeDialog; 1222 long mLastMemUsageReportTime = 0; 1223 1224 /** 1225 * Flag whether the current user is a "monkey", i.e. whether 1226 * the UI is driven by a UI automation tool. 1227 */ 1228 private boolean mUserIsMonkey; 1229 1230 /** Flag whether the device has a Recents UI */ 1231 boolean mHasRecents; 1232 1233 /** The dimensions of the thumbnails in the Recents UI. */ 1234 int mThumbnailWidth; 1235 int mThumbnailHeight; 1236 1237 final ServiceThread mHandlerThread; 1238 final MainHandler mHandler; 1239 1240 final class MainHandler extends Handler { 1241 public MainHandler(Looper looper) { 1242 super(looper, null, true); 1243 } 1244 1245 @Override 1246 public void handleMessage(Message msg) { 1247 switch (msg.what) { 1248 case SHOW_ERROR_MSG: { 1249 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1250 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1251 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1252 synchronized (ActivityManagerService.this) { 1253 ProcessRecord proc = (ProcessRecord)data.get("app"); 1254 AppErrorResult res = (AppErrorResult) data.get("result"); 1255 if (proc != null && proc.crashDialog != null) { 1256 Slog.e(TAG, "App already has crash dialog: " + proc); 1257 if (res != null) { 1258 res.set(0); 1259 } 1260 return; 1261 } 1262 boolean isBackground = (UserHandle.getAppId(proc.uid) 1263 >= Process.FIRST_APPLICATION_UID 1264 && proc.pid != MY_PID); 1265 for (int userId : mCurrentProfileIds) { 1266 isBackground &= (proc.userId != userId); 1267 } 1268 if (isBackground && !showBackground) { 1269 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1270 if (res != null) { 1271 res.set(0); 1272 } 1273 return; 1274 } 1275 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1276 Dialog d = new AppErrorDialog(mContext, 1277 ActivityManagerService.this, res, proc); 1278 d.show(); 1279 proc.crashDialog = d; 1280 } else { 1281 // The device is asleep, so just pretend that the user 1282 // saw a crash dialog and hit "force quit". 1283 if (res != null) { 1284 res.set(0); 1285 } 1286 } 1287 } 1288 1289 ensureBootCompleted(); 1290 } break; 1291 case SHOW_NOT_RESPONDING_MSG: { 1292 synchronized (ActivityManagerService.this) { 1293 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1294 ProcessRecord proc = (ProcessRecord)data.get("app"); 1295 if (proc != null && proc.anrDialog != null) { 1296 Slog.e(TAG, "App already has anr dialog: " + proc); 1297 return; 1298 } 1299 1300 Intent intent = new Intent("android.intent.action.ANR"); 1301 if (!mProcessesReady) { 1302 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1303 | Intent.FLAG_RECEIVER_FOREGROUND); 1304 } 1305 broadcastIntentLocked(null, null, intent, 1306 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1307 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1308 1309 if (mShowDialogs) { 1310 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1311 mContext, proc, (ActivityRecord)data.get("activity"), 1312 msg.arg1 != 0); 1313 d.show(); 1314 proc.anrDialog = d; 1315 } else { 1316 // Just kill the app if there is no dialog to be shown. 1317 killAppAtUsersRequest(proc, null); 1318 } 1319 } 1320 1321 ensureBootCompleted(); 1322 } break; 1323 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1324 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1325 synchronized (ActivityManagerService.this) { 1326 ProcessRecord proc = (ProcessRecord) data.get("app"); 1327 if (proc == null) { 1328 Slog.e(TAG, "App not found when showing strict mode dialog."); 1329 break; 1330 } 1331 if (proc.crashDialog != null) { 1332 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1333 return; 1334 } 1335 AppErrorResult res = (AppErrorResult) data.get("result"); 1336 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1337 Dialog d = new StrictModeViolationDialog(mContext, 1338 ActivityManagerService.this, res, proc); 1339 d.show(); 1340 proc.crashDialog = d; 1341 } else { 1342 // The device is asleep, so just pretend that the user 1343 // saw a crash dialog and hit "force quit". 1344 res.set(0); 1345 } 1346 } 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_FACTORY_ERROR_MSG: { 1350 Dialog d = new FactoryErrorDialog( 1351 mContext, msg.getData().getCharSequence("msg")); 1352 d.show(); 1353 ensureBootCompleted(); 1354 } break; 1355 case UPDATE_CONFIGURATION_MSG: { 1356 final ContentResolver resolver = mContext.getContentResolver(); 1357 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1358 } break; 1359 case GC_BACKGROUND_PROCESSES_MSG: { 1360 synchronized (ActivityManagerService.this) { 1361 performAppGcsIfAppropriateLocked(); 1362 } 1363 } break; 1364 case WAIT_FOR_DEBUGGER_MSG: { 1365 synchronized (ActivityManagerService.this) { 1366 ProcessRecord app = (ProcessRecord)msg.obj; 1367 if (msg.arg1 != 0) { 1368 if (!app.waitedForDebugger) { 1369 Dialog d = new AppWaitingForDebuggerDialog( 1370 ActivityManagerService.this, 1371 mContext, app); 1372 app.waitDialog = d; 1373 app.waitedForDebugger = true; 1374 d.show(); 1375 } 1376 } else { 1377 if (app.waitDialog != null) { 1378 app.waitDialog.dismiss(); 1379 app.waitDialog = null; 1380 } 1381 } 1382 } 1383 } break; 1384 case SERVICE_TIMEOUT_MSG: { 1385 if (mDidDexOpt) { 1386 mDidDexOpt = false; 1387 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1388 nmsg.obj = msg.obj; 1389 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1390 return; 1391 } 1392 mServices.serviceTimeout((ProcessRecord)msg.obj); 1393 } break; 1394 case UPDATE_TIME_ZONE: { 1395 synchronized (ActivityManagerService.this) { 1396 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1397 ProcessRecord r = mLruProcesses.get(i); 1398 if (r.thread != null) { 1399 try { 1400 r.thread.updateTimeZone(); 1401 } catch (RemoteException ex) { 1402 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1403 } 1404 } 1405 } 1406 } 1407 } break; 1408 case CLEAR_DNS_CACHE_MSG: { 1409 synchronized (ActivityManagerService.this) { 1410 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1411 ProcessRecord r = mLruProcesses.get(i); 1412 if (r.thread != null) { 1413 try { 1414 r.thread.clearDnsCache(); 1415 } catch (RemoteException ex) { 1416 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1417 } 1418 } 1419 } 1420 } 1421 } break; 1422 case UPDATE_HTTP_PROXY_MSG: { 1423 ProxyInfo proxy = (ProxyInfo)msg.obj; 1424 String host = ""; 1425 String port = ""; 1426 String exclList = ""; 1427 Uri pacFileUrl = Uri.EMPTY; 1428 if (proxy != null) { 1429 host = proxy.getHost(); 1430 port = Integer.toString(proxy.getPort()); 1431 exclList = proxy.getExclusionListAsString(); 1432 pacFileUrl = proxy.getPacFileUrl(); 1433 } 1434 synchronized (ActivityManagerService.this) { 1435 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1436 ProcessRecord r = mLruProcesses.get(i); 1437 if (r.thread != null) { 1438 try { 1439 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1440 } catch (RemoteException ex) { 1441 Slog.w(TAG, "Failed to update http proxy for: " + 1442 r.info.processName); 1443 } 1444 } 1445 } 1446 } 1447 } break; 1448 case SHOW_UID_ERROR_MSG: { 1449 if (mShowDialogs) { 1450 AlertDialog d = new BaseErrorDialog(mContext); 1451 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1452 d.setCancelable(false); 1453 d.setTitle(mContext.getText(R.string.android_system_label)); 1454 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1455 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1456 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1457 d.show(); 1458 } 1459 } break; 1460 case SHOW_FINGERPRINT_ERROR_MSG: { 1461 if (mShowDialogs) { 1462 AlertDialog d = new BaseErrorDialog(mContext); 1463 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1464 d.setCancelable(false); 1465 d.setTitle(mContext.getText(R.string.android_system_label)); 1466 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1467 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1468 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1469 d.show(); 1470 } 1471 } break; 1472 case PROC_START_TIMEOUT_MSG: { 1473 if (mDidDexOpt) { 1474 mDidDexOpt = false; 1475 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1476 nmsg.obj = msg.obj; 1477 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1478 return; 1479 } 1480 ProcessRecord app = (ProcessRecord)msg.obj; 1481 synchronized (ActivityManagerService.this) { 1482 processStartTimedOutLocked(app); 1483 } 1484 } break; 1485 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1486 synchronized (ActivityManagerService.this) { 1487 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1488 } 1489 } break; 1490 case KILL_APPLICATION_MSG: { 1491 synchronized (ActivityManagerService.this) { 1492 int appid = msg.arg1; 1493 boolean restart = (msg.arg2 == 1); 1494 Bundle bundle = (Bundle)msg.obj; 1495 String pkg = bundle.getString("pkg"); 1496 String reason = bundle.getString("reason"); 1497 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1498 false, UserHandle.USER_ALL, reason); 1499 } 1500 } break; 1501 case FINALIZE_PENDING_INTENT_MSG: { 1502 ((PendingIntentRecord)msg.obj).completeFinalize(); 1503 } break; 1504 case POST_HEAVY_NOTIFICATION_MSG: { 1505 INotificationManager inm = NotificationManager.getService(); 1506 if (inm == null) { 1507 return; 1508 } 1509 1510 ActivityRecord root = (ActivityRecord)msg.obj; 1511 ProcessRecord process = root.app; 1512 if (process == null) { 1513 return; 1514 } 1515 1516 try { 1517 Context context = mContext.createPackageContext(process.info.packageName, 0); 1518 String text = mContext.getString(R.string.heavy_weight_notification, 1519 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1520 Notification notification = new Notification(); 1521 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1522 notification.when = 0; 1523 notification.flags = Notification.FLAG_ONGOING_EVENT; 1524 notification.tickerText = text; 1525 notification.defaults = 0; // please be quiet 1526 notification.sound = null; 1527 notification.vibrate = null; 1528 notification.color = mContext.getResources().getColor( 1529 com.android.internal.R.color.system_notification_accent_color); 1530 notification.setLatestEventInfo(context, text, 1531 mContext.getText(R.string.heavy_weight_notification_detail), 1532 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1533 PendingIntent.FLAG_CANCEL_CURRENT, null, 1534 new UserHandle(root.userId))); 1535 1536 try { 1537 int[] outId = new int[1]; 1538 inm.enqueueNotificationWithTag("android", "android", null, 1539 R.string.heavy_weight_notification, 1540 notification, outId, root.userId); 1541 } catch (RuntimeException e) { 1542 Slog.w(ActivityManagerService.TAG, 1543 "Error showing notification for heavy-weight app", e); 1544 } catch (RemoteException e) { 1545 } 1546 } catch (NameNotFoundException e) { 1547 Slog.w(TAG, "Unable to create context for heavy notification", e); 1548 } 1549 } break; 1550 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1551 INotificationManager inm = NotificationManager.getService(); 1552 if (inm == null) { 1553 return; 1554 } 1555 try { 1556 inm.cancelNotificationWithTag("android", null, 1557 R.string.heavy_weight_notification, msg.arg1); 1558 } catch (RuntimeException e) { 1559 Slog.w(ActivityManagerService.TAG, 1560 "Error canceling notification for service", e); 1561 } catch (RemoteException e) { 1562 } 1563 } break; 1564 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1565 synchronized (ActivityManagerService.this) { 1566 checkExcessivePowerUsageLocked(true); 1567 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1568 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1569 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1570 } 1571 } break; 1572 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1573 synchronized (ActivityManagerService.this) { 1574 ActivityRecord ar = (ActivityRecord)msg.obj; 1575 if (mCompatModeDialog != null) { 1576 if (mCompatModeDialog.mAppInfo.packageName.equals( 1577 ar.info.applicationInfo.packageName)) { 1578 return; 1579 } 1580 mCompatModeDialog.dismiss(); 1581 mCompatModeDialog = null; 1582 } 1583 if (ar != null && false) { 1584 if (mCompatModePackages.getPackageAskCompatModeLocked( 1585 ar.packageName)) { 1586 int mode = mCompatModePackages.computeCompatModeLocked( 1587 ar.info.applicationInfo); 1588 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1589 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1590 mCompatModeDialog = new CompatModeDialog( 1591 ActivityManagerService.this, mContext, 1592 ar.info.applicationInfo); 1593 mCompatModeDialog.show(); 1594 } 1595 } 1596 } 1597 } 1598 break; 1599 } 1600 case DISPATCH_PROCESSES_CHANGED: { 1601 dispatchProcessesChanged(); 1602 break; 1603 } 1604 case DISPATCH_PROCESS_DIED: { 1605 final int pid = msg.arg1; 1606 final int uid = msg.arg2; 1607 dispatchProcessDied(pid, uid); 1608 break; 1609 } 1610 case REPORT_MEM_USAGE_MSG: { 1611 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1612 Thread thread = new Thread() { 1613 @Override public void run() { 1614 reportMemUsage(memInfos); 1615 } 1616 }; 1617 thread.start(); 1618 break; 1619 } 1620 case START_USER_SWITCH_MSG: { 1621 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1622 break; 1623 } 1624 case REPORT_USER_SWITCH_MSG: { 1625 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1626 break; 1627 } 1628 case CONTINUE_USER_SWITCH_MSG: { 1629 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1630 break; 1631 } 1632 case USER_SWITCH_TIMEOUT_MSG: { 1633 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1634 break; 1635 } 1636 case IMMERSIVE_MODE_LOCK_MSG: { 1637 final boolean nextState = (msg.arg1 != 0); 1638 if (mUpdateLock.isHeld() != nextState) { 1639 if (DEBUG_IMMERSIVE) { 1640 final ActivityRecord r = (ActivityRecord) msg.obj; 1641 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1642 } 1643 if (nextState) { 1644 mUpdateLock.acquire(); 1645 } else { 1646 mUpdateLock.release(); 1647 } 1648 } 1649 break; 1650 } 1651 case PERSIST_URI_GRANTS_MSG: { 1652 writeGrantedUriPermissions(); 1653 break; 1654 } 1655 case REQUEST_ALL_PSS_MSG: { 1656 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1657 break; 1658 } 1659 case START_PROFILES_MSG: { 1660 synchronized (ActivityManagerService.this) { 1661 startProfilesLocked(); 1662 } 1663 break; 1664 } 1665 case UPDATE_TIME: { 1666 synchronized (ActivityManagerService.this) { 1667 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1668 ProcessRecord r = mLruProcesses.get(i); 1669 if (r.thread != null) { 1670 try { 1671 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1672 } catch (RemoteException ex) { 1673 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1674 } 1675 } 1676 } 1677 } 1678 break; 1679 } 1680 case SYSTEM_USER_START_MSG: { 1681 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1682 Integer.toString(msg.arg1), msg.arg1); 1683 mSystemServiceManager.startUser(msg.arg1); 1684 break; 1685 } 1686 case SYSTEM_USER_CURRENT_MSG: { 1687 mBatteryStatsService.noteEvent( 1688 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1689 Integer.toString(msg.arg2), msg.arg2); 1690 mBatteryStatsService.noteEvent( 1691 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1692 Integer.toString(msg.arg1), msg.arg1); 1693 mSystemServiceManager.switchUser(msg.arg1); 1694 break; 1695 } 1696 case ENTER_ANIMATION_COMPLETE_MSG: { 1697 synchronized (ActivityManagerService.this) { 1698 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1699 if (r != null && r.app != null && r.app.thread != null) { 1700 try { 1701 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1702 } catch (RemoteException e) { 1703 } 1704 } 1705 } 1706 break; 1707 } 1708 case FINISH_BOOTING_MSG: { 1709 if (msg.arg1 != 0) { 1710 finishBooting(); 1711 } 1712 if (msg.arg2 != 0) { 1713 enableScreenAfterBoot(); 1714 } 1715 break; 1716 } 1717 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1718 try { 1719 Locale l = (Locale) msg.obj; 1720 IBinder service = ServiceManager.getService("mount"); 1721 IMountService mountService = IMountService.Stub.asInterface(service); 1722 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1723 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1724 } catch (RemoteException e) { 1725 Log.e(TAG, "Error storing locale for decryption UI", e); 1726 } 1727 break; 1728 } 1729 case DISMISS_DIALOG_MSG: { 1730 final Dialog d = (Dialog) msg.obj; 1731 d.dismiss(); 1732 break; 1733 } 1734 } 1735 } 1736 }; 1737 1738 static final int COLLECT_PSS_BG_MSG = 1; 1739 1740 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1741 @Override 1742 public void handleMessage(Message msg) { 1743 switch (msg.what) { 1744 case COLLECT_PSS_BG_MSG: { 1745 long start = SystemClock.uptimeMillis(); 1746 MemInfoReader memInfo = null; 1747 synchronized (ActivityManagerService.this) { 1748 if (mFullPssPending) { 1749 mFullPssPending = false; 1750 memInfo = new MemInfoReader(); 1751 } 1752 } 1753 if (memInfo != null) { 1754 updateCpuStatsNow(); 1755 long nativeTotalPss = 0; 1756 synchronized (mProcessCpuTracker) { 1757 final int N = mProcessCpuTracker.countStats(); 1758 for (int j=0; j<N; j++) { 1759 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1760 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1761 // This is definitely an application process; skip it. 1762 continue; 1763 } 1764 synchronized (mPidsSelfLocked) { 1765 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1766 // This is one of our own processes; skip it. 1767 continue; 1768 } 1769 } 1770 nativeTotalPss += Debug.getPss(st.pid, null); 1771 } 1772 } 1773 memInfo.readMemInfo(); 1774 synchronized (ActivityManagerService.this) { 1775 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1776 + (SystemClock.uptimeMillis()-start) + "ms"); 1777 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1778 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1779 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1780 } 1781 } 1782 1783 int i = 0; 1784 int num = 0; 1785 long[] tmp = new long[1]; 1786 do { 1787 ProcessRecord proc; 1788 int procState; 1789 int pid; 1790 synchronized (ActivityManagerService.this) { 1791 if (i >= mPendingPssProcesses.size()) { 1792 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1793 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1794 mPendingPssProcesses.clear(); 1795 return; 1796 } 1797 proc = mPendingPssProcesses.get(i); 1798 procState = proc.pssProcState; 1799 if (proc.thread != null && procState == proc.setProcState) { 1800 pid = proc.pid; 1801 } else { 1802 proc = null; 1803 pid = 0; 1804 } 1805 i++; 1806 } 1807 if (proc != null) { 1808 long pss = Debug.getPss(pid, tmp); 1809 synchronized (ActivityManagerService.this) { 1810 if (proc.thread != null && proc.setProcState == procState 1811 && proc.pid == pid) { 1812 num++; 1813 proc.lastPssTime = SystemClock.uptimeMillis(); 1814 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1815 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1816 + ": " + pss + " lastPss=" + proc.lastPss 1817 + " state=" + ProcessList.makeProcStateString(procState)); 1818 if (proc.initialIdlePss == 0) { 1819 proc.initialIdlePss = pss; 1820 } 1821 proc.lastPss = pss; 1822 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1823 proc.lastCachedPss = pss; 1824 } 1825 } 1826 } 1827 } 1828 } while (true); 1829 } 1830 } 1831 } 1832 }; 1833 1834 public void setSystemProcess() { 1835 try { 1836 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1837 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1838 ServiceManager.addService("meminfo", new MemBinder(this)); 1839 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1840 ServiceManager.addService("dbinfo", new DbBinder(this)); 1841 if (MONITOR_CPU_USAGE) { 1842 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1843 } 1844 ServiceManager.addService("permission", new PermissionController(this)); 1845 1846 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1847 "android", STOCK_PM_FLAGS); 1848 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1849 1850 synchronized (this) { 1851 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1852 app.persistent = true; 1853 app.pid = MY_PID; 1854 app.maxAdj = ProcessList.SYSTEM_ADJ; 1855 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1856 mProcessNames.put(app.processName, app.uid, app); 1857 synchronized (mPidsSelfLocked) { 1858 mPidsSelfLocked.put(app.pid, app); 1859 } 1860 updateLruProcessLocked(app, false, null); 1861 updateOomAdjLocked(); 1862 } 1863 } catch (PackageManager.NameNotFoundException e) { 1864 throw new RuntimeException( 1865 "Unable to find android system package", e); 1866 } 1867 } 1868 1869 public void setWindowManager(WindowManagerService wm) { 1870 mWindowManager = wm; 1871 mStackSupervisor.setWindowManager(wm); 1872 } 1873 1874 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1875 mUsageStatsService = usageStatsManager; 1876 } 1877 1878 public void startObservingNativeCrashes() { 1879 final NativeCrashListener ncl = new NativeCrashListener(this); 1880 ncl.start(); 1881 } 1882 1883 public IAppOpsService getAppOpsService() { 1884 return mAppOpsService; 1885 } 1886 1887 static class MemBinder extends Binder { 1888 ActivityManagerService mActivityManagerService; 1889 MemBinder(ActivityManagerService activityManagerService) { 1890 mActivityManagerService = activityManagerService; 1891 } 1892 1893 @Override 1894 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1895 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1896 != PackageManager.PERMISSION_GRANTED) { 1897 pw.println("Permission Denial: can't dump meminfo from from pid=" 1898 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1899 + " without permission " + android.Manifest.permission.DUMP); 1900 return; 1901 } 1902 1903 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1904 } 1905 } 1906 1907 static class GraphicsBinder extends Binder { 1908 ActivityManagerService mActivityManagerService; 1909 GraphicsBinder(ActivityManagerService activityManagerService) { 1910 mActivityManagerService = activityManagerService; 1911 } 1912 1913 @Override 1914 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1915 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1916 != PackageManager.PERMISSION_GRANTED) { 1917 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1918 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1919 + " without permission " + android.Manifest.permission.DUMP); 1920 return; 1921 } 1922 1923 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1924 } 1925 } 1926 1927 static class DbBinder extends Binder { 1928 ActivityManagerService mActivityManagerService; 1929 DbBinder(ActivityManagerService activityManagerService) { 1930 mActivityManagerService = activityManagerService; 1931 } 1932 1933 @Override 1934 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1935 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1936 != PackageManager.PERMISSION_GRANTED) { 1937 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1938 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1939 + " without permission " + android.Manifest.permission.DUMP); 1940 return; 1941 } 1942 1943 mActivityManagerService.dumpDbInfo(fd, pw, args); 1944 } 1945 } 1946 1947 static class CpuBinder extends Binder { 1948 ActivityManagerService mActivityManagerService; 1949 CpuBinder(ActivityManagerService activityManagerService) { 1950 mActivityManagerService = activityManagerService; 1951 } 1952 1953 @Override 1954 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1955 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1956 != PackageManager.PERMISSION_GRANTED) { 1957 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1958 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1959 + " without permission " + android.Manifest.permission.DUMP); 1960 return; 1961 } 1962 1963 synchronized (mActivityManagerService.mProcessCpuTracker) { 1964 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1965 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1966 SystemClock.uptimeMillis())); 1967 } 1968 } 1969 } 1970 1971 public static final class Lifecycle extends SystemService { 1972 private final ActivityManagerService mService; 1973 1974 public Lifecycle(Context context) { 1975 super(context); 1976 mService = new ActivityManagerService(context); 1977 } 1978 1979 @Override 1980 public void onStart() { 1981 mService.start(); 1982 } 1983 1984 public ActivityManagerService getService() { 1985 return mService; 1986 } 1987 } 1988 1989 // Note: This method is invoked on the main thread but may need to attach various 1990 // handlers to other threads. So take care to be explicit about the looper. 1991 public ActivityManagerService(Context systemContext) { 1992 mContext = systemContext; 1993 mFactoryTest = FactoryTest.getMode(); 1994 mSystemThread = ActivityThread.currentActivityThread(); 1995 1996 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1997 1998 mHandlerThread = new ServiceThread(TAG, 1999 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2000 mHandlerThread.start(); 2001 mHandler = new MainHandler(mHandlerThread.getLooper()); 2002 2003 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2004 "foreground", BROADCAST_FG_TIMEOUT, false); 2005 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2006 "background", BROADCAST_BG_TIMEOUT, true); 2007 mBroadcastQueues[0] = mFgBroadcastQueue; 2008 mBroadcastQueues[1] = mBgBroadcastQueue; 2009 2010 mServices = new ActiveServices(this); 2011 mProviderMap = new ProviderMap(this); 2012 2013 // TODO: Move creation of battery stats service outside of activity manager service. 2014 File dataDir = Environment.getDataDirectory(); 2015 File systemDir = new File(dataDir, "system"); 2016 systemDir.mkdirs(); 2017 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2018 mBatteryStatsService.getActiveStatistics().readLocked(); 2019 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2020 mOnBattery = DEBUG_POWER ? true 2021 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2022 mBatteryStatsService.getActiveStatistics().setCallback(this); 2023 2024 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2025 2026 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2027 2028 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2029 2030 // User 0 is the first and only user that runs at boot. 2031 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2032 mUserLru.add(Integer.valueOf(0)); 2033 updateStartedUserArrayLocked(); 2034 2035 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2036 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2037 2038 mConfiguration.setToDefaults(); 2039 mConfiguration.setLocale(Locale.getDefault()); 2040 2041 mConfigurationSeq = mConfiguration.seq = 1; 2042 mProcessCpuTracker.init(); 2043 2044 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2045 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2046 mStackSupervisor = new ActivityStackSupervisor(this); 2047 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2048 2049 mProcessCpuThread = new Thread("CpuTracker") { 2050 @Override 2051 public void run() { 2052 while (true) { 2053 try { 2054 try { 2055 synchronized(this) { 2056 final long now = SystemClock.uptimeMillis(); 2057 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2058 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2059 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2060 // + ", write delay=" + nextWriteDelay); 2061 if (nextWriteDelay < nextCpuDelay) { 2062 nextCpuDelay = nextWriteDelay; 2063 } 2064 if (nextCpuDelay > 0) { 2065 mProcessCpuMutexFree.set(true); 2066 this.wait(nextCpuDelay); 2067 } 2068 } 2069 } catch (InterruptedException e) { 2070 } 2071 updateCpuStatsNow(); 2072 } catch (Exception e) { 2073 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2074 } 2075 } 2076 } 2077 }; 2078 2079 Watchdog.getInstance().addMonitor(this); 2080 Watchdog.getInstance().addThread(mHandler); 2081 } 2082 2083 public void setSystemServiceManager(SystemServiceManager mgr) { 2084 mSystemServiceManager = mgr; 2085 } 2086 2087 public void setInstaller(Installer installer) { 2088 mInstaller = installer; 2089 } 2090 2091 private void start() { 2092 Process.removeAllProcessGroups(); 2093 mProcessCpuThread.start(); 2094 2095 mBatteryStatsService.publish(mContext); 2096 mAppOpsService.publish(mContext); 2097 Slog.d("AppOps", "AppOpsService published"); 2098 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2099 } 2100 2101 public void initPowerManagement() { 2102 mStackSupervisor.initPowerManagement(); 2103 mBatteryStatsService.initPowerManagement(); 2104 } 2105 2106 @Override 2107 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2108 throws RemoteException { 2109 if (code == SYSPROPS_TRANSACTION) { 2110 // We need to tell all apps about the system property change. 2111 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2112 synchronized(this) { 2113 final int NP = mProcessNames.getMap().size(); 2114 for (int ip=0; ip<NP; ip++) { 2115 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2116 final int NA = apps.size(); 2117 for (int ia=0; ia<NA; ia++) { 2118 ProcessRecord app = apps.valueAt(ia); 2119 if (app.thread != null) { 2120 procs.add(app.thread.asBinder()); 2121 } 2122 } 2123 } 2124 } 2125 2126 int N = procs.size(); 2127 for (int i=0; i<N; i++) { 2128 Parcel data2 = Parcel.obtain(); 2129 try { 2130 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2131 } catch (RemoteException e) { 2132 } 2133 data2.recycle(); 2134 } 2135 } 2136 try { 2137 return super.onTransact(code, data, reply, flags); 2138 } catch (RuntimeException e) { 2139 // The activity manager only throws security exceptions, so let's 2140 // log all others. 2141 if (!(e instanceof SecurityException)) { 2142 Slog.wtf(TAG, "Activity Manager Crash", e); 2143 } 2144 throw e; 2145 } 2146 } 2147 2148 void updateCpuStats() { 2149 final long now = SystemClock.uptimeMillis(); 2150 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2151 return; 2152 } 2153 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2154 synchronized (mProcessCpuThread) { 2155 mProcessCpuThread.notify(); 2156 } 2157 } 2158 } 2159 2160 void updateCpuStatsNow() { 2161 synchronized (mProcessCpuTracker) { 2162 mProcessCpuMutexFree.set(false); 2163 final long now = SystemClock.uptimeMillis(); 2164 boolean haveNewCpuStats = false; 2165 2166 if (MONITOR_CPU_USAGE && 2167 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2168 mLastCpuTime.set(now); 2169 haveNewCpuStats = true; 2170 mProcessCpuTracker.update(); 2171 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2172 //Slog.i(TAG, "Total CPU usage: " 2173 // + mProcessCpu.getTotalCpuPercent() + "%"); 2174 2175 // Slog the cpu usage if the property is set. 2176 if ("true".equals(SystemProperties.get("events.cpu"))) { 2177 int user = mProcessCpuTracker.getLastUserTime(); 2178 int system = mProcessCpuTracker.getLastSystemTime(); 2179 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2180 int irq = mProcessCpuTracker.getLastIrqTime(); 2181 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2182 int idle = mProcessCpuTracker.getLastIdleTime(); 2183 2184 int total = user + system + iowait + irq + softIrq + idle; 2185 if (total == 0) total = 1; 2186 2187 EventLog.writeEvent(EventLogTags.CPU, 2188 ((user+system+iowait+irq+softIrq) * 100) / total, 2189 (user * 100) / total, 2190 (system * 100) / total, 2191 (iowait * 100) / total, 2192 (irq * 100) / total, 2193 (softIrq * 100) / total); 2194 } 2195 } 2196 2197 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2198 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2199 synchronized(bstats) { 2200 synchronized(mPidsSelfLocked) { 2201 if (haveNewCpuStats) { 2202 if (mOnBattery) { 2203 int perc = bstats.startAddingCpuLocked(); 2204 int totalUTime = 0; 2205 int totalSTime = 0; 2206 final int N = mProcessCpuTracker.countStats(); 2207 for (int i=0; i<N; i++) { 2208 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2209 if (!st.working) { 2210 continue; 2211 } 2212 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2213 int otherUTime = (st.rel_utime*perc)/100; 2214 int otherSTime = (st.rel_stime*perc)/100; 2215 totalUTime += otherUTime; 2216 totalSTime += otherSTime; 2217 if (pr != null) { 2218 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2219 if (ps == null || !ps.isActive()) { 2220 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2221 pr.info.uid, pr.processName); 2222 } 2223 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2224 st.rel_stime-otherSTime); 2225 ps.addSpeedStepTimes(cpuSpeedTimes); 2226 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2227 } else { 2228 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2229 if (ps == null || !ps.isActive()) { 2230 st.batteryStats = ps = bstats.getProcessStatsLocked( 2231 bstats.mapUid(st.uid), st.name); 2232 } 2233 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2234 st.rel_stime-otherSTime); 2235 ps.addSpeedStepTimes(cpuSpeedTimes); 2236 } 2237 } 2238 bstats.finishAddingCpuLocked(perc, totalUTime, 2239 totalSTime, cpuSpeedTimes); 2240 } 2241 } 2242 } 2243 2244 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2245 mLastWriteTime = now; 2246 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2247 } 2248 } 2249 } 2250 } 2251 2252 @Override 2253 public void batteryNeedsCpuUpdate() { 2254 updateCpuStatsNow(); 2255 } 2256 2257 @Override 2258 public void batteryPowerChanged(boolean onBattery) { 2259 // When plugging in, update the CPU stats first before changing 2260 // the plug state. 2261 updateCpuStatsNow(); 2262 synchronized (this) { 2263 synchronized(mPidsSelfLocked) { 2264 mOnBattery = DEBUG_POWER ? true : onBattery; 2265 } 2266 } 2267 } 2268 2269 /** 2270 * Initialize the application bind args. These are passed to each 2271 * process when the bindApplication() IPC is sent to the process. They're 2272 * lazily setup to make sure the services are running when they're asked for. 2273 */ 2274 private HashMap<String, IBinder> getCommonServicesLocked() { 2275 if (mAppBindArgs == null) { 2276 mAppBindArgs = new HashMap<String, IBinder>(); 2277 2278 // Setup the application init args 2279 mAppBindArgs.put("package", ServiceManager.getService("package")); 2280 mAppBindArgs.put("window", ServiceManager.getService("window")); 2281 mAppBindArgs.put(Context.ALARM_SERVICE, 2282 ServiceManager.getService(Context.ALARM_SERVICE)); 2283 } 2284 return mAppBindArgs; 2285 } 2286 2287 final void setFocusedActivityLocked(ActivityRecord r) { 2288 if (mFocusedActivity != r) { 2289 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2290 mFocusedActivity = r; 2291 if (r.task != null && r.task.voiceInteractor != null) { 2292 startRunningVoiceLocked(); 2293 } else { 2294 finishRunningVoiceLocked(); 2295 } 2296 mStackSupervisor.setFocusedStack(r); 2297 if (r != null) { 2298 mWindowManager.setFocusedApp(r.appToken, true); 2299 } 2300 applyUpdateLockStateLocked(r); 2301 } 2302 } 2303 2304 final void clearFocusedActivity(ActivityRecord r) { 2305 if (mFocusedActivity == r) { 2306 mFocusedActivity = null; 2307 } 2308 } 2309 2310 @Override 2311 public void setFocusedStack(int stackId) { 2312 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2313 synchronized (ActivityManagerService.this) { 2314 ActivityStack stack = mStackSupervisor.getStack(stackId); 2315 if (stack != null) { 2316 ActivityRecord r = stack.topRunningActivityLocked(null); 2317 if (r != null) { 2318 setFocusedActivityLocked(r); 2319 } 2320 } 2321 } 2322 } 2323 2324 @Override 2325 public void notifyActivityDrawn(IBinder token) { 2326 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2327 synchronized (this) { 2328 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2329 if (r != null) { 2330 r.task.stack.notifyActivityDrawnLocked(r); 2331 } 2332 } 2333 } 2334 2335 final void applyUpdateLockStateLocked(ActivityRecord r) { 2336 // Modifications to the UpdateLock state are done on our handler, outside 2337 // the activity manager's locks. The new state is determined based on the 2338 // state *now* of the relevant activity record. The object is passed to 2339 // the handler solely for logging detail, not to be consulted/modified. 2340 final boolean nextState = r != null && r.immersive; 2341 mHandler.sendMessage( 2342 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2343 } 2344 2345 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2346 Message msg = Message.obtain(); 2347 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2348 msg.obj = r.task.askedCompatMode ? null : r; 2349 mHandler.sendMessage(msg); 2350 } 2351 2352 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2353 String what, Object obj, ProcessRecord srcApp) { 2354 app.lastActivityTime = now; 2355 2356 if (app.activities.size() > 0) { 2357 // Don't want to touch dependent processes that are hosting activities. 2358 return index; 2359 } 2360 2361 int lrui = mLruProcesses.lastIndexOf(app); 2362 if (lrui < 0) { 2363 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2364 + what + " " + obj + " from " + srcApp); 2365 return index; 2366 } 2367 2368 if (lrui >= index) { 2369 // Don't want to cause this to move dependent processes *back* in the 2370 // list as if they were less frequently used. 2371 return index; 2372 } 2373 2374 if (lrui >= mLruProcessActivityStart) { 2375 // Don't want to touch dependent processes that are hosting activities. 2376 return index; 2377 } 2378 2379 mLruProcesses.remove(lrui); 2380 if (index > 0) { 2381 index--; 2382 } 2383 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2384 + " in LRU list: " + app); 2385 mLruProcesses.add(index, app); 2386 return index; 2387 } 2388 2389 final void removeLruProcessLocked(ProcessRecord app) { 2390 int lrui = mLruProcesses.lastIndexOf(app); 2391 if (lrui >= 0) { 2392 if (!app.killed) { 2393 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2394 Process.killProcessQuiet(app.pid); 2395 Process.killProcessGroup(app.info.uid, app.pid); 2396 } 2397 if (lrui <= mLruProcessActivityStart) { 2398 mLruProcessActivityStart--; 2399 } 2400 if (lrui <= mLruProcessServiceStart) { 2401 mLruProcessServiceStart--; 2402 } 2403 mLruProcesses.remove(lrui); 2404 } 2405 } 2406 2407 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2408 ProcessRecord client) { 2409 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2410 || app.treatLikeActivity; 2411 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2412 if (!activityChange && hasActivity) { 2413 // The process has activities, so we are only allowing activity-based adjustments 2414 // to move it. It should be kept in the front of the list with other 2415 // processes that have activities, and we don't want those to change their 2416 // order except due to activity operations. 2417 return; 2418 } 2419 2420 mLruSeq++; 2421 final long now = SystemClock.uptimeMillis(); 2422 app.lastActivityTime = now; 2423 2424 // First a quick reject: if the app is already at the position we will 2425 // put it, then there is nothing to do. 2426 if (hasActivity) { 2427 final int N = mLruProcesses.size(); 2428 if (N > 0 && mLruProcesses.get(N-1) == app) { 2429 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2430 return; 2431 } 2432 } else { 2433 if (mLruProcessServiceStart > 0 2434 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2435 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2436 return; 2437 } 2438 } 2439 2440 int lrui = mLruProcesses.lastIndexOf(app); 2441 2442 if (app.persistent && lrui >= 0) { 2443 // We don't care about the position of persistent processes, as long as 2444 // they are in the list. 2445 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2446 return; 2447 } 2448 2449 /* In progress: compute new position first, so we can avoid doing work 2450 if the process is not actually going to move. Not yet working. 2451 int addIndex; 2452 int nextIndex; 2453 boolean inActivity = false, inService = false; 2454 if (hasActivity) { 2455 // Process has activities, put it at the very tipsy-top. 2456 addIndex = mLruProcesses.size(); 2457 nextIndex = mLruProcessServiceStart; 2458 inActivity = true; 2459 } else if (hasService) { 2460 // Process has services, put it at the top of the service list. 2461 addIndex = mLruProcessActivityStart; 2462 nextIndex = mLruProcessServiceStart; 2463 inActivity = true; 2464 inService = true; 2465 } else { 2466 // Process not otherwise of interest, it goes to the top of the non-service area. 2467 addIndex = mLruProcessServiceStart; 2468 if (client != null) { 2469 int clientIndex = mLruProcesses.lastIndexOf(client); 2470 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2471 + app); 2472 if (clientIndex >= 0 && addIndex > clientIndex) { 2473 addIndex = clientIndex; 2474 } 2475 } 2476 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2477 } 2478 2479 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2480 + mLruProcessActivityStart + "): " + app); 2481 */ 2482 2483 if (lrui >= 0) { 2484 if (lrui < mLruProcessActivityStart) { 2485 mLruProcessActivityStart--; 2486 } 2487 if (lrui < mLruProcessServiceStart) { 2488 mLruProcessServiceStart--; 2489 } 2490 /* 2491 if (addIndex > lrui) { 2492 addIndex--; 2493 } 2494 if (nextIndex > lrui) { 2495 nextIndex--; 2496 } 2497 */ 2498 mLruProcesses.remove(lrui); 2499 } 2500 2501 /* 2502 mLruProcesses.add(addIndex, app); 2503 if (inActivity) { 2504 mLruProcessActivityStart++; 2505 } 2506 if (inService) { 2507 mLruProcessActivityStart++; 2508 } 2509 */ 2510 2511 int nextIndex; 2512 if (hasActivity) { 2513 final int N = mLruProcesses.size(); 2514 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2515 // Process doesn't have activities, but has clients with 2516 // activities... move it up, but one below the top (the top 2517 // should always have a real activity). 2518 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2519 mLruProcesses.add(N-1, app); 2520 // To keep it from spamming the LRU list (by making a bunch of clients), 2521 // we will push down any other entries owned by the app. 2522 final int uid = app.info.uid; 2523 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2524 ProcessRecord subProc = mLruProcesses.get(i); 2525 if (subProc.info.uid == uid) { 2526 // We want to push this one down the list. If the process after 2527 // it is for the same uid, however, don't do so, because we don't 2528 // want them internally to be re-ordered. 2529 if (mLruProcesses.get(i-1).info.uid != uid) { 2530 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2531 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2532 ProcessRecord tmp = mLruProcesses.get(i); 2533 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2534 mLruProcesses.set(i-1, tmp); 2535 i--; 2536 } 2537 } else { 2538 // A gap, we can stop here. 2539 break; 2540 } 2541 } 2542 } else { 2543 // Process has activities, put it at the very tipsy-top. 2544 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2545 mLruProcesses.add(app); 2546 } 2547 nextIndex = mLruProcessServiceStart; 2548 } else if (hasService) { 2549 // Process has services, put it at the top of the service list. 2550 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2551 mLruProcesses.add(mLruProcessActivityStart, app); 2552 nextIndex = mLruProcessServiceStart; 2553 mLruProcessActivityStart++; 2554 } else { 2555 // Process not otherwise of interest, it goes to the top of the non-service area. 2556 int index = mLruProcessServiceStart; 2557 if (client != null) { 2558 // If there is a client, don't allow the process to be moved up higher 2559 // in the list than that client. 2560 int clientIndex = mLruProcesses.lastIndexOf(client); 2561 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2562 + " when updating " + app); 2563 if (clientIndex <= lrui) { 2564 // Don't allow the client index restriction to push it down farther in the 2565 // list than it already is. 2566 clientIndex = lrui; 2567 } 2568 if (clientIndex >= 0 && index > clientIndex) { 2569 index = clientIndex; 2570 } 2571 } 2572 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2573 mLruProcesses.add(index, app); 2574 nextIndex = index-1; 2575 mLruProcessActivityStart++; 2576 mLruProcessServiceStart++; 2577 } 2578 2579 // If the app is currently using a content provider or service, 2580 // bump those processes as well. 2581 for (int j=app.connections.size()-1; j>=0; j--) { 2582 ConnectionRecord cr = app.connections.valueAt(j); 2583 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2584 && cr.binding.service.app != null 2585 && cr.binding.service.app.lruSeq != mLruSeq 2586 && !cr.binding.service.app.persistent) { 2587 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2588 "service connection", cr, app); 2589 } 2590 } 2591 for (int j=app.conProviders.size()-1; j>=0; j--) { 2592 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2593 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2594 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2595 "provider reference", cpr, app); 2596 } 2597 } 2598 } 2599 2600 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2601 if (uid == Process.SYSTEM_UID) { 2602 // The system gets to run in any process. If there are multiple 2603 // processes with the same uid, just pick the first (this 2604 // should never happen). 2605 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2606 if (procs == null) return null; 2607 final int N = procs.size(); 2608 for (int i = 0; i < N; i++) { 2609 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2610 } 2611 } 2612 ProcessRecord proc = mProcessNames.get(processName, uid); 2613 if (false && proc != null && !keepIfLarge 2614 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2615 && proc.lastCachedPss >= 4000) { 2616 // Turn this condition on to cause killing to happen regularly, for testing. 2617 if (proc.baseProcessTracker != null) { 2618 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2619 } 2620 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2621 } else if (proc != null && !keepIfLarge 2622 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2623 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2624 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2625 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2626 if (proc.baseProcessTracker != null) { 2627 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2628 } 2629 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2630 } 2631 } 2632 return proc; 2633 } 2634 2635 void ensurePackageDexOpt(String packageName) { 2636 IPackageManager pm = AppGlobals.getPackageManager(); 2637 try { 2638 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2639 mDidDexOpt = true; 2640 } 2641 } catch (RemoteException e) { 2642 } 2643 } 2644 2645 boolean isNextTransitionForward() { 2646 int transit = mWindowManager.getPendingAppTransition(); 2647 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2648 || transit == AppTransition.TRANSIT_TASK_OPEN 2649 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2650 } 2651 2652 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2653 String processName, String abiOverride, int uid, Runnable crashHandler) { 2654 synchronized(this) { 2655 ApplicationInfo info = new ApplicationInfo(); 2656 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2657 // For isolated processes, the former contains the parent's uid and the latter the 2658 // actual uid of the isolated process. 2659 // In the special case introduced by this method (which is, starting an isolated 2660 // process directly from the SystemServer without an actual parent app process) the 2661 // closest thing to a parent's uid is SYSTEM_UID. 2662 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2663 // the |isolated| logic in the ProcessRecord constructor. 2664 info.uid = Process.SYSTEM_UID; 2665 info.processName = processName; 2666 info.className = entryPoint; 2667 info.packageName = "android"; 2668 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2669 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2670 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2671 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2672 crashHandler); 2673 return proc != null ? proc.pid : 0; 2674 } 2675 } 2676 2677 final ProcessRecord startProcessLocked(String processName, 2678 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2679 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2680 boolean isolated, boolean keepIfLarge) { 2681 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2682 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2683 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2684 null /* crashHandler */); 2685 } 2686 2687 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2688 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2689 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2690 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2691 long startTime = SystemClock.elapsedRealtime(); 2692 ProcessRecord app; 2693 if (!isolated) { 2694 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2695 checkTime(startTime, "startProcess: after getProcessRecord"); 2696 } else { 2697 // If this is an isolated process, it can't re-use an existing process. 2698 app = null; 2699 } 2700 // We don't have to do anything more if: 2701 // (1) There is an existing application record; and 2702 // (2) The caller doesn't think it is dead, OR there is no thread 2703 // object attached to it so we know it couldn't have crashed; and 2704 // (3) There is a pid assigned to it, so it is either starting or 2705 // already running. 2706 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2707 + " app=" + app + " knownToBeDead=" + knownToBeDead 2708 + " thread=" + (app != null ? app.thread : null) 2709 + " pid=" + (app != null ? app.pid : -1)); 2710 if (app != null && app.pid > 0) { 2711 if (!knownToBeDead || app.thread == null) { 2712 // We already have the app running, or are waiting for it to 2713 // come up (we have a pid but not yet its thread), so keep it. 2714 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2715 // If this is a new package in the process, add the package to the list 2716 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2717 checkTime(startTime, "startProcess: done, added package to proc"); 2718 return app; 2719 } 2720 2721 // An application record is attached to a previous process, 2722 // clean it up now. 2723 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2724 checkTime(startTime, "startProcess: bad proc running, killing"); 2725 Process.killProcessGroup(app.info.uid, app.pid); 2726 handleAppDiedLocked(app, true, true); 2727 checkTime(startTime, "startProcess: done killing old proc"); 2728 } 2729 2730 String hostingNameStr = hostingName != null 2731 ? hostingName.flattenToShortString() : null; 2732 2733 if (!isolated) { 2734 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2735 // If we are in the background, then check to see if this process 2736 // is bad. If so, we will just silently fail. 2737 if (mBadProcesses.get(info.processName, info.uid) != null) { 2738 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2739 + "/" + info.processName); 2740 return null; 2741 } 2742 } else { 2743 // When the user is explicitly starting a process, then clear its 2744 // crash count so that we won't make it bad until they see at 2745 // least one crash dialog again, and make the process good again 2746 // if it had been bad. 2747 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2748 + "/" + info.processName); 2749 mProcessCrashTimes.remove(info.processName, info.uid); 2750 if (mBadProcesses.get(info.processName, info.uid) != null) { 2751 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2752 UserHandle.getUserId(info.uid), info.uid, 2753 info.processName); 2754 mBadProcesses.remove(info.processName, info.uid); 2755 if (app != null) { 2756 app.bad = false; 2757 } 2758 } 2759 } 2760 } 2761 2762 if (app == null) { 2763 checkTime(startTime, "startProcess: creating new process record"); 2764 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2765 app.crashHandler = crashHandler; 2766 if (app == null) { 2767 Slog.w(TAG, "Failed making new process record for " 2768 + processName + "/" + info.uid + " isolated=" + isolated); 2769 return null; 2770 } 2771 mProcessNames.put(processName, app.uid, app); 2772 if (isolated) { 2773 mIsolatedProcesses.put(app.uid, app); 2774 } 2775 checkTime(startTime, "startProcess: done creating new process record"); 2776 } else { 2777 // If this is a new package in the process, add the package to the list 2778 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2779 checkTime(startTime, "startProcess: added package to existing proc"); 2780 } 2781 2782 // If the system is not ready yet, then hold off on starting this 2783 // process until it is. 2784 if (!mProcessesReady 2785 && !isAllowedWhileBooting(info) 2786 && !allowWhileBooting) { 2787 if (!mProcessesOnHold.contains(app)) { 2788 mProcessesOnHold.add(app); 2789 } 2790 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2791 checkTime(startTime, "startProcess: returning with proc on hold"); 2792 return app; 2793 } 2794 2795 checkTime(startTime, "startProcess: stepping in to startProcess"); 2796 startProcessLocked( 2797 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2798 checkTime(startTime, "startProcess: done starting proc!"); 2799 return (app.pid != 0) ? app : null; 2800 } 2801 2802 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2803 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2804 } 2805 2806 private final void startProcessLocked(ProcessRecord app, 2807 String hostingType, String hostingNameStr) { 2808 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2809 null /* entryPoint */, null /* entryPointArgs */); 2810 } 2811 2812 private final void startProcessLocked(ProcessRecord app, String hostingType, 2813 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2814 long startTime = SystemClock.elapsedRealtime(); 2815 if (app.pid > 0 && app.pid != MY_PID) { 2816 checkTime(startTime, "startProcess: removing from pids map"); 2817 synchronized (mPidsSelfLocked) { 2818 mPidsSelfLocked.remove(app.pid); 2819 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2820 } 2821 checkTime(startTime, "startProcess: done removing from pids map"); 2822 app.setPid(0); 2823 } 2824 2825 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2826 "startProcessLocked removing on hold: " + app); 2827 mProcessesOnHold.remove(app); 2828 2829 checkTime(startTime, "startProcess: starting to update cpu stats"); 2830 updateCpuStats(); 2831 checkTime(startTime, "startProcess: done updating cpu stats"); 2832 2833 try { 2834 int uid = app.uid; 2835 2836 int[] gids = null; 2837 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2838 if (!app.isolated) { 2839 int[] permGids = null; 2840 try { 2841 checkTime(startTime, "startProcess: getting gids from package manager"); 2842 final PackageManager pm = mContext.getPackageManager(); 2843 permGids = pm.getPackageGids(app.info.packageName); 2844 2845 if (Environment.isExternalStorageEmulated()) { 2846 checkTime(startTime, "startProcess: checking external storage perm"); 2847 if (pm.checkPermission( 2848 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2849 app.info.packageName) == PERMISSION_GRANTED) { 2850 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2851 } else { 2852 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2853 } 2854 } 2855 } catch (PackageManager.NameNotFoundException e) { 2856 Slog.w(TAG, "Unable to retrieve gids", e); 2857 } 2858 2859 /* 2860 * Add shared application and profile GIDs so applications can share some 2861 * resources like shared libraries and access user-wide resources 2862 */ 2863 if (permGids == null) { 2864 gids = new int[2]; 2865 } else { 2866 gids = new int[permGids.length + 2]; 2867 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2868 } 2869 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2870 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2871 } 2872 checkTime(startTime, "startProcess: building args"); 2873 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2874 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2875 && mTopComponent != null 2876 && app.processName.equals(mTopComponent.getPackageName())) { 2877 uid = 0; 2878 } 2879 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2880 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2881 uid = 0; 2882 } 2883 } 2884 int debugFlags = 0; 2885 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2886 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2887 // Also turn on CheckJNI for debuggable apps. It's quite 2888 // awkward to turn on otherwise. 2889 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2890 } 2891 // Run the app in safe mode if its manifest requests so or the 2892 // system is booted in safe mode. 2893 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2894 mSafeMode == true) { 2895 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2896 } 2897 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2899 } 2900 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2902 } 2903 if ("1".equals(SystemProperties.get("debug.assert"))) { 2904 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2905 } 2906 2907 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2908 if (requiredAbi == null) { 2909 requiredAbi = Build.SUPPORTED_ABIS[0]; 2910 } 2911 2912 String instructionSet = null; 2913 if (app.info.primaryCpuAbi != null) { 2914 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2915 } 2916 2917 // Start the process. It will either succeed and return a result containing 2918 // the PID of the new process, or else throw a RuntimeException. 2919 boolean isActivityProcess = (entryPoint == null); 2920 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2921 checkTime(startTime, "startProcess: asking zygote to start proc"); 2922 Process.ProcessStartResult startResult = Process.start(entryPoint, 2923 app.processName, uid, uid, gids, debugFlags, mountExternal, 2924 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2925 app.info.dataDir, entryPointArgs); 2926 checkTime(startTime, "startProcess: returned from zygote!"); 2927 2928 if (app.isolated) { 2929 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2930 } 2931 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2932 checkTime(startTime, "startProcess: done updating battery stats"); 2933 2934 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2935 UserHandle.getUserId(uid), startResult.pid, uid, 2936 app.processName, hostingType, 2937 hostingNameStr != null ? hostingNameStr : ""); 2938 2939 if (app.persistent) { 2940 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2941 } 2942 2943 checkTime(startTime, "startProcess: building log message"); 2944 StringBuilder buf = mStringBuilder; 2945 buf.setLength(0); 2946 buf.append("Start proc "); 2947 buf.append(app.processName); 2948 if (!isActivityProcess) { 2949 buf.append(" ["); 2950 buf.append(entryPoint); 2951 buf.append("]"); 2952 } 2953 buf.append(" for "); 2954 buf.append(hostingType); 2955 if (hostingNameStr != null) { 2956 buf.append(" "); 2957 buf.append(hostingNameStr); 2958 } 2959 buf.append(": pid="); 2960 buf.append(startResult.pid); 2961 buf.append(" uid="); 2962 buf.append(uid); 2963 buf.append(" gids={"); 2964 if (gids != null) { 2965 for (int gi=0; gi<gids.length; gi++) { 2966 if (gi != 0) buf.append(", "); 2967 buf.append(gids[gi]); 2968 2969 } 2970 } 2971 buf.append("}"); 2972 if (requiredAbi != null) { 2973 buf.append(" abi="); 2974 buf.append(requiredAbi); 2975 } 2976 Slog.i(TAG, buf.toString()); 2977 app.setPid(startResult.pid); 2978 app.usingWrapper = startResult.usingWrapper; 2979 app.removed = false; 2980 app.killed = false; 2981 app.killedByAm = false; 2982 checkTime(startTime, "startProcess: starting to update pids map"); 2983 synchronized (mPidsSelfLocked) { 2984 this.mPidsSelfLocked.put(startResult.pid, app); 2985 if (isActivityProcess) { 2986 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2987 msg.obj = app; 2988 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2989 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2990 } 2991 } 2992 checkTime(startTime, "startProcess: done updating pids map"); 2993 } catch (RuntimeException e) { 2994 // XXX do better error recovery. 2995 app.setPid(0); 2996 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 2997 if (app.isolated) { 2998 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 2999 } 3000 Slog.e(TAG, "Failure starting process " + app.processName, e); 3001 } 3002 } 3003 3004 void updateUsageStats(ActivityRecord component, boolean resumed) { 3005 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3006 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3007 if (resumed) { 3008 if (mUsageStatsService != null) { 3009 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3010 UsageEvents.Event.MOVE_TO_FOREGROUND); 3011 } 3012 synchronized (stats) { 3013 stats.noteActivityResumedLocked(component.app.uid); 3014 } 3015 } else { 3016 if (mUsageStatsService != null) { 3017 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3018 UsageEvents.Event.MOVE_TO_BACKGROUND); 3019 } 3020 synchronized (stats) { 3021 stats.noteActivityPausedLocked(component.app.uid); 3022 } 3023 } 3024 } 3025 3026 Intent getHomeIntent() { 3027 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3028 intent.setComponent(mTopComponent); 3029 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3030 intent.addCategory(Intent.CATEGORY_HOME); 3031 } 3032 return intent; 3033 } 3034 3035 boolean startHomeActivityLocked(int userId) { 3036 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3037 && mTopAction == null) { 3038 // We are running in factory test mode, but unable to find 3039 // the factory test app, so just sit around displaying the 3040 // error message and don't try to start anything. 3041 return false; 3042 } 3043 Intent intent = getHomeIntent(); 3044 ActivityInfo aInfo = 3045 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3046 if (aInfo != null) { 3047 intent.setComponent(new ComponentName( 3048 aInfo.applicationInfo.packageName, aInfo.name)); 3049 // Don't do this if the home app is currently being 3050 // instrumented. 3051 aInfo = new ActivityInfo(aInfo); 3052 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3053 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3054 aInfo.applicationInfo.uid, true); 3055 if (app == null || app.instrumentationClass == null) { 3056 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3057 mStackSupervisor.startHomeActivity(intent, aInfo); 3058 } 3059 } 3060 3061 return true; 3062 } 3063 3064 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3065 ActivityInfo ai = null; 3066 ComponentName comp = intent.getComponent(); 3067 try { 3068 if (comp != null) { 3069 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3070 } else { 3071 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3072 intent, 3073 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3074 flags, userId); 3075 3076 if (info != null) { 3077 ai = info.activityInfo; 3078 } 3079 } 3080 } catch (RemoteException e) { 3081 // ignore 3082 } 3083 3084 return ai; 3085 } 3086 3087 /** 3088 * Starts the "new version setup screen" if appropriate. 3089 */ 3090 void startSetupActivityLocked() { 3091 // Only do this once per boot. 3092 if (mCheckedForSetup) { 3093 return; 3094 } 3095 3096 // We will show this screen if the current one is a different 3097 // version than the last one shown, and we are not running in 3098 // low-level factory test mode. 3099 final ContentResolver resolver = mContext.getContentResolver(); 3100 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3101 Settings.Global.getInt(resolver, 3102 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3103 mCheckedForSetup = true; 3104 3105 // See if we should be showing the platform update setup UI. 3106 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3107 List<ResolveInfo> ris = mContext.getPackageManager() 3108 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3109 3110 // We don't allow third party apps to replace this. 3111 ResolveInfo ri = null; 3112 for (int i=0; ris != null && i<ris.size(); i++) { 3113 if ((ris.get(i).activityInfo.applicationInfo.flags 3114 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3115 ri = ris.get(i); 3116 break; 3117 } 3118 } 3119 3120 if (ri != null) { 3121 String vers = ri.activityInfo.metaData != null 3122 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3123 : null; 3124 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3125 vers = ri.activityInfo.applicationInfo.metaData.getString( 3126 Intent.METADATA_SETUP_VERSION); 3127 } 3128 String lastVers = Settings.Secure.getString( 3129 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3130 if (vers != null && !vers.equals(lastVers)) { 3131 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3132 intent.setComponent(new ComponentName( 3133 ri.activityInfo.packageName, ri.activityInfo.name)); 3134 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3135 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3136 null); 3137 } 3138 } 3139 } 3140 } 3141 3142 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3143 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3144 } 3145 3146 void enforceNotIsolatedCaller(String caller) { 3147 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3148 throw new SecurityException("Isolated process not allowed to call " + caller); 3149 } 3150 } 3151 3152 void enforceShellRestriction(String restriction, int userHandle) { 3153 if (Binder.getCallingUid() == Process.SHELL_UID) { 3154 if (userHandle < 0 3155 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3156 throw new SecurityException("Shell does not have permission to access user " 3157 + userHandle); 3158 } 3159 } 3160 } 3161 3162 @Override 3163 public int getFrontActivityScreenCompatMode() { 3164 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3165 synchronized (this) { 3166 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3167 } 3168 } 3169 3170 @Override 3171 public void setFrontActivityScreenCompatMode(int mode) { 3172 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3173 "setFrontActivityScreenCompatMode"); 3174 synchronized (this) { 3175 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3176 } 3177 } 3178 3179 @Override 3180 public int getPackageScreenCompatMode(String packageName) { 3181 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3182 synchronized (this) { 3183 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3184 } 3185 } 3186 3187 @Override 3188 public void setPackageScreenCompatMode(String packageName, int mode) { 3189 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3190 "setPackageScreenCompatMode"); 3191 synchronized (this) { 3192 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3193 } 3194 } 3195 3196 @Override 3197 public boolean getPackageAskScreenCompat(String packageName) { 3198 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3199 synchronized (this) { 3200 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3201 } 3202 } 3203 3204 @Override 3205 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3206 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3207 "setPackageAskScreenCompat"); 3208 synchronized (this) { 3209 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3210 } 3211 } 3212 3213 private void dispatchProcessesChanged() { 3214 int N; 3215 synchronized (this) { 3216 N = mPendingProcessChanges.size(); 3217 if (mActiveProcessChanges.length < N) { 3218 mActiveProcessChanges = new ProcessChangeItem[N]; 3219 } 3220 mPendingProcessChanges.toArray(mActiveProcessChanges); 3221 mAvailProcessChanges.addAll(mPendingProcessChanges); 3222 mPendingProcessChanges.clear(); 3223 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3224 } 3225 3226 int i = mProcessObservers.beginBroadcast(); 3227 while (i > 0) { 3228 i--; 3229 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3230 if (observer != null) { 3231 try { 3232 for (int j=0; j<N; j++) { 3233 ProcessChangeItem item = mActiveProcessChanges[j]; 3234 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3235 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3236 + item.pid + " uid=" + item.uid + ": " 3237 + item.foregroundActivities); 3238 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3239 item.foregroundActivities); 3240 } 3241 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3242 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3243 + item.pid + " uid=" + item.uid + ": " + item.processState); 3244 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3245 } 3246 } 3247 } catch (RemoteException e) { 3248 } 3249 } 3250 } 3251 mProcessObservers.finishBroadcast(); 3252 } 3253 3254 private void dispatchProcessDied(int pid, int uid) { 3255 int i = mProcessObservers.beginBroadcast(); 3256 while (i > 0) { 3257 i--; 3258 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3259 if (observer != null) { 3260 try { 3261 observer.onProcessDied(pid, uid); 3262 } catch (RemoteException e) { 3263 } 3264 } 3265 } 3266 mProcessObservers.finishBroadcast(); 3267 } 3268 3269 @Override 3270 public final int startActivity(IApplicationThread caller, String callingPackage, 3271 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3272 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3273 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3274 resultWho, requestCode, startFlags, profilerInfo, options, 3275 UserHandle.getCallingUserId()); 3276 } 3277 3278 @Override 3279 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3280 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3281 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3282 enforceNotIsolatedCaller("startActivity"); 3283 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3284 false, ALLOW_FULL_ONLY, "startActivity", null); 3285 // TODO: Switch to user app stacks here. 3286 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3287 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3288 profilerInfo, null, null, options, userId, null, null); 3289 } 3290 3291 @Override 3292 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3293 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3294 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3295 3296 // This is very dangerous -- it allows you to perform a start activity (including 3297 // permission grants) as any app that may launch one of your own activities. So 3298 // we will only allow this to be done from activities that are part of the core framework, 3299 // and then only when they are running as the system. 3300 final ActivityRecord sourceRecord; 3301 final int targetUid; 3302 final String targetPackage; 3303 synchronized (this) { 3304 if (resultTo == null) { 3305 throw new SecurityException("Must be called from an activity"); 3306 } 3307 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3308 if (sourceRecord == null) { 3309 throw new SecurityException("Called with bad activity token: " + resultTo); 3310 } 3311 if (!sourceRecord.info.packageName.equals("android")) { 3312 throw new SecurityException( 3313 "Must be called from an activity that is declared in the android package"); 3314 } 3315 if (sourceRecord.app == null) { 3316 throw new SecurityException("Called without a process attached to activity"); 3317 } 3318 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3319 // This is still okay, as long as this activity is running under the 3320 // uid of the original calling activity. 3321 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3322 throw new SecurityException( 3323 "Calling activity in uid " + sourceRecord.app.uid 3324 + " must be system uid or original calling uid " 3325 + sourceRecord.launchedFromUid); 3326 } 3327 } 3328 targetUid = sourceRecord.launchedFromUid; 3329 targetPackage = sourceRecord.launchedFromPackage; 3330 } 3331 3332 if (userId == UserHandle.USER_NULL) { 3333 userId = UserHandle.getUserId(sourceRecord.app.uid); 3334 } 3335 3336 // TODO: Switch to user app stacks here. 3337 try { 3338 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3339 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3340 null, null, options, userId, null, null); 3341 return ret; 3342 } catch (SecurityException e) { 3343 // XXX need to figure out how to propagate to original app. 3344 // A SecurityException here is generally actually a fault of the original 3345 // calling activity (such as a fairly granting permissions), so propagate it 3346 // back to them. 3347 /* 3348 StringBuilder msg = new StringBuilder(); 3349 msg.append("While launching"); 3350 msg.append(intent.toString()); 3351 msg.append(": "); 3352 msg.append(e.getMessage()); 3353 */ 3354 throw e; 3355 } 3356 } 3357 3358 @Override 3359 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3360 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3361 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3362 enforceNotIsolatedCaller("startActivityAndWait"); 3363 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3364 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3365 WaitResult res = new WaitResult(); 3366 // TODO: Switch to user app stacks here. 3367 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3368 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3369 options, userId, null, null); 3370 return res; 3371 } 3372 3373 @Override 3374 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3375 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3376 int startFlags, Configuration config, Bundle options, int userId) { 3377 enforceNotIsolatedCaller("startActivityWithConfig"); 3378 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3379 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3380 // TODO: Switch to user app stacks here. 3381 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3382 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3383 null, null, config, options, userId, null, null); 3384 return ret; 3385 } 3386 3387 @Override 3388 public int startActivityIntentSender(IApplicationThread caller, 3389 IntentSender intent, Intent fillInIntent, String resolvedType, 3390 IBinder resultTo, String resultWho, int requestCode, 3391 int flagsMask, int flagsValues, Bundle options) { 3392 enforceNotIsolatedCaller("startActivityIntentSender"); 3393 // Refuse possible leaked file descriptors 3394 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3395 throw new IllegalArgumentException("File descriptors passed in Intent"); 3396 } 3397 3398 IIntentSender sender = intent.getTarget(); 3399 if (!(sender instanceof PendingIntentRecord)) { 3400 throw new IllegalArgumentException("Bad PendingIntent object"); 3401 } 3402 3403 PendingIntentRecord pir = (PendingIntentRecord)sender; 3404 3405 synchronized (this) { 3406 // If this is coming from the currently resumed activity, it is 3407 // effectively saying that app switches are allowed at this point. 3408 final ActivityStack stack = getFocusedStack(); 3409 if (stack.mResumedActivity != null && 3410 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3411 mAppSwitchesAllowedTime = 0; 3412 } 3413 } 3414 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3415 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3416 return ret; 3417 } 3418 3419 @Override 3420 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3421 Intent intent, String resolvedType, IVoiceInteractionSession session, 3422 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3423 Bundle options, int userId) { 3424 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3425 != PackageManager.PERMISSION_GRANTED) { 3426 String msg = "Permission Denial: startVoiceActivity() from pid=" 3427 + Binder.getCallingPid() 3428 + ", uid=" + Binder.getCallingUid() 3429 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3430 Slog.w(TAG, msg); 3431 throw new SecurityException(msg); 3432 } 3433 if (session == null || interactor == null) { 3434 throw new NullPointerException("null session or interactor"); 3435 } 3436 userId = handleIncomingUser(callingPid, callingUid, userId, 3437 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3438 // TODO: Switch to user app stacks here. 3439 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3440 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3441 null, options, userId, null, null); 3442 } 3443 3444 @Override 3445 public boolean startNextMatchingActivity(IBinder callingActivity, 3446 Intent intent, Bundle options) { 3447 // Refuse possible leaked file descriptors 3448 if (intent != null && intent.hasFileDescriptors() == true) { 3449 throw new IllegalArgumentException("File descriptors passed in Intent"); 3450 } 3451 3452 synchronized (this) { 3453 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3454 if (r == null) { 3455 ActivityOptions.abort(options); 3456 return false; 3457 } 3458 if (r.app == null || r.app.thread == null) { 3459 // The caller is not running... d'oh! 3460 ActivityOptions.abort(options); 3461 return false; 3462 } 3463 intent = new Intent(intent); 3464 // The caller is not allowed to change the data. 3465 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3466 // And we are resetting to find the next component... 3467 intent.setComponent(null); 3468 3469 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3470 3471 ActivityInfo aInfo = null; 3472 try { 3473 List<ResolveInfo> resolves = 3474 AppGlobals.getPackageManager().queryIntentActivities( 3475 intent, r.resolvedType, 3476 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3477 UserHandle.getCallingUserId()); 3478 3479 // Look for the original activity in the list... 3480 final int N = resolves != null ? resolves.size() : 0; 3481 for (int i=0; i<N; i++) { 3482 ResolveInfo rInfo = resolves.get(i); 3483 if (rInfo.activityInfo.packageName.equals(r.packageName) 3484 && rInfo.activityInfo.name.equals(r.info.name)) { 3485 // We found the current one... the next matching is 3486 // after it. 3487 i++; 3488 if (i<N) { 3489 aInfo = resolves.get(i).activityInfo; 3490 } 3491 if (debug) { 3492 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3493 + "/" + r.info.name); 3494 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3495 + "/" + aInfo.name); 3496 } 3497 break; 3498 } 3499 } 3500 } catch (RemoteException e) { 3501 } 3502 3503 if (aInfo == null) { 3504 // Nobody who is next! 3505 ActivityOptions.abort(options); 3506 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3507 return false; 3508 } 3509 3510 intent.setComponent(new ComponentName( 3511 aInfo.applicationInfo.packageName, aInfo.name)); 3512 intent.setFlags(intent.getFlags()&~( 3513 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3514 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3515 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3516 Intent.FLAG_ACTIVITY_NEW_TASK)); 3517 3518 // Okay now we need to start the new activity, replacing the 3519 // currently running activity. This is a little tricky because 3520 // we want to start the new one as if the current one is finished, 3521 // but not finish the current one first so that there is no flicker. 3522 // And thus... 3523 final boolean wasFinishing = r.finishing; 3524 r.finishing = true; 3525 3526 // Propagate reply information over to the new activity. 3527 final ActivityRecord resultTo = r.resultTo; 3528 final String resultWho = r.resultWho; 3529 final int requestCode = r.requestCode; 3530 r.resultTo = null; 3531 if (resultTo != null) { 3532 resultTo.removeResultsLocked(r, resultWho, requestCode); 3533 } 3534 3535 final long origId = Binder.clearCallingIdentity(); 3536 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3537 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3538 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3539 -1, r.launchedFromUid, 0, options, false, null, null, null); 3540 Binder.restoreCallingIdentity(origId); 3541 3542 r.finishing = wasFinishing; 3543 if (res != ActivityManager.START_SUCCESS) { 3544 return false; 3545 } 3546 return true; 3547 } 3548 } 3549 3550 @Override 3551 public final int startActivityFromRecents(int taskId, Bundle options) { 3552 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3553 String msg = "Permission Denial: startActivityFromRecents called without " + 3554 START_TASKS_FROM_RECENTS; 3555 Slog.w(TAG, msg); 3556 throw new SecurityException(msg); 3557 } 3558 return startActivityFromRecentsInner(taskId, options); 3559 } 3560 3561 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3562 final TaskRecord task; 3563 final int callingUid; 3564 final String callingPackage; 3565 final Intent intent; 3566 final int userId; 3567 synchronized (this) { 3568 task = recentTaskForIdLocked(taskId); 3569 if (task == null) { 3570 throw new IllegalArgumentException("Task " + taskId + " not found."); 3571 } 3572 callingUid = task.mCallingUid; 3573 callingPackage = task.mCallingPackage; 3574 intent = task.intent; 3575 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3576 userId = task.userId; 3577 } 3578 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3579 options, userId, null, task); 3580 } 3581 3582 final int startActivityInPackage(int uid, String callingPackage, 3583 Intent intent, String resolvedType, IBinder resultTo, 3584 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3585 IActivityContainer container, TaskRecord inTask) { 3586 3587 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3588 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3589 3590 // TODO: Switch to user app stacks here. 3591 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3592 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3593 null, null, null, options, userId, container, inTask); 3594 return ret; 3595 } 3596 3597 @Override 3598 public final int startActivities(IApplicationThread caller, String callingPackage, 3599 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3600 int userId) { 3601 enforceNotIsolatedCaller("startActivities"); 3602 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3603 false, ALLOW_FULL_ONLY, "startActivity", null); 3604 // TODO: Switch to user app stacks here. 3605 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3606 resolvedTypes, resultTo, options, userId); 3607 return ret; 3608 } 3609 3610 final int startActivitiesInPackage(int uid, String callingPackage, 3611 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3612 Bundle options, int userId) { 3613 3614 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3615 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3616 // TODO: Switch to user app stacks here. 3617 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3618 resultTo, options, userId); 3619 return ret; 3620 } 3621 3622 //explicitly remove thd old information in mRecentTasks when removing existing user. 3623 private void removeRecentTasksForUserLocked(int userId) { 3624 if(userId <= 0) { 3625 Slog.i(TAG, "Can't remove recent task on user " + userId); 3626 return; 3627 } 3628 3629 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3630 TaskRecord tr = mRecentTasks.get(i); 3631 if (tr.userId == userId) { 3632 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3633 + " when finishing user" + userId); 3634 mRecentTasks.remove(i); 3635 tr.removedFromRecents(mTaskPersister); 3636 } 3637 } 3638 3639 // Remove tasks from persistent storage. 3640 mTaskPersister.wakeup(null, true); 3641 } 3642 3643 // Sort by taskId 3644 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3645 @Override 3646 public int compare(TaskRecord lhs, TaskRecord rhs) { 3647 return rhs.taskId - lhs.taskId; 3648 } 3649 }; 3650 3651 // Extract the affiliates of the chain containing mRecentTasks[start]. 3652 private int processNextAffiliateChain(int start) { 3653 final TaskRecord startTask = mRecentTasks.get(start); 3654 final int affiliateId = startTask.mAffiliatedTaskId; 3655 3656 // Quick identification of isolated tasks. I.e. those not launched behind. 3657 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3658 startTask.mNextAffiliate == null) { 3659 // There is still a slim chance that there are other tasks that point to this task 3660 // and that the chain is so messed up that this task no longer points to them but 3661 // the gain of this optimization outweighs the risk. 3662 startTask.inRecents = true; 3663 return start + 1; 3664 } 3665 3666 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3667 mTmpRecents.clear(); 3668 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3669 final TaskRecord task = mRecentTasks.get(i); 3670 if (task.mAffiliatedTaskId == affiliateId) { 3671 mRecentTasks.remove(i); 3672 mTmpRecents.add(task); 3673 } 3674 } 3675 3676 // Sort them all by taskId. That is the order they were create in and that order will 3677 // always be correct. 3678 Collections.sort(mTmpRecents, mTaskRecordComparator); 3679 3680 // Go through and fix up the linked list. 3681 // The first one is the end of the chain and has no next. 3682 final TaskRecord first = mTmpRecents.get(0); 3683 first.inRecents = true; 3684 if (first.mNextAffiliate != null) { 3685 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3686 first.setNextAffiliate(null); 3687 mTaskPersister.wakeup(first, false); 3688 } 3689 // Everything in the middle is doubly linked from next to prev. 3690 final int tmpSize = mTmpRecents.size(); 3691 for (int i = 0; i < tmpSize - 1; ++i) { 3692 final TaskRecord next = mTmpRecents.get(i); 3693 final TaskRecord prev = mTmpRecents.get(i + 1); 3694 if (next.mPrevAffiliate != prev) { 3695 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3696 " setting prev=" + prev); 3697 next.setPrevAffiliate(prev); 3698 mTaskPersister.wakeup(next, false); 3699 } 3700 if (prev.mNextAffiliate != next) { 3701 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3702 " setting next=" + next); 3703 prev.setNextAffiliate(next); 3704 mTaskPersister.wakeup(prev, false); 3705 } 3706 prev.inRecents = true; 3707 } 3708 // The last one is the beginning of the list and has no prev. 3709 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3710 if (last.mPrevAffiliate != null) { 3711 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3712 last.setPrevAffiliate(null); 3713 mTaskPersister.wakeup(last, false); 3714 } 3715 3716 // Insert the group back into mRecentTasks at start. 3717 mRecentTasks.addAll(start, mTmpRecents); 3718 3719 // Let the caller know where we left off. 3720 return start + tmpSize; 3721 } 3722 3723 /** 3724 * Update the recent tasks lists: make sure tasks should still be here (their 3725 * applications / activities still exist), update their availability, fixup ordering 3726 * of affiliations. 3727 */ 3728 void cleanupRecentTasksLocked(int userId) { 3729 if (mRecentTasks == null) { 3730 // Happens when called from the packagemanager broadcast before boot. 3731 return; 3732 } 3733 3734 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3735 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3736 final IPackageManager pm = AppGlobals.getPackageManager(); 3737 final ActivityInfo dummyAct = new ActivityInfo(); 3738 final ApplicationInfo dummyApp = new ApplicationInfo(); 3739 3740 int N = mRecentTasks.size(); 3741 3742 int[] users = userId == UserHandle.USER_ALL 3743 ? getUsersLocked() : new int[] { userId }; 3744 for (int user : users) { 3745 for (int i = 0; i < N; i++) { 3746 TaskRecord task = mRecentTasks.get(i); 3747 if (task.userId != user) { 3748 // Only look at tasks for the user ID of interest. 3749 continue; 3750 } 3751 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3752 // This situation is broken, and we should just get rid of it now. 3753 mRecentTasks.remove(i); 3754 task.removedFromRecents(mTaskPersister); 3755 i--; 3756 N--; 3757 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3758 continue; 3759 } 3760 // Check whether this activity is currently available. 3761 if (task.realActivity != null) { 3762 ActivityInfo ai = availActCache.get(task.realActivity); 3763 if (ai == null) { 3764 try { 3765 ai = pm.getActivityInfo(task.realActivity, 3766 PackageManager.GET_UNINSTALLED_PACKAGES 3767 | PackageManager.GET_DISABLED_COMPONENTS, user); 3768 } catch (RemoteException e) { 3769 // Will never happen. 3770 continue; 3771 } 3772 if (ai == null) { 3773 ai = dummyAct; 3774 } 3775 availActCache.put(task.realActivity, ai); 3776 } 3777 if (ai == dummyAct) { 3778 // This could be either because the activity no longer exists, or the 3779 // app is temporarily gone. For the former we want to remove the recents 3780 // entry; for the latter we want to mark it as unavailable. 3781 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3782 if (app == null) { 3783 try { 3784 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3785 PackageManager.GET_UNINSTALLED_PACKAGES 3786 | PackageManager.GET_DISABLED_COMPONENTS, user); 3787 } catch (RemoteException e) { 3788 // Will never happen. 3789 continue; 3790 } 3791 if (app == null) { 3792 app = dummyApp; 3793 } 3794 availAppCache.put(task.realActivity.getPackageName(), app); 3795 } 3796 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3797 // Doesn't exist any more! Good-bye. 3798 mRecentTasks.remove(i); 3799 task.removedFromRecents(mTaskPersister); 3800 i--; 3801 N--; 3802 Slog.w(TAG, "Removing no longer valid recent: " + task); 3803 continue; 3804 } else { 3805 // Otherwise just not available for now. 3806 if (task.isAvailable) { 3807 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3808 + task); 3809 } 3810 task.isAvailable = false; 3811 } 3812 } else { 3813 if (!ai.enabled || !ai.applicationInfo.enabled 3814 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3815 if (task.isAvailable) { 3816 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3817 + task + " (enabled=" + ai.enabled + "/" 3818 + ai.applicationInfo.enabled + " flags=" 3819 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3820 } 3821 task.isAvailable = false; 3822 } else { 3823 if (!task.isAvailable) { 3824 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3825 + task); 3826 } 3827 task.isAvailable = true; 3828 } 3829 } 3830 } 3831 } 3832 } 3833 3834 // Verify the affiliate chain for each task. 3835 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3836 } 3837 3838 mTmpRecents.clear(); 3839 // mRecentTasks is now in sorted, affiliated order. 3840 } 3841 3842 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3843 int N = mRecentTasks.size(); 3844 TaskRecord top = task; 3845 int topIndex = taskIndex; 3846 while (top.mNextAffiliate != null && topIndex > 0) { 3847 top = top.mNextAffiliate; 3848 topIndex--; 3849 } 3850 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3851 + topIndex + " from intial " + taskIndex); 3852 // Find the end of the chain, doing a sanity check along the way. 3853 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3854 int endIndex = topIndex; 3855 TaskRecord prev = top; 3856 while (endIndex < N) { 3857 TaskRecord cur = mRecentTasks.get(endIndex); 3858 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3859 + endIndex + " " + cur); 3860 if (cur == top) { 3861 // Verify start of the chain. 3862 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3863 Slog.wtf(TAG, "Bad chain @" + endIndex 3864 + ": first task has next affiliate: " + prev); 3865 sane = false; 3866 break; 3867 } 3868 } else { 3869 // Verify middle of the chain's next points back to the one before. 3870 if (cur.mNextAffiliate != prev 3871 || cur.mNextAffiliateTaskId != prev.taskId) { 3872 Slog.wtf(TAG, "Bad chain @" + endIndex 3873 + ": middle task " + cur + " @" + endIndex 3874 + " has bad next affiliate " 3875 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3876 + ", expected " + prev); 3877 sane = false; 3878 break; 3879 } 3880 } 3881 if (cur.mPrevAffiliateTaskId == -1) { 3882 // Chain ends here. 3883 if (cur.mPrevAffiliate != null) { 3884 Slog.wtf(TAG, "Bad chain @" + endIndex 3885 + ": last task " + cur + " has previous affiliate " 3886 + cur.mPrevAffiliate); 3887 sane = false; 3888 } 3889 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3890 break; 3891 } else { 3892 // Verify middle of the chain's prev points to a valid item. 3893 if (cur.mPrevAffiliate == null) { 3894 Slog.wtf(TAG, "Bad chain @" + endIndex 3895 + ": task " + cur + " has previous affiliate " 3896 + cur.mPrevAffiliate + " but should be id " 3897 + cur.mPrevAffiliate); 3898 sane = false; 3899 break; 3900 } 3901 } 3902 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3903 Slog.wtf(TAG, "Bad chain @" + endIndex 3904 + ": task " + cur + " has affiliated id " 3905 + cur.mAffiliatedTaskId + " but should be " 3906 + task.mAffiliatedTaskId); 3907 sane = false; 3908 break; 3909 } 3910 prev = cur; 3911 endIndex++; 3912 if (endIndex >= N) { 3913 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3914 + ": last task " + prev); 3915 sane = false; 3916 break; 3917 } 3918 } 3919 if (sane) { 3920 if (endIndex < taskIndex) { 3921 Slog.wtf(TAG, "Bad chain @" + endIndex 3922 + ": did not extend to task " + task + " @" + taskIndex); 3923 sane = false; 3924 } 3925 } 3926 if (sane) { 3927 // All looks good, we can just move all of the affiliated tasks 3928 // to the top. 3929 for (int i=topIndex; i<=endIndex; i++) { 3930 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3931 + " from " + i + " to " + (i-topIndex)); 3932 TaskRecord cur = mRecentTasks.remove(i); 3933 mRecentTasks.add(i-topIndex, cur); 3934 } 3935 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3936 + " to " + endIndex); 3937 return true; 3938 } 3939 3940 // Whoops, couldn't do it. 3941 return false; 3942 } 3943 3944 final void addRecentTaskLocked(TaskRecord task) { 3945 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3946 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3947 3948 int N = mRecentTasks.size(); 3949 // Quick case: check if the top-most recent task is the same. 3950 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3951 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 3952 return; 3953 } 3954 // Another quick case: check if this is part of a set of affiliated 3955 // tasks that are at the top. 3956 if (isAffiliated && N > 0 && task.inRecents 3957 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 3958 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 3959 + " at top when adding " + task); 3960 return; 3961 } 3962 // Another quick case: never add voice sessions. 3963 if (task.voiceSession != null) { 3964 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 3965 return; 3966 } 3967 3968 boolean needAffiliationFix = false; 3969 3970 // Slightly less quick case: the task is already in recents, so all we need 3971 // to do is move it. 3972 if (task.inRecents) { 3973 int taskIndex = mRecentTasks.indexOf(task); 3974 if (taskIndex >= 0) { 3975 if (!isAffiliated) { 3976 // Simple case: this is not an affiliated task, so we just move it to the front. 3977 mRecentTasks.remove(taskIndex); 3978 mRecentTasks.add(0, task); 3979 notifyTaskPersisterLocked(task, false); 3980 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 3981 + " from " + taskIndex); 3982 return; 3983 } else { 3984 // More complicated: need to keep all affiliated tasks together. 3985 if (moveAffiliatedTasksToFront(task, taskIndex)) { 3986 // All went well. 3987 return; 3988 } 3989 3990 // Uh oh... something bad in the affiliation chain, try to rebuild 3991 // everything and then go through our general path of adding a new task. 3992 needAffiliationFix = true; 3993 } 3994 } else { 3995 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 3996 needAffiliationFix = true; 3997 } 3998 } 3999 4000 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4001 trimRecentsForTask(task, true); 4002 4003 N = mRecentTasks.size(); 4004 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4005 final TaskRecord tr = mRecentTasks.remove(N - 1); 4006 tr.removedFromRecents(mTaskPersister); 4007 N--; 4008 } 4009 task.inRecents = true; 4010 if (!isAffiliated || needAffiliationFix) { 4011 // If this is a simple non-affiliated task, or we had some failure trying to 4012 // handle it as part of an affilated task, then just place it at the top. 4013 mRecentTasks.add(0, task); 4014 } else if (isAffiliated) { 4015 // If this is a new affiliated task, then move all of the affiliated tasks 4016 // to the front and insert this new one. 4017 TaskRecord other = task.mNextAffiliate; 4018 if (other == null) { 4019 other = task.mPrevAffiliate; 4020 } 4021 if (other != null) { 4022 int otherIndex = mRecentTasks.indexOf(other); 4023 if (otherIndex >= 0) { 4024 // Insert new task at appropriate location. 4025 int taskIndex; 4026 if (other == task.mNextAffiliate) { 4027 // We found the index of our next affiliation, which is who is 4028 // before us in the list, so add after that point. 4029 taskIndex = otherIndex+1; 4030 } else { 4031 // We found the index of our previous affiliation, which is who is 4032 // after us in the list, so add at their position. 4033 taskIndex = otherIndex; 4034 } 4035 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4036 + taskIndex + ": " + task); 4037 mRecentTasks.add(taskIndex, task); 4038 4039 // Now move everything to the front. 4040 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4041 // All went well. 4042 return; 4043 } 4044 4045 // Uh oh... something bad in the affiliation chain, try to rebuild 4046 // everything and then go through our general path of adding a new task. 4047 needAffiliationFix = true; 4048 } else { 4049 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4050 + other); 4051 needAffiliationFix = true; 4052 } 4053 } else { 4054 if (DEBUG_RECENTS) Slog.d(TAG, 4055 "addRecent: adding affiliated task without next/prev:" + task); 4056 needAffiliationFix = true; 4057 } 4058 } 4059 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4060 4061 if (needAffiliationFix) { 4062 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4063 cleanupRecentTasksLocked(task.userId); 4064 } 4065 } 4066 4067 /** 4068 * If needed, remove oldest existing entries in recents that are for the same kind 4069 * of task as the given one. 4070 */ 4071 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4072 int N = mRecentTasks.size(); 4073 final Intent intent = task.intent; 4074 final boolean document = intent != null && intent.isDocument(); 4075 4076 int maxRecents = task.maxRecents - 1; 4077 for (int i=0; i<N; i++) { 4078 final TaskRecord tr = mRecentTasks.get(i); 4079 if (task != tr) { 4080 if (task.userId != tr.userId) { 4081 continue; 4082 } 4083 if (i > MAX_RECENT_BITMAPS) { 4084 tr.freeLastThumbnail(); 4085 } 4086 final Intent trIntent = tr.intent; 4087 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4088 (intent == null || !intent.filterEquals(trIntent))) { 4089 continue; 4090 } 4091 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4092 if (document && trIsDocument) { 4093 // These are the same document activity (not necessarily the same doc). 4094 if (maxRecents > 0) { 4095 --maxRecents; 4096 continue; 4097 } 4098 // Hit the maximum number of documents for this task. Fall through 4099 // and remove this document from recents. 4100 } else if (document || trIsDocument) { 4101 // Only one of these is a document. Not the droid we're looking for. 4102 continue; 4103 } 4104 } 4105 4106 if (!doTrim) { 4107 // If the caller is not actually asking for a trim, just tell them we reached 4108 // a point where the trim would happen. 4109 return i; 4110 } 4111 4112 // Either task and tr are the same or, their affinities match or their intents match 4113 // and neither of them is a document, or they are documents using the same activity 4114 // and their maxRecents has been reached. 4115 tr.disposeThumbnail(); 4116 mRecentTasks.remove(i); 4117 if (task != tr) { 4118 tr.removedFromRecents(mTaskPersister); 4119 } 4120 i--; 4121 N--; 4122 if (task.intent == null) { 4123 // If the new recent task we are adding is not fully 4124 // specified, then replace it with the existing recent task. 4125 task = tr; 4126 } 4127 notifyTaskPersisterLocked(tr, false); 4128 } 4129 4130 return -1; 4131 } 4132 4133 @Override 4134 public void reportActivityFullyDrawn(IBinder token) { 4135 synchronized (this) { 4136 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4137 if (r == null) { 4138 return; 4139 } 4140 r.reportFullyDrawnLocked(); 4141 } 4142 } 4143 4144 @Override 4145 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4146 synchronized (this) { 4147 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4148 if (r == null) { 4149 return; 4150 } 4151 final long origId = Binder.clearCallingIdentity(); 4152 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4153 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4154 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4155 if (config != null) { 4156 r.frozenBeforeDestroy = true; 4157 if (!updateConfigurationLocked(config, r, false, false)) { 4158 mStackSupervisor.resumeTopActivitiesLocked(); 4159 } 4160 } 4161 Binder.restoreCallingIdentity(origId); 4162 } 4163 } 4164 4165 @Override 4166 public int getRequestedOrientation(IBinder token) { 4167 synchronized (this) { 4168 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4169 if (r == null) { 4170 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4171 } 4172 return mWindowManager.getAppOrientation(r.appToken); 4173 } 4174 } 4175 4176 /** 4177 * This is the internal entry point for handling Activity.finish(). 4178 * 4179 * @param token The Binder token referencing the Activity we want to finish. 4180 * @param resultCode Result code, if any, from this Activity. 4181 * @param resultData Result data (Intent), if any, from this Activity. 4182 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4183 * the root Activity in the task. 4184 * 4185 * @return Returns true if the activity successfully finished, or false if it is still running. 4186 */ 4187 @Override 4188 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4189 boolean finishTask) { 4190 // Refuse possible leaked file descriptors 4191 if (resultData != null && resultData.hasFileDescriptors() == true) { 4192 throw new IllegalArgumentException("File descriptors passed in Intent"); 4193 } 4194 4195 synchronized(this) { 4196 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4197 if (r == null) { 4198 return true; 4199 } 4200 // Keep track of the root activity of the task before we finish it 4201 TaskRecord tr = r.task; 4202 ActivityRecord rootR = tr.getRootActivity(); 4203 if (rootR == null) { 4204 Slog.w(TAG, "Finishing task with all activities already finished"); 4205 } 4206 // Do not allow task to finish in Lock Task mode. 4207 if (tr == mStackSupervisor.mLockTaskModeTask) { 4208 if (rootR == r) { 4209 Slog.i(TAG, "Not finishing task in lock task mode"); 4210 mStackSupervisor.showLockTaskToast(); 4211 return false; 4212 } 4213 } 4214 if (mController != null) { 4215 // Find the first activity that is not finishing. 4216 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4217 if (next != null) { 4218 // ask watcher if this is allowed 4219 boolean resumeOK = true; 4220 try { 4221 resumeOK = mController.activityResuming(next.packageName); 4222 } catch (RemoteException e) { 4223 mController = null; 4224 Watchdog.getInstance().setActivityController(null); 4225 } 4226 4227 if (!resumeOK) { 4228 Slog.i(TAG, "Not finishing activity because controller resumed"); 4229 return false; 4230 } 4231 } 4232 } 4233 final long origId = Binder.clearCallingIdentity(); 4234 try { 4235 boolean res; 4236 if (finishTask && r == rootR) { 4237 // If requested, remove the task that is associated to this activity only if it 4238 // was the root activity in the task. The result code and data is ignored 4239 // because we don't support returning them across task boundaries. 4240 res = removeTaskByIdLocked(tr.taskId, false); 4241 if (!res) { 4242 Slog.i(TAG, "Removing task failed to finish activity"); 4243 } 4244 } else { 4245 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4246 resultData, "app-request", true); 4247 if (!res) { 4248 Slog.i(TAG, "Failed to finish by app-request"); 4249 } 4250 } 4251 return res; 4252 } finally { 4253 Binder.restoreCallingIdentity(origId); 4254 } 4255 } 4256 } 4257 4258 @Override 4259 public final void finishHeavyWeightApp() { 4260 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4261 != PackageManager.PERMISSION_GRANTED) { 4262 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4263 + Binder.getCallingPid() 4264 + ", uid=" + Binder.getCallingUid() 4265 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4266 Slog.w(TAG, msg); 4267 throw new SecurityException(msg); 4268 } 4269 4270 synchronized(this) { 4271 if (mHeavyWeightProcess == null) { 4272 return; 4273 } 4274 4275 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4276 mHeavyWeightProcess.activities); 4277 for (int i=0; i<activities.size(); i++) { 4278 ActivityRecord r = activities.get(i); 4279 if (!r.finishing) { 4280 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4281 null, "finish-heavy", true); 4282 } 4283 } 4284 4285 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4286 mHeavyWeightProcess.userId, 0)); 4287 mHeavyWeightProcess = null; 4288 } 4289 } 4290 4291 @Override 4292 public void crashApplication(int uid, int initialPid, String packageName, 4293 String message) { 4294 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4295 != PackageManager.PERMISSION_GRANTED) { 4296 String msg = "Permission Denial: crashApplication() from pid=" 4297 + Binder.getCallingPid() 4298 + ", uid=" + Binder.getCallingUid() 4299 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4300 Slog.w(TAG, msg); 4301 throw new SecurityException(msg); 4302 } 4303 4304 synchronized(this) { 4305 ProcessRecord proc = null; 4306 4307 // Figure out which process to kill. We don't trust that initialPid 4308 // still has any relation to current pids, so must scan through the 4309 // list. 4310 synchronized (mPidsSelfLocked) { 4311 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4312 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4313 if (p.uid != uid) { 4314 continue; 4315 } 4316 if (p.pid == initialPid) { 4317 proc = p; 4318 break; 4319 } 4320 if (p.pkgList.containsKey(packageName)) { 4321 proc = p; 4322 } 4323 } 4324 } 4325 4326 if (proc == null) { 4327 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4328 + " initialPid=" + initialPid 4329 + " packageName=" + packageName); 4330 return; 4331 } 4332 4333 if (proc.thread != null) { 4334 if (proc.pid == Process.myPid()) { 4335 Log.w(TAG, "crashApplication: trying to crash self!"); 4336 return; 4337 } 4338 long ident = Binder.clearCallingIdentity(); 4339 try { 4340 proc.thread.scheduleCrash(message); 4341 } catch (RemoteException e) { 4342 } 4343 Binder.restoreCallingIdentity(ident); 4344 } 4345 } 4346 } 4347 4348 @Override 4349 public final void finishSubActivity(IBinder token, String resultWho, 4350 int requestCode) { 4351 synchronized(this) { 4352 final long origId = Binder.clearCallingIdentity(); 4353 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4354 if (r != null) { 4355 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4356 } 4357 Binder.restoreCallingIdentity(origId); 4358 } 4359 } 4360 4361 @Override 4362 public boolean finishActivityAffinity(IBinder token) { 4363 synchronized(this) { 4364 final long origId = Binder.clearCallingIdentity(); 4365 try { 4366 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4367 4368 ActivityRecord rootR = r.task.getRootActivity(); 4369 // Do not allow task to finish in Lock Task mode. 4370 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4371 if (rootR == r) { 4372 mStackSupervisor.showLockTaskToast(); 4373 return false; 4374 } 4375 } 4376 boolean res = false; 4377 if (r != null) { 4378 res = r.task.stack.finishActivityAffinityLocked(r); 4379 } 4380 return res; 4381 } finally { 4382 Binder.restoreCallingIdentity(origId); 4383 } 4384 } 4385 } 4386 4387 @Override 4388 public void finishVoiceTask(IVoiceInteractionSession session) { 4389 synchronized(this) { 4390 final long origId = Binder.clearCallingIdentity(); 4391 try { 4392 mStackSupervisor.finishVoiceTask(session); 4393 } finally { 4394 Binder.restoreCallingIdentity(origId); 4395 } 4396 } 4397 4398 } 4399 4400 @Override 4401 public boolean releaseActivityInstance(IBinder token) { 4402 synchronized(this) { 4403 final long origId = Binder.clearCallingIdentity(); 4404 try { 4405 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4406 if (r.task == null || r.task.stack == null) { 4407 return false; 4408 } 4409 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4410 } finally { 4411 Binder.restoreCallingIdentity(origId); 4412 } 4413 } 4414 } 4415 4416 @Override 4417 public void releaseSomeActivities(IApplicationThread appInt) { 4418 synchronized(this) { 4419 final long origId = Binder.clearCallingIdentity(); 4420 try { 4421 ProcessRecord app = getRecordForAppLocked(appInt); 4422 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4423 } finally { 4424 Binder.restoreCallingIdentity(origId); 4425 } 4426 } 4427 } 4428 4429 @Override 4430 public boolean willActivityBeVisible(IBinder token) { 4431 synchronized(this) { 4432 ActivityStack stack = ActivityRecord.getStackLocked(token); 4433 if (stack != null) { 4434 return stack.willActivityBeVisibleLocked(token); 4435 } 4436 return false; 4437 } 4438 } 4439 4440 @Override 4441 public void overridePendingTransition(IBinder token, String packageName, 4442 int enterAnim, int exitAnim) { 4443 synchronized(this) { 4444 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4445 if (self == null) { 4446 return; 4447 } 4448 4449 final long origId = Binder.clearCallingIdentity(); 4450 4451 if (self.state == ActivityState.RESUMED 4452 || self.state == ActivityState.PAUSING) { 4453 mWindowManager.overridePendingAppTransition(packageName, 4454 enterAnim, exitAnim, null); 4455 } 4456 4457 Binder.restoreCallingIdentity(origId); 4458 } 4459 } 4460 4461 /** 4462 * Main function for removing an existing process from the activity manager 4463 * as a result of that process going away. Clears out all connections 4464 * to the process. 4465 */ 4466 private final void handleAppDiedLocked(ProcessRecord app, 4467 boolean restarting, boolean allowRestart) { 4468 int pid = app.pid; 4469 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4470 if (!kept && !restarting) { 4471 removeLruProcessLocked(app); 4472 if (pid > 0) { 4473 ProcessList.remove(pid); 4474 } 4475 } 4476 4477 if (mProfileProc == app) { 4478 clearProfilerLocked(); 4479 } 4480 4481 // Remove this application's activities from active lists. 4482 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4483 4484 app.activities.clear(); 4485 4486 if (app.instrumentationClass != null) { 4487 Slog.w(TAG, "Crash of app " + app.processName 4488 + " running instrumentation " + app.instrumentationClass); 4489 Bundle info = new Bundle(); 4490 info.putString("shortMsg", "Process crashed."); 4491 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4492 } 4493 4494 if (!restarting) { 4495 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4496 // If there was nothing to resume, and we are not already 4497 // restarting this process, but there is a visible activity that 4498 // is hosted by the process... then make sure all visible 4499 // activities are running, taking care of restarting this 4500 // process. 4501 if (hasVisibleActivities) { 4502 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4503 } 4504 } 4505 } 4506 } 4507 4508 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4509 IBinder threadBinder = thread.asBinder(); 4510 // Find the application record. 4511 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4512 ProcessRecord rec = mLruProcesses.get(i); 4513 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4514 return i; 4515 } 4516 } 4517 return -1; 4518 } 4519 4520 final ProcessRecord getRecordForAppLocked( 4521 IApplicationThread thread) { 4522 if (thread == null) { 4523 return null; 4524 } 4525 4526 int appIndex = getLRURecordIndexForAppLocked(thread); 4527 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4528 } 4529 4530 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4531 // If there are no longer any background processes running, 4532 // and the app that died was not running instrumentation, 4533 // then tell everyone we are now low on memory. 4534 boolean haveBg = false; 4535 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4536 ProcessRecord rec = mLruProcesses.get(i); 4537 if (rec.thread != null 4538 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4539 haveBg = true; 4540 break; 4541 } 4542 } 4543 4544 if (!haveBg) { 4545 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4546 if (doReport) { 4547 long now = SystemClock.uptimeMillis(); 4548 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4549 doReport = false; 4550 } else { 4551 mLastMemUsageReportTime = now; 4552 } 4553 } 4554 final ArrayList<ProcessMemInfo> memInfos 4555 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4556 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4557 long now = SystemClock.uptimeMillis(); 4558 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4559 ProcessRecord rec = mLruProcesses.get(i); 4560 if (rec == dyingProc || rec.thread == null) { 4561 continue; 4562 } 4563 if (doReport) { 4564 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4565 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4566 } 4567 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4568 // The low memory report is overriding any current 4569 // state for a GC request. Make sure to do 4570 // heavy/important/visible/foreground processes first. 4571 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4572 rec.lastRequestedGc = 0; 4573 } else { 4574 rec.lastRequestedGc = rec.lastLowMemory; 4575 } 4576 rec.reportLowMemory = true; 4577 rec.lastLowMemory = now; 4578 mProcessesToGc.remove(rec); 4579 addProcessToGcListLocked(rec); 4580 } 4581 } 4582 if (doReport) { 4583 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4584 mHandler.sendMessage(msg); 4585 } 4586 scheduleAppGcsLocked(); 4587 } 4588 } 4589 4590 final void appDiedLocked(ProcessRecord app) { 4591 appDiedLocked(app, app.pid, app.thread); 4592 } 4593 4594 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4595 // First check if this ProcessRecord is actually active for the pid. 4596 synchronized (mPidsSelfLocked) { 4597 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4598 if (curProc != app) { 4599 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4600 return; 4601 } 4602 } 4603 4604 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4605 synchronized (stats) { 4606 stats.noteProcessDiedLocked(app.info.uid, pid); 4607 } 4608 4609 Process.killProcessQuiet(pid); 4610 Process.killProcessGroup(app.info.uid, pid); 4611 app.killed = true; 4612 4613 // Clean up already done if the process has been re-started. 4614 if (app.pid == pid && app.thread != null && 4615 app.thread.asBinder() == thread.asBinder()) { 4616 boolean doLowMem = app.instrumentationClass == null; 4617 boolean doOomAdj = doLowMem; 4618 if (!app.killedByAm) { 4619 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4620 + ") has died"); 4621 mAllowLowerMemLevel = true; 4622 } else { 4623 // Note that we always want to do oom adj to update our state with the 4624 // new number of procs. 4625 mAllowLowerMemLevel = false; 4626 doLowMem = false; 4627 } 4628 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4629 if (DEBUG_CLEANUP) Slog.v( 4630 TAG, "Dying app: " + app + ", pid: " + pid 4631 + ", thread: " + thread.asBinder()); 4632 handleAppDiedLocked(app, false, true); 4633 4634 if (doOomAdj) { 4635 updateOomAdjLocked(); 4636 } 4637 if (doLowMem) { 4638 doLowMemReportIfNeededLocked(app); 4639 } 4640 } else if (app.pid != pid) { 4641 // A new process has already been started. 4642 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4643 + ") has died and restarted (pid " + app.pid + ")."); 4644 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4645 } else if (DEBUG_PROCESSES) { 4646 Slog.d(TAG, "Received spurious death notification for thread " 4647 + thread.asBinder()); 4648 } 4649 } 4650 4651 /** 4652 * If a stack trace dump file is configured, dump process stack traces. 4653 * @param clearTraces causes the dump file to be erased prior to the new 4654 * traces being written, if true; when false, the new traces will be 4655 * appended to any existing file content. 4656 * @param firstPids of dalvik VM processes to dump stack traces for first 4657 * @param lastPids of dalvik VM processes to dump stack traces for last 4658 * @param nativeProcs optional list of native process names to dump stack crawls 4659 * @return file containing stack traces, or null if no dump file is configured 4660 */ 4661 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4662 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4663 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4664 if (tracesPath == null || tracesPath.length() == 0) { 4665 return null; 4666 } 4667 4668 File tracesFile = new File(tracesPath); 4669 try { 4670 File tracesDir = tracesFile.getParentFile(); 4671 if (!tracesDir.exists()) { 4672 tracesDir.mkdirs(); 4673 if (!SELinux.restorecon(tracesDir)) { 4674 return null; 4675 } 4676 } 4677 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4678 4679 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4680 tracesFile.createNewFile(); 4681 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4682 } catch (IOException e) { 4683 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4684 return null; 4685 } 4686 4687 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4688 return tracesFile; 4689 } 4690 4691 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4692 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4693 // Use a FileObserver to detect when traces finish writing. 4694 // The order of traces is considered important to maintain for legibility. 4695 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4696 @Override 4697 public synchronized void onEvent(int event, String path) { notify(); } 4698 }; 4699 4700 try { 4701 observer.startWatching(); 4702 4703 // First collect all of the stacks of the most important pids. 4704 if (firstPids != null) { 4705 try { 4706 int num = firstPids.size(); 4707 for (int i = 0; i < num; i++) { 4708 synchronized (observer) { 4709 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4710 observer.wait(200); // Wait for write-close, give up after 200msec 4711 } 4712 } 4713 } catch (InterruptedException e) { 4714 Slog.wtf(TAG, e); 4715 } 4716 } 4717 4718 // Next collect the stacks of the native pids 4719 if (nativeProcs != null) { 4720 int[] pids = Process.getPidsForCommands(nativeProcs); 4721 if (pids != null) { 4722 for (int pid : pids) { 4723 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4724 } 4725 } 4726 } 4727 4728 // Lastly, measure CPU usage. 4729 if (processCpuTracker != null) { 4730 processCpuTracker.init(); 4731 System.gc(); 4732 processCpuTracker.update(); 4733 try { 4734 synchronized (processCpuTracker) { 4735 processCpuTracker.wait(500); // measure over 1/2 second. 4736 } 4737 } catch (InterruptedException e) { 4738 } 4739 processCpuTracker.update(); 4740 4741 // We'll take the stack crawls of just the top apps using CPU. 4742 final int N = processCpuTracker.countWorkingStats(); 4743 int numProcs = 0; 4744 for (int i=0; i<N && numProcs<5; i++) { 4745 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4746 if (lastPids.indexOfKey(stats.pid) >= 0) { 4747 numProcs++; 4748 try { 4749 synchronized (observer) { 4750 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4751 observer.wait(200); // Wait for write-close, give up after 200msec 4752 } 4753 } catch (InterruptedException e) { 4754 Slog.wtf(TAG, e); 4755 } 4756 4757 } 4758 } 4759 } 4760 } finally { 4761 observer.stopWatching(); 4762 } 4763 } 4764 4765 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4766 if (true || IS_USER_BUILD) { 4767 return; 4768 } 4769 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4770 if (tracesPath == null || tracesPath.length() == 0) { 4771 return; 4772 } 4773 4774 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4775 StrictMode.allowThreadDiskWrites(); 4776 try { 4777 final File tracesFile = new File(tracesPath); 4778 final File tracesDir = tracesFile.getParentFile(); 4779 final File tracesTmp = new File(tracesDir, "__tmp__"); 4780 try { 4781 if (!tracesDir.exists()) { 4782 tracesDir.mkdirs(); 4783 if (!SELinux.restorecon(tracesDir.getPath())) { 4784 return; 4785 } 4786 } 4787 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4788 4789 if (tracesFile.exists()) { 4790 tracesTmp.delete(); 4791 tracesFile.renameTo(tracesTmp); 4792 } 4793 StringBuilder sb = new StringBuilder(); 4794 Time tobj = new Time(); 4795 tobj.set(System.currentTimeMillis()); 4796 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4797 sb.append(": "); 4798 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4799 sb.append(" since "); 4800 sb.append(msg); 4801 FileOutputStream fos = new FileOutputStream(tracesFile); 4802 fos.write(sb.toString().getBytes()); 4803 if (app == null) { 4804 fos.write("\n*** No application process!".getBytes()); 4805 } 4806 fos.close(); 4807 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4808 } catch (IOException e) { 4809 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4810 return; 4811 } 4812 4813 if (app != null) { 4814 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4815 firstPids.add(app.pid); 4816 dumpStackTraces(tracesPath, firstPids, null, null, null); 4817 } 4818 4819 File lastTracesFile = null; 4820 File curTracesFile = null; 4821 for (int i=9; i>=0; i--) { 4822 String name = String.format(Locale.US, "slow%02d.txt", i); 4823 curTracesFile = new File(tracesDir, name); 4824 if (curTracesFile.exists()) { 4825 if (lastTracesFile != null) { 4826 curTracesFile.renameTo(lastTracesFile); 4827 } else { 4828 curTracesFile.delete(); 4829 } 4830 } 4831 lastTracesFile = curTracesFile; 4832 } 4833 tracesFile.renameTo(curTracesFile); 4834 if (tracesTmp.exists()) { 4835 tracesTmp.renameTo(tracesFile); 4836 } 4837 } finally { 4838 StrictMode.setThreadPolicy(oldPolicy); 4839 } 4840 } 4841 4842 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4843 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4844 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4845 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4846 4847 if (mController != null) { 4848 try { 4849 // 0 == continue, -1 = kill process immediately 4850 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4851 if (res < 0 && app.pid != MY_PID) { 4852 app.kill("anr", true); 4853 } 4854 } catch (RemoteException e) { 4855 mController = null; 4856 Watchdog.getInstance().setActivityController(null); 4857 } 4858 } 4859 4860 long anrTime = SystemClock.uptimeMillis(); 4861 if (MONITOR_CPU_USAGE) { 4862 updateCpuStatsNow(); 4863 } 4864 4865 synchronized (this) { 4866 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4867 if (mShuttingDown) { 4868 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4869 return; 4870 } else if (app.notResponding) { 4871 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4872 return; 4873 } else if (app.crashing) { 4874 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4875 return; 4876 } 4877 4878 // In case we come through here for the same app before completing 4879 // this one, mark as anring now so we will bail out. 4880 app.notResponding = true; 4881 4882 // Log the ANR to the event log. 4883 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4884 app.processName, app.info.flags, annotation); 4885 4886 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4887 firstPids.add(app.pid); 4888 4889 int parentPid = app.pid; 4890 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4891 if (parentPid != app.pid) firstPids.add(parentPid); 4892 4893 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4894 4895 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4896 ProcessRecord r = mLruProcesses.get(i); 4897 if (r != null && r.thread != null) { 4898 int pid = r.pid; 4899 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4900 if (r.persistent) { 4901 firstPids.add(pid); 4902 } else { 4903 lastPids.put(pid, Boolean.TRUE); 4904 } 4905 } 4906 } 4907 } 4908 } 4909 4910 // Log the ANR to the main log. 4911 StringBuilder info = new StringBuilder(); 4912 info.setLength(0); 4913 info.append("ANR in ").append(app.processName); 4914 if (activity != null && activity.shortComponentName != null) { 4915 info.append(" (").append(activity.shortComponentName).append(")"); 4916 } 4917 info.append("\n"); 4918 info.append("PID: ").append(app.pid).append("\n"); 4919 if (annotation != null) { 4920 info.append("Reason: ").append(annotation).append("\n"); 4921 } 4922 if (parent != null && parent != activity) { 4923 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4924 } 4925 4926 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4927 4928 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4929 NATIVE_STACKS_OF_INTEREST); 4930 4931 String cpuInfo = null; 4932 if (MONITOR_CPU_USAGE) { 4933 updateCpuStatsNow(); 4934 synchronized (mProcessCpuTracker) { 4935 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4936 } 4937 info.append(processCpuTracker.printCurrentLoad()); 4938 info.append(cpuInfo); 4939 } 4940 4941 info.append(processCpuTracker.printCurrentState(anrTime)); 4942 4943 Slog.e(TAG, info.toString()); 4944 if (tracesFile == null) { 4945 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4946 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4947 } 4948 4949 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4950 cpuInfo, tracesFile, null); 4951 4952 if (mController != null) { 4953 try { 4954 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4955 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4956 if (res != 0) { 4957 if (res < 0 && app.pid != MY_PID) { 4958 app.kill("anr", true); 4959 } else { 4960 synchronized (this) { 4961 mServices.scheduleServiceTimeoutLocked(app); 4962 } 4963 } 4964 return; 4965 } 4966 } catch (RemoteException e) { 4967 mController = null; 4968 Watchdog.getInstance().setActivityController(null); 4969 } 4970 } 4971 4972 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4973 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4974 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4975 4976 synchronized (this) { 4977 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4978 app.kill("bg anr", true); 4979 return; 4980 } 4981 4982 // Set the app's notResponding state, and look up the errorReportReceiver 4983 makeAppNotRespondingLocked(app, 4984 activity != null ? activity.shortComponentName : null, 4985 annotation != null ? "ANR " + annotation : "ANR", 4986 info.toString()); 4987 4988 // Bring up the infamous App Not Responding dialog 4989 Message msg = Message.obtain(); 4990 HashMap<String, Object> map = new HashMap<String, Object>(); 4991 msg.what = SHOW_NOT_RESPONDING_MSG; 4992 msg.obj = map; 4993 msg.arg1 = aboveSystem ? 1 : 0; 4994 map.put("app", app); 4995 if (activity != null) { 4996 map.put("activity", activity); 4997 } 4998 4999 mHandler.sendMessage(msg); 5000 } 5001 } 5002 5003 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5004 if (!mLaunchWarningShown) { 5005 mLaunchWarningShown = true; 5006 mHandler.post(new Runnable() { 5007 @Override 5008 public void run() { 5009 synchronized (ActivityManagerService.this) { 5010 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5011 d.show(); 5012 mHandler.postDelayed(new Runnable() { 5013 @Override 5014 public void run() { 5015 synchronized (ActivityManagerService.this) { 5016 d.dismiss(); 5017 mLaunchWarningShown = false; 5018 } 5019 } 5020 }, 4000); 5021 } 5022 } 5023 }); 5024 } 5025 } 5026 5027 @Override 5028 public boolean clearApplicationUserData(final String packageName, 5029 final IPackageDataObserver observer, int userId) { 5030 enforceNotIsolatedCaller("clearApplicationUserData"); 5031 int uid = Binder.getCallingUid(); 5032 int pid = Binder.getCallingPid(); 5033 userId = handleIncomingUser(pid, uid, 5034 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5035 long callingId = Binder.clearCallingIdentity(); 5036 try { 5037 IPackageManager pm = AppGlobals.getPackageManager(); 5038 int pkgUid = -1; 5039 synchronized(this) { 5040 try { 5041 pkgUid = pm.getPackageUid(packageName, userId); 5042 } catch (RemoteException e) { 5043 } 5044 if (pkgUid == -1) { 5045 Slog.w(TAG, "Invalid packageName: " + packageName); 5046 if (observer != null) { 5047 try { 5048 observer.onRemoveCompleted(packageName, false); 5049 } catch (RemoteException e) { 5050 Slog.i(TAG, "Observer no longer exists."); 5051 } 5052 } 5053 return false; 5054 } 5055 if (uid == pkgUid || checkComponentPermission( 5056 android.Manifest.permission.CLEAR_APP_USER_DATA, 5057 pid, uid, -1, true) 5058 == PackageManager.PERMISSION_GRANTED) { 5059 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5060 } else { 5061 throw new SecurityException("PID " + pid + " does not have permission " 5062 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5063 + " of package " + packageName); 5064 } 5065 5066 // Remove all tasks match the cleared application package and user 5067 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5068 final TaskRecord tr = mRecentTasks.get(i); 5069 final String taskPackageName = 5070 tr.getBaseIntent().getComponent().getPackageName(); 5071 if (tr.userId != userId) continue; 5072 if (!taskPackageName.equals(packageName)) continue; 5073 removeTaskByIdLocked(tr.taskId, false); 5074 } 5075 } 5076 5077 try { 5078 // Clear application user data 5079 pm.clearApplicationUserData(packageName, observer, userId); 5080 5081 synchronized(this) { 5082 // Remove all permissions granted from/to this package 5083 removeUriPermissionsForPackageLocked(packageName, userId, true); 5084 } 5085 5086 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5087 Uri.fromParts("package", packageName, null)); 5088 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5089 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5090 null, null, 0, null, null, null, false, false, userId); 5091 } catch (RemoteException e) { 5092 } 5093 } finally { 5094 Binder.restoreCallingIdentity(callingId); 5095 } 5096 return true; 5097 } 5098 5099 @Override 5100 public void killBackgroundProcesses(final String packageName, int userId) { 5101 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5102 != PackageManager.PERMISSION_GRANTED && 5103 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5104 != PackageManager.PERMISSION_GRANTED) { 5105 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5106 + Binder.getCallingPid() 5107 + ", uid=" + Binder.getCallingUid() 5108 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5109 Slog.w(TAG, msg); 5110 throw new SecurityException(msg); 5111 } 5112 5113 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5114 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5115 long callingId = Binder.clearCallingIdentity(); 5116 try { 5117 IPackageManager pm = AppGlobals.getPackageManager(); 5118 synchronized(this) { 5119 int appId = -1; 5120 try { 5121 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5122 } catch (RemoteException e) { 5123 } 5124 if (appId == -1) { 5125 Slog.w(TAG, "Invalid packageName: " + packageName); 5126 return; 5127 } 5128 killPackageProcessesLocked(packageName, appId, userId, 5129 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5130 } 5131 } finally { 5132 Binder.restoreCallingIdentity(callingId); 5133 } 5134 } 5135 5136 @Override 5137 public void killAllBackgroundProcesses() { 5138 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5139 != PackageManager.PERMISSION_GRANTED) { 5140 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5141 + Binder.getCallingPid() 5142 + ", uid=" + Binder.getCallingUid() 5143 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5144 Slog.w(TAG, msg); 5145 throw new SecurityException(msg); 5146 } 5147 5148 long callingId = Binder.clearCallingIdentity(); 5149 try { 5150 synchronized(this) { 5151 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5152 final int NP = mProcessNames.getMap().size(); 5153 for (int ip=0; ip<NP; ip++) { 5154 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5155 final int NA = apps.size(); 5156 for (int ia=0; ia<NA; ia++) { 5157 ProcessRecord app = apps.valueAt(ia); 5158 if (app.persistent) { 5159 // we don't kill persistent processes 5160 continue; 5161 } 5162 if (app.removed) { 5163 procs.add(app); 5164 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5165 app.removed = true; 5166 procs.add(app); 5167 } 5168 } 5169 } 5170 5171 int N = procs.size(); 5172 for (int i=0; i<N; i++) { 5173 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5174 } 5175 mAllowLowerMemLevel = true; 5176 updateOomAdjLocked(); 5177 doLowMemReportIfNeededLocked(null); 5178 } 5179 } finally { 5180 Binder.restoreCallingIdentity(callingId); 5181 } 5182 } 5183 5184 @Override 5185 public void forceStopPackage(final String packageName, int userId) { 5186 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5187 != PackageManager.PERMISSION_GRANTED) { 5188 String msg = "Permission Denial: forceStopPackage() from pid=" 5189 + Binder.getCallingPid() 5190 + ", uid=" + Binder.getCallingUid() 5191 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5192 Slog.w(TAG, msg); 5193 throw new SecurityException(msg); 5194 } 5195 final int callingPid = Binder.getCallingPid(); 5196 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5197 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5198 long callingId = Binder.clearCallingIdentity(); 5199 try { 5200 IPackageManager pm = AppGlobals.getPackageManager(); 5201 synchronized(this) { 5202 int[] users = userId == UserHandle.USER_ALL 5203 ? getUsersLocked() : new int[] { userId }; 5204 for (int user : users) { 5205 int pkgUid = -1; 5206 try { 5207 pkgUid = pm.getPackageUid(packageName, user); 5208 } catch (RemoteException e) { 5209 } 5210 if (pkgUid == -1) { 5211 Slog.w(TAG, "Invalid packageName: " + packageName); 5212 continue; 5213 } 5214 try { 5215 pm.setPackageStoppedState(packageName, true, user); 5216 } catch (RemoteException e) { 5217 } catch (IllegalArgumentException e) { 5218 Slog.w(TAG, "Failed trying to unstop package " 5219 + packageName + ": " + e); 5220 } 5221 if (isUserRunningLocked(user, false)) { 5222 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5223 } 5224 } 5225 } 5226 } finally { 5227 Binder.restoreCallingIdentity(callingId); 5228 } 5229 } 5230 5231 @Override 5232 public void addPackageDependency(String packageName) { 5233 synchronized (this) { 5234 int callingPid = Binder.getCallingPid(); 5235 if (callingPid == Process.myPid()) { 5236 // Yeah, um, no. 5237 Slog.w(TAG, "Can't addPackageDependency on system process"); 5238 return; 5239 } 5240 ProcessRecord proc; 5241 synchronized (mPidsSelfLocked) { 5242 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5243 } 5244 if (proc != null) { 5245 if (proc.pkgDeps == null) { 5246 proc.pkgDeps = new ArraySet<String>(1); 5247 } 5248 proc.pkgDeps.add(packageName); 5249 } 5250 } 5251 } 5252 5253 /* 5254 * The pkg name and app id have to be specified. 5255 */ 5256 @Override 5257 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5258 if (pkg == null) { 5259 return; 5260 } 5261 // Make sure the uid is valid. 5262 if (appid < 0) { 5263 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5264 return; 5265 } 5266 int callerUid = Binder.getCallingUid(); 5267 // Only the system server can kill an application 5268 if (callerUid == Process.SYSTEM_UID) { 5269 // Post an aysnc message to kill the application 5270 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5271 msg.arg1 = appid; 5272 msg.arg2 = 0; 5273 Bundle bundle = new Bundle(); 5274 bundle.putString("pkg", pkg); 5275 bundle.putString("reason", reason); 5276 msg.obj = bundle; 5277 mHandler.sendMessage(msg); 5278 } else { 5279 throw new SecurityException(callerUid + " cannot kill pkg: " + 5280 pkg); 5281 } 5282 } 5283 5284 @Override 5285 public void closeSystemDialogs(String reason) { 5286 enforceNotIsolatedCaller("closeSystemDialogs"); 5287 5288 final int pid = Binder.getCallingPid(); 5289 final int uid = Binder.getCallingUid(); 5290 final long origId = Binder.clearCallingIdentity(); 5291 try { 5292 synchronized (this) { 5293 // Only allow this from foreground processes, so that background 5294 // applications can't abuse it to prevent system UI from being shown. 5295 if (uid >= Process.FIRST_APPLICATION_UID) { 5296 ProcessRecord proc; 5297 synchronized (mPidsSelfLocked) { 5298 proc = mPidsSelfLocked.get(pid); 5299 } 5300 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5301 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5302 + " from background process " + proc); 5303 return; 5304 } 5305 } 5306 closeSystemDialogsLocked(reason); 5307 } 5308 } finally { 5309 Binder.restoreCallingIdentity(origId); 5310 } 5311 } 5312 5313 void closeSystemDialogsLocked(String reason) { 5314 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5315 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5316 | Intent.FLAG_RECEIVER_FOREGROUND); 5317 if (reason != null) { 5318 intent.putExtra("reason", reason); 5319 } 5320 mWindowManager.closeSystemDialogs(reason); 5321 5322 mStackSupervisor.closeSystemDialogsLocked(); 5323 5324 broadcastIntentLocked(null, null, intent, null, 5325 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5326 Process.SYSTEM_UID, UserHandle.USER_ALL); 5327 } 5328 5329 @Override 5330 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5331 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5332 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5333 for (int i=pids.length-1; i>=0; i--) { 5334 ProcessRecord proc; 5335 int oomAdj; 5336 synchronized (this) { 5337 synchronized (mPidsSelfLocked) { 5338 proc = mPidsSelfLocked.get(pids[i]); 5339 oomAdj = proc != null ? proc.setAdj : 0; 5340 } 5341 } 5342 infos[i] = new Debug.MemoryInfo(); 5343 Debug.getMemoryInfo(pids[i], infos[i]); 5344 if (proc != null) { 5345 synchronized (this) { 5346 if (proc.thread != null && proc.setAdj == oomAdj) { 5347 // Record this for posterity if the process has been stable. 5348 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5349 infos[i].getTotalUss(), false, proc.pkgList); 5350 } 5351 } 5352 } 5353 } 5354 return infos; 5355 } 5356 5357 @Override 5358 public long[] getProcessPss(int[] pids) { 5359 enforceNotIsolatedCaller("getProcessPss"); 5360 long[] pss = new long[pids.length]; 5361 for (int i=pids.length-1; i>=0; i--) { 5362 ProcessRecord proc; 5363 int oomAdj; 5364 synchronized (this) { 5365 synchronized (mPidsSelfLocked) { 5366 proc = mPidsSelfLocked.get(pids[i]); 5367 oomAdj = proc != null ? proc.setAdj : 0; 5368 } 5369 } 5370 long[] tmpUss = new long[1]; 5371 pss[i] = Debug.getPss(pids[i], tmpUss); 5372 if (proc != null) { 5373 synchronized (this) { 5374 if (proc.thread != null && proc.setAdj == oomAdj) { 5375 // Record this for posterity if the process has been stable. 5376 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5377 } 5378 } 5379 } 5380 } 5381 return pss; 5382 } 5383 5384 @Override 5385 public void killApplicationProcess(String processName, int uid) { 5386 if (processName == null) { 5387 return; 5388 } 5389 5390 int callerUid = Binder.getCallingUid(); 5391 // Only the system server can kill an application 5392 if (callerUid == Process.SYSTEM_UID) { 5393 synchronized (this) { 5394 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5395 if (app != null && app.thread != null) { 5396 try { 5397 app.thread.scheduleSuicide(); 5398 } catch (RemoteException e) { 5399 // If the other end already died, then our work here is done. 5400 } 5401 } else { 5402 Slog.w(TAG, "Process/uid not found attempting kill of " 5403 + processName + " / " + uid); 5404 } 5405 } 5406 } else { 5407 throw new SecurityException(callerUid + " cannot kill app process: " + 5408 processName); 5409 } 5410 } 5411 5412 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5413 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5414 false, true, false, false, UserHandle.getUserId(uid), reason); 5415 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5416 Uri.fromParts("package", packageName, null)); 5417 if (!mProcessesReady) { 5418 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5419 | Intent.FLAG_RECEIVER_FOREGROUND); 5420 } 5421 intent.putExtra(Intent.EXTRA_UID, uid); 5422 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5423 broadcastIntentLocked(null, null, intent, 5424 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5425 false, false, 5426 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5427 } 5428 5429 private void forceStopUserLocked(int userId, String reason) { 5430 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5431 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5432 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5433 | Intent.FLAG_RECEIVER_FOREGROUND); 5434 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5435 broadcastIntentLocked(null, null, intent, 5436 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5437 false, false, 5438 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5439 } 5440 5441 private final boolean killPackageProcessesLocked(String packageName, int appId, 5442 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5443 boolean doit, boolean evenPersistent, String reason) { 5444 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5445 5446 // Remove all processes this package may have touched: all with the 5447 // same UID (except for the system or root user), and all whose name 5448 // matches the package name. 5449 final int NP = mProcessNames.getMap().size(); 5450 for (int ip=0; ip<NP; ip++) { 5451 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5452 final int NA = apps.size(); 5453 for (int ia=0; ia<NA; ia++) { 5454 ProcessRecord app = apps.valueAt(ia); 5455 if (app.persistent && !evenPersistent) { 5456 // we don't kill persistent processes 5457 continue; 5458 } 5459 if (app.removed) { 5460 if (doit) { 5461 procs.add(app); 5462 } 5463 continue; 5464 } 5465 5466 // Skip process if it doesn't meet our oom adj requirement. 5467 if (app.setAdj < minOomAdj) { 5468 continue; 5469 } 5470 5471 // If no package is specified, we call all processes under the 5472 // give user id. 5473 if (packageName == null) { 5474 if (app.userId != userId) { 5475 continue; 5476 } 5477 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5478 continue; 5479 } 5480 // Package has been specified, we want to hit all processes 5481 // that match it. We need to qualify this by the processes 5482 // that are running under the specified app and user ID. 5483 } else { 5484 final boolean isDep = app.pkgDeps != null 5485 && app.pkgDeps.contains(packageName); 5486 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5487 continue; 5488 } 5489 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5490 continue; 5491 } 5492 if (!app.pkgList.containsKey(packageName) && !isDep) { 5493 continue; 5494 } 5495 } 5496 5497 // Process has passed all conditions, kill it! 5498 if (!doit) { 5499 return true; 5500 } 5501 app.removed = true; 5502 procs.add(app); 5503 } 5504 } 5505 5506 int N = procs.size(); 5507 for (int i=0; i<N; i++) { 5508 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5509 } 5510 updateOomAdjLocked(); 5511 return N > 0; 5512 } 5513 5514 private final boolean forceStopPackageLocked(String name, int appId, 5515 boolean callerWillRestart, boolean purgeCache, boolean doit, 5516 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5517 int i; 5518 int N; 5519 5520 if (userId == UserHandle.USER_ALL && name == null) { 5521 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5522 } 5523 5524 if (appId < 0 && name != null) { 5525 try { 5526 appId = UserHandle.getAppId( 5527 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5528 } catch (RemoteException e) { 5529 } 5530 } 5531 5532 if (doit) { 5533 if (name != null) { 5534 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5535 + " user=" + userId + ": " + reason); 5536 } else { 5537 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5538 } 5539 5540 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5541 for (int ip=pmap.size()-1; ip>=0; ip--) { 5542 SparseArray<Long> ba = pmap.valueAt(ip); 5543 for (i=ba.size()-1; i>=0; i--) { 5544 boolean remove = false; 5545 final int entUid = ba.keyAt(i); 5546 if (name != null) { 5547 if (userId == UserHandle.USER_ALL) { 5548 if (UserHandle.getAppId(entUid) == appId) { 5549 remove = true; 5550 } 5551 } else { 5552 if (entUid == UserHandle.getUid(userId, appId)) { 5553 remove = true; 5554 } 5555 } 5556 } else if (UserHandle.getUserId(entUid) == userId) { 5557 remove = true; 5558 } 5559 if (remove) { 5560 ba.removeAt(i); 5561 } 5562 } 5563 if (ba.size() == 0) { 5564 pmap.removeAt(ip); 5565 } 5566 } 5567 } 5568 5569 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5570 -100, callerWillRestart, true, doit, evenPersistent, 5571 name == null ? ("stop user " + userId) : ("stop " + name)); 5572 5573 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5574 if (!doit) { 5575 return true; 5576 } 5577 didSomething = true; 5578 } 5579 5580 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5581 if (!doit) { 5582 return true; 5583 } 5584 didSomething = true; 5585 } 5586 5587 if (name == null) { 5588 // Remove all sticky broadcasts from this user. 5589 mStickyBroadcasts.remove(userId); 5590 } 5591 5592 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5593 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5594 userId, providers)) { 5595 if (!doit) { 5596 return true; 5597 } 5598 didSomething = true; 5599 } 5600 N = providers.size(); 5601 for (i=0; i<N; i++) { 5602 removeDyingProviderLocked(null, providers.get(i), true); 5603 } 5604 5605 // Remove transient permissions granted from/to this package/user 5606 removeUriPermissionsForPackageLocked(name, userId, false); 5607 5608 if (name == null || uninstalling) { 5609 // Remove pending intents. For now we only do this when force 5610 // stopping users, because we have some problems when doing this 5611 // for packages -- app widgets are not currently cleaned up for 5612 // such packages, so they can be left with bad pending intents. 5613 if (mIntentSenderRecords.size() > 0) { 5614 Iterator<WeakReference<PendingIntentRecord>> it 5615 = mIntentSenderRecords.values().iterator(); 5616 while (it.hasNext()) { 5617 WeakReference<PendingIntentRecord> wpir = it.next(); 5618 if (wpir == null) { 5619 it.remove(); 5620 continue; 5621 } 5622 PendingIntentRecord pir = wpir.get(); 5623 if (pir == null) { 5624 it.remove(); 5625 continue; 5626 } 5627 if (name == null) { 5628 // Stopping user, remove all objects for the user. 5629 if (pir.key.userId != userId) { 5630 // Not the same user, skip it. 5631 continue; 5632 } 5633 } else { 5634 if (UserHandle.getAppId(pir.uid) != appId) { 5635 // Different app id, skip it. 5636 continue; 5637 } 5638 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5639 // Different user, skip it. 5640 continue; 5641 } 5642 if (!pir.key.packageName.equals(name)) { 5643 // Different package, skip it. 5644 continue; 5645 } 5646 } 5647 if (!doit) { 5648 return true; 5649 } 5650 didSomething = true; 5651 it.remove(); 5652 pir.canceled = true; 5653 if (pir.key.activity != null) { 5654 pir.key.activity.pendingResults.remove(pir.ref); 5655 } 5656 } 5657 } 5658 } 5659 5660 if (doit) { 5661 if (purgeCache && name != null) { 5662 AttributeCache ac = AttributeCache.instance(); 5663 if (ac != null) { 5664 ac.removePackage(name); 5665 } 5666 } 5667 if (mBooted) { 5668 mStackSupervisor.resumeTopActivitiesLocked(); 5669 mStackSupervisor.scheduleIdleLocked(); 5670 } 5671 } 5672 5673 return didSomething; 5674 } 5675 5676 private final boolean removeProcessLocked(ProcessRecord app, 5677 boolean callerWillRestart, boolean allowRestart, String reason) { 5678 final String name = app.processName; 5679 final int uid = app.uid; 5680 if (DEBUG_PROCESSES) Slog.d( 5681 TAG, "Force removing proc " + app.toShortString() + " (" + name 5682 + "/" + uid + ")"); 5683 5684 mProcessNames.remove(name, uid); 5685 mIsolatedProcesses.remove(app.uid); 5686 if (mHeavyWeightProcess == app) { 5687 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5688 mHeavyWeightProcess.userId, 0)); 5689 mHeavyWeightProcess = null; 5690 } 5691 boolean needRestart = false; 5692 if (app.pid > 0 && app.pid != MY_PID) { 5693 int pid = app.pid; 5694 synchronized (mPidsSelfLocked) { 5695 mPidsSelfLocked.remove(pid); 5696 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5697 } 5698 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5699 if (app.isolated) { 5700 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5701 } 5702 app.kill(reason, true); 5703 handleAppDiedLocked(app, true, allowRestart); 5704 removeLruProcessLocked(app); 5705 5706 if (app.persistent && !app.isolated) { 5707 if (!callerWillRestart) { 5708 addAppLocked(app.info, false, null /* ABI override */); 5709 } else { 5710 needRestart = true; 5711 } 5712 } 5713 } else { 5714 mRemovedProcesses.add(app); 5715 } 5716 5717 return needRestart; 5718 } 5719 5720 private final void processStartTimedOutLocked(ProcessRecord app) { 5721 final int pid = app.pid; 5722 boolean gone = false; 5723 synchronized (mPidsSelfLocked) { 5724 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5725 if (knownApp != null && knownApp.thread == null) { 5726 mPidsSelfLocked.remove(pid); 5727 gone = true; 5728 } 5729 } 5730 5731 if (gone) { 5732 Slog.w(TAG, "Process " + app + " failed to attach"); 5733 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5734 pid, app.uid, app.processName); 5735 mProcessNames.remove(app.processName, app.uid); 5736 mIsolatedProcesses.remove(app.uid); 5737 if (mHeavyWeightProcess == app) { 5738 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5739 mHeavyWeightProcess.userId, 0)); 5740 mHeavyWeightProcess = null; 5741 } 5742 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5743 if (app.isolated) { 5744 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5745 } 5746 // Take care of any launching providers waiting for this process. 5747 checkAppInLaunchingProvidersLocked(app, true); 5748 // Take care of any services that are waiting for the process. 5749 mServices.processStartTimedOutLocked(app); 5750 app.kill("start timeout", true); 5751 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5752 Slog.w(TAG, "Unattached app died before backup, skipping"); 5753 try { 5754 IBackupManager bm = IBackupManager.Stub.asInterface( 5755 ServiceManager.getService(Context.BACKUP_SERVICE)); 5756 bm.agentDisconnected(app.info.packageName); 5757 } catch (RemoteException e) { 5758 // Can't happen; the backup manager is local 5759 } 5760 } 5761 if (isPendingBroadcastProcessLocked(pid)) { 5762 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5763 skipPendingBroadcastLocked(pid); 5764 } 5765 } else { 5766 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5767 } 5768 } 5769 5770 private final boolean attachApplicationLocked(IApplicationThread thread, 5771 int pid) { 5772 5773 // Find the application record that is being attached... either via 5774 // the pid if we are running in multiple processes, or just pull the 5775 // next app record if we are emulating process with anonymous threads. 5776 ProcessRecord app; 5777 if (pid != MY_PID && pid >= 0) { 5778 synchronized (mPidsSelfLocked) { 5779 app = mPidsSelfLocked.get(pid); 5780 } 5781 } else { 5782 app = null; 5783 } 5784 5785 if (app == null) { 5786 Slog.w(TAG, "No pending application record for pid " + pid 5787 + " (IApplicationThread " + thread + "); dropping process"); 5788 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5789 if (pid > 0 && pid != MY_PID) { 5790 Process.killProcessQuiet(pid); 5791 //TODO: Process.killProcessGroup(app.info.uid, pid); 5792 } else { 5793 try { 5794 thread.scheduleExit(); 5795 } catch (Exception e) { 5796 // Ignore exceptions. 5797 } 5798 } 5799 return false; 5800 } 5801 5802 // If this application record is still attached to a previous 5803 // process, clean it up now. 5804 if (app.thread != null) { 5805 handleAppDiedLocked(app, true, true); 5806 } 5807 5808 // Tell the process all about itself. 5809 5810 if (localLOGV) Slog.v( 5811 TAG, "Binding process pid " + pid + " to record " + app); 5812 5813 final String processName = app.processName; 5814 try { 5815 AppDeathRecipient adr = new AppDeathRecipient( 5816 app, pid, thread); 5817 thread.asBinder().linkToDeath(adr, 0); 5818 app.deathRecipient = adr; 5819 } catch (RemoteException e) { 5820 app.resetPackageList(mProcessStats); 5821 startProcessLocked(app, "link fail", processName); 5822 return false; 5823 } 5824 5825 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5826 5827 app.makeActive(thread, mProcessStats); 5828 app.curAdj = app.setAdj = -100; 5829 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5830 app.forcingToForeground = null; 5831 updateProcessForegroundLocked(app, false, false); 5832 app.hasShownUi = false; 5833 app.debugging = false; 5834 app.cached = false; 5835 5836 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5837 5838 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5839 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5840 5841 if (!normalMode) { 5842 Slog.i(TAG, "Launching preboot mode app: " + app); 5843 } 5844 5845 if (localLOGV) Slog.v( 5846 TAG, "New app record " + app 5847 + " thread=" + thread.asBinder() + " pid=" + pid); 5848 try { 5849 int testMode = IApplicationThread.DEBUG_OFF; 5850 if (mDebugApp != null && mDebugApp.equals(processName)) { 5851 testMode = mWaitForDebugger 5852 ? IApplicationThread.DEBUG_WAIT 5853 : IApplicationThread.DEBUG_ON; 5854 app.debugging = true; 5855 if (mDebugTransient) { 5856 mDebugApp = mOrigDebugApp; 5857 mWaitForDebugger = mOrigWaitForDebugger; 5858 } 5859 } 5860 String profileFile = app.instrumentationProfileFile; 5861 ParcelFileDescriptor profileFd = null; 5862 int samplingInterval = 0; 5863 boolean profileAutoStop = false; 5864 if (mProfileApp != null && mProfileApp.equals(processName)) { 5865 mProfileProc = app; 5866 profileFile = mProfileFile; 5867 profileFd = mProfileFd; 5868 samplingInterval = mSamplingInterval; 5869 profileAutoStop = mAutoStopProfiler; 5870 } 5871 boolean enableOpenGlTrace = false; 5872 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5873 enableOpenGlTrace = true; 5874 mOpenGlTraceApp = null; 5875 } 5876 5877 // If the app is being launched for restore or full backup, set it up specially 5878 boolean isRestrictedBackupMode = false; 5879 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5880 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5881 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5882 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5883 } 5884 5885 ensurePackageDexOpt(app.instrumentationInfo != null 5886 ? app.instrumentationInfo.packageName 5887 : app.info.packageName); 5888 if (app.instrumentationClass != null) { 5889 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5890 } 5891 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5892 + processName + " with config " + mConfiguration); 5893 ApplicationInfo appInfo = app.instrumentationInfo != null 5894 ? app.instrumentationInfo : app.info; 5895 app.compat = compatibilityInfoForPackageLocked(appInfo); 5896 if (profileFd != null) { 5897 profileFd = profileFd.dup(); 5898 } 5899 ProfilerInfo profilerInfo = profileFile == null ? null 5900 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5901 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5902 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5903 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5904 isRestrictedBackupMode || !normalMode, app.persistent, 5905 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5906 mCoreSettingsObserver.getCoreSettingsLocked()); 5907 updateLruProcessLocked(app, false, null); 5908 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5909 } catch (Exception e) { 5910 // todo: Yikes! What should we do? For now we will try to 5911 // start another process, but that could easily get us in 5912 // an infinite loop of restarting processes... 5913 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5914 5915 app.resetPackageList(mProcessStats); 5916 app.unlinkDeathRecipient(); 5917 startProcessLocked(app, "bind fail", processName); 5918 return false; 5919 } 5920 5921 // Remove this record from the list of starting applications. 5922 mPersistentStartingProcesses.remove(app); 5923 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5924 "Attach application locked removing on hold: " + app); 5925 mProcessesOnHold.remove(app); 5926 5927 boolean badApp = false; 5928 boolean didSomething = false; 5929 5930 // See if the top visible activity is waiting to run in this process... 5931 if (normalMode) { 5932 try { 5933 if (mStackSupervisor.attachApplicationLocked(app)) { 5934 didSomething = true; 5935 } 5936 } catch (Exception e) { 5937 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5938 badApp = true; 5939 } 5940 } 5941 5942 // Find any services that should be running in this process... 5943 if (!badApp) { 5944 try { 5945 didSomething |= mServices.attachApplicationLocked(app, processName); 5946 } catch (Exception e) { 5947 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5948 badApp = true; 5949 } 5950 } 5951 5952 // Check if a next-broadcast receiver is in this process... 5953 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5954 try { 5955 didSomething |= sendPendingBroadcastsLocked(app); 5956 } catch (Exception e) { 5957 // If the app died trying to launch the receiver we declare it 'bad' 5958 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 5959 badApp = true; 5960 } 5961 } 5962 5963 // Check whether the next backup agent is in this process... 5964 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5965 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5966 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5967 try { 5968 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5969 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5970 mBackupTarget.backupMode); 5971 } catch (Exception e) { 5972 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 5973 badApp = true; 5974 } 5975 } 5976 5977 if (badApp) { 5978 app.kill("error during init", true); 5979 handleAppDiedLocked(app, false, true); 5980 return false; 5981 } 5982 5983 if (!didSomething) { 5984 updateOomAdjLocked(); 5985 } 5986 5987 return true; 5988 } 5989 5990 @Override 5991 public final void attachApplication(IApplicationThread thread) { 5992 synchronized (this) { 5993 int callingPid = Binder.getCallingPid(); 5994 final long origId = Binder.clearCallingIdentity(); 5995 attachApplicationLocked(thread, callingPid); 5996 Binder.restoreCallingIdentity(origId); 5997 } 5998 } 5999 6000 @Override 6001 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6002 final long origId = Binder.clearCallingIdentity(); 6003 synchronized (this) { 6004 ActivityStack stack = ActivityRecord.getStackLocked(token); 6005 if (stack != null) { 6006 ActivityRecord r = 6007 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6008 if (stopProfiling) { 6009 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6010 try { 6011 mProfileFd.close(); 6012 } catch (IOException e) { 6013 } 6014 clearProfilerLocked(); 6015 } 6016 } 6017 } 6018 } 6019 Binder.restoreCallingIdentity(origId); 6020 } 6021 6022 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6023 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6024 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6025 } 6026 6027 void enableScreenAfterBoot() { 6028 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6029 SystemClock.uptimeMillis()); 6030 mWindowManager.enableScreenAfterBoot(); 6031 6032 synchronized (this) { 6033 updateEventDispatchingLocked(); 6034 } 6035 } 6036 6037 @Override 6038 public void showBootMessage(final CharSequence msg, final boolean always) { 6039 enforceNotIsolatedCaller("showBootMessage"); 6040 mWindowManager.showBootMessage(msg, always); 6041 } 6042 6043 @Override 6044 public void keyguardWaitingForActivityDrawn() { 6045 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6046 final long token = Binder.clearCallingIdentity(); 6047 try { 6048 synchronized (this) { 6049 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6050 mWindowManager.keyguardWaitingForActivityDrawn(); 6051 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6052 mLockScreenShown = LOCK_SCREEN_LEAVING; 6053 } 6054 } 6055 } finally { 6056 Binder.restoreCallingIdentity(token); 6057 } 6058 } 6059 6060 final void finishBooting() { 6061 synchronized (this) { 6062 if (!mBootAnimationComplete) { 6063 mCallFinishBooting = true; 6064 return; 6065 } 6066 mCallFinishBooting = false; 6067 } 6068 6069 ArraySet<String> completedIsas = new ArraySet<String>(); 6070 for (String abi : Build.SUPPORTED_ABIS) { 6071 Process.establishZygoteConnectionForAbi(abi); 6072 final String instructionSet = VMRuntime.getInstructionSet(abi); 6073 if (!completedIsas.contains(instructionSet)) { 6074 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6075 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6076 } 6077 completedIsas.add(instructionSet); 6078 } 6079 } 6080 6081 IntentFilter pkgFilter = new IntentFilter(); 6082 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6083 pkgFilter.addDataScheme("package"); 6084 mContext.registerReceiver(new BroadcastReceiver() { 6085 @Override 6086 public void onReceive(Context context, Intent intent) { 6087 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6088 if (pkgs != null) { 6089 for (String pkg : pkgs) { 6090 synchronized (ActivityManagerService.this) { 6091 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6092 0, "finished booting")) { 6093 setResultCode(Activity.RESULT_OK); 6094 return; 6095 } 6096 } 6097 } 6098 } 6099 } 6100 }, pkgFilter); 6101 6102 // Let system services know. 6103 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6104 6105 synchronized (this) { 6106 // Ensure that any processes we had put on hold are now started 6107 // up. 6108 final int NP = mProcessesOnHold.size(); 6109 if (NP > 0) { 6110 ArrayList<ProcessRecord> procs = 6111 new ArrayList<ProcessRecord>(mProcessesOnHold); 6112 for (int ip=0; ip<NP; ip++) { 6113 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6114 + procs.get(ip)); 6115 startProcessLocked(procs.get(ip), "on-hold", null); 6116 } 6117 } 6118 6119 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6120 // Start looking for apps that are abusing wake locks. 6121 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6122 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6123 // Tell anyone interested that we are done booting! 6124 SystemProperties.set("sys.boot_completed", "1"); 6125 6126 // And trigger dev.bootcomplete if we are not showing encryption progress 6127 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6128 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6129 SystemProperties.set("dev.bootcomplete", "1"); 6130 } 6131 for (int i=0; i<mStartedUsers.size(); i++) { 6132 UserStartedState uss = mStartedUsers.valueAt(i); 6133 if (uss.mState == UserStartedState.STATE_BOOTING) { 6134 uss.mState = UserStartedState.STATE_RUNNING; 6135 final int userId = mStartedUsers.keyAt(i); 6136 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6137 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6138 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6139 broadcastIntentLocked(null, null, intent, null, 6140 new IIntentReceiver.Stub() { 6141 @Override 6142 public void performReceive(Intent intent, int resultCode, 6143 String data, Bundle extras, boolean ordered, 6144 boolean sticky, int sendingUser) { 6145 synchronized (ActivityManagerService.this) { 6146 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6147 true, false); 6148 } 6149 } 6150 }, 6151 0, null, null, 6152 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6153 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6154 userId); 6155 } 6156 } 6157 scheduleStartProfilesLocked(); 6158 } 6159 } 6160 } 6161 6162 @Override 6163 public void bootAnimationComplete() { 6164 final boolean callFinishBooting; 6165 synchronized (this) { 6166 callFinishBooting = mCallFinishBooting; 6167 mBootAnimationComplete = true; 6168 } 6169 if (callFinishBooting) { 6170 finishBooting(); 6171 } 6172 } 6173 6174 final void ensureBootCompleted() { 6175 boolean booting; 6176 boolean enableScreen; 6177 synchronized (this) { 6178 booting = mBooting; 6179 mBooting = false; 6180 enableScreen = !mBooted; 6181 mBooted = true; 6182 } 6183 6184 if (booting) { 6185 finishBooting(); 6186 } 6187 6188 if (enableScreen) { 6189 enableScreenAfterBoot(); 6190 } 6191 } 6192 6193 @Override 6194 public final void activityResumed(IBinder token) { 6195 final long origId = Binder.clearCallingIdentity(); 6196 synchronized(this) { 6197 ActivityStack stack = ActivityRecord.getStackLocked(token); 6198 if (stack != null) { 6199 ActivityRecord.activityResumedLocked(token); 6200 } 6201 } 6202 Binder.restoreCallingIdentity(origId); 6203 } 6204 6205 @Override 6206 public final void activityPaused(IBinder token) { 6207 final long origId = Binder.clearCallingIdentity(); 6208 synchronized(this) { 6209 ActivityStack stack = ActivityRecord.getStackLocked(token); 6210 if (stack != null) { 6211 stack.activityPausedLocked(token, false); 6212 } 6213 } 6214 Binder.restoreCallingIdentity(origId); 6215 } 6216 6217 @Override 6218 public final void activityStopped(IBinder token, Bundle icicle, 6219 PersistableBundle persistentState, CharSequence description) { 6220 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6221 6222 // Refuse possible leaked file descriptors 6223 if (icicle != null && icicle.hasFileDescriptors()) { 6224 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6225 } 6226 6227 final long origId = Binder.clearCallingIdentity(); 6228 6229 synchronized (this) { 6230 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6231 if (r != null) { 6232 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6233 } 6234 } 6235 6236 trimApplications(); 6237 6238 Binder.restoreCallingIdentity(origId); 6239 } 6240 6241 @Override 6242 public final void activityDestroyed(IBinder token) { 6243 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6244 synchronized (this) { 6245 ActivityStack stack = ActivityRecord.getStackLocked(token); 6246 if (stack != null) { 6247 stack.activityDestroyedLocked(token); 6248 } 6249 } 6250 } 6251 6252 @Override 6253 public final void backgroundResourcesReleased(IBinder token) { 6254 final long origId = Binder.clearCallingIdentity(); 6255 try { 6256 synchronized (this) { 6257 ActivityStack stack = ActivityRecord.getStackLocked(token); 6258 if (stack != null) { 6259 stack.backgroundResourcesReleased(token); 6260 } 6261 } 6262 } finally { 6263 Binder.restoreCallingIdentity(origId); 6264 } 6265 } 6266 6267 @Override 6268 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6269 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6270 } 6271 6272 @Override 6273 public final void notifyEnterAnimationComplete(IBinder token) { 6274 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6275 } 6276 6277 @Override 6278 public String getCallingPackage(IBinder token) { 6279 synchronized (this) { 6280 ActivityRecord r = getCallingRecordLocked(token); 6281 return r != null ? r.info.packageName : null; 6282 } 6283 } 6284 6285 @Override 6286 public ComponentName getCallingActivity(IBinder token) { 6287 synchronized (this) { 6288 ActivityRecord r = getCallingRecordLocked(token); 6289 return r != null ? r.intent.getComponent() : null; 6290 } 6291 } 6292 6293 private ActivityRecord getCallingRecordLocked(IBinder token) { 6294 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6295 if (r == null) { 6296 return null; 6297 } 6298 return r.resultTo; 6299 } 6300 6301 @Override 6302 public ComponentName getActivityClassForToken(IBinder token) { 6303 synchronized(this) { 6304 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6305 if (r == null) { 6306 return null; 6307 } 6308 return r.intent.getComponent(); 6309 } 6310 } 6311 6312 @Override 6313 public String getPackageForToken(IBinder token) { 6314 synchronized(this) { 6315 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6316 if (r == null) { 6317 return null; 6318 } 6319 return r.packageName; 6320 } 6321 } 6322 6323 @Override 6324 public IIntentSender getIntentSender(int type, 6325 String packageName, IBinder token, String resultWho, 6326 int requestCode, Intent[] intents, String[] resolvedTypes, 6327 int flags, Bundle options, int userId) { 6328 enforceNotIsolatedCaller("getIntentSender"); 6329 // Refuse possible leaked file descriptors 6330 if (intents != null) { 6331 if (intents.length < 1) { 6332 throw new IllegalArgumentException("Intents array length must be >= 1"); 6333 } 6334 for (int i=0; i<intents.length; i++) { 6335 Intent intent = intents[i]; 6336 if (intent != null) { 6337 if (intent.hasFileDescriptors()) { 6338 throw new IllegalArgumentException("File descriptors passed in Intent"); 6339 } 6340 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6341 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6342 throw new IllegalArgumentException( 6343 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6344 } 6345 intents[i] = new Intent(intent); 6346 } 6347 } 6348 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6349 throw new IllegalArgumentException( 6350 "Intent array length does not match resolvedTypes length"); 6351 } 6352 } 6353 if (options != null) { 6354 if (options.hasFileDescriptors()) { 6355 throw new IllegalArgumentException("File descriptors passed in options"); 6356 } 6357 } 6358 6359 synchronized(this) { 6360 int callingUid = Binder.getCallingUid(); 6361 int origUserId = userId; 6362 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6363 type == ActivityManager.INTENT_SENDER_BROADCAST, 6364 ALLOW_NON_FULL, "getIntentSender", null); 6365 if (origUserId == UserHandle.USER_CURRENT) { 6366 // We don't want to evaluate this until the pending intent is 6367 // actually executed. However, we do want to always do the 6368 // security checking for it above. 6369 userId = UserHandle.USER_CURRENT; 6370 } 6371 try { 6372 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6373 int uid = AppGlobals.getPackageManager() 6374 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6375 if (!UserHandle.isSameApp(callingUid, uid)) { 6376 String msg = "Permission Denial: getIntentSender() from pid=" 6377 + Binder.getCallingPid() 6378 + ", uid=" + Binder.getCallingUid() 6379 + ", (need uid=" + uid + ")" 6380 + " is not allowed to send as package " + packageName; 6381 Slog.w(TAG, msg); 6382 throw new SecurityException(msg); 6383 } 6384 } 6385 6386 return getIntentSenderLocked(type, packageName, callingUid, userId, 6387 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6388 6389 } catch (RemoteException e) { 6390 throw new SecurityException(e); 6391 } 6392 } 6393 } 6394 6395 IIntentSender getIntentSenderLocked(int type, String packageName, 6396 int callingUid, int userId, IBinder token, String resultWho, 6397 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6398 Bundle options) { 6399 if (DEBUG_MU) 6400 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6401 ActivityRecord activity = null; 6402 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6403 activity = ActivityRecord.isInStackLocked(token); 6404 if (activity == null) { 6405 return null; 6406 } 6407 if (activity.finishing) { 6408 return null; 6409 } 6410 } 6411 6412 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6413 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6414 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6415 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6416 |PendingIntent.FLAG_UPDATE_CURRENT); 6417 6418 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6419 type, packageName, activity, resultWho, 6420 requestCode, intents, resolvedTypes, flags, options, userId); 6421 WeakReference<PendingIntentRecord> ref; 6422 ref = mIntentSenderRecords.get(key); 6423 PendingIntentRecord rec = ref != null ? ref.get() : null; 6424 if (rec != null) { 6425 if (!cancelCurrent) { 6426 if (updateCurrent) { 6427 if (rec.key.requestIntent != null) { 6428 rec.key.requestIntent.replaceExtras(intents != null ? 6429 intents[intents.length - 1] : null); 6430 } 6431 if (intents != null) { 6432 intents[intents.length-1] = rec.key.requestIntent; 6433 rec.key.allIntents = intents; 6434 rec.key.allResolvedTypes = resolvedTypes; 6435 } else { 6436 rec.key.allIntents = null; 6437 rec.key.allResolvedTypes = null; 6438 } 6439 } 6440 return rec; 6441 } 6442 rec.canceled = true; 6443 mIntentSenderRecords.remove(key); 6444 } 6445 if (noCreate) { 6446 return rec; 6447 } 6448 rec = new PendingIntentRecord(this, key, callingUid); 6449 mIntentSenderRecords.put(key, rec.ref); 6450 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6451 if (activity.pendingResults == null) { 6452 activity.pendingResults 6453 = new HashSet<WeakReference<PendingIntentRecord>>(); 6454 } 6455 activity.pendingResults.add(rec.ref); 6456 } 6457 return rec; 6458 } 6459 6460 @Override 6461 public void cancelIntentSender(IIntentSender sender) { 6462 if (!(sender instanceof PendingIntentRecord)) { 6463 return; 6464 } 6465 synchronized(this) { 6466 PendingIntentRecord rec = (PendingIntentRecord)sender; 6467 try { 6468 int uid = AppGlobals.getPackageManager() 6469 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6470 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6471 String msg = "Permission Denial: cancelIntentSender() from pid=" 6472 + Binder.getCallingPid() 6473 + ", uid=" + Binder.getCallingUid() 6474 + " is not allowed to cancel packges " 6475 + rec.key.packageName; 6476 Slog.w(TAG, msg); 6477 throw new SecurityException(msg); 6478 } 6479 } catch (RemoteException e) { 6480 throw new SecurityException(e); 6481 } 6482 cancelIntentSenderLocked(rec, true); 6483 } 6484 } 6485 6486 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6487 rec.canceled = true; 6488 mIntentSenderRecords.remove(rec.key); 6489 if (cleanActivity && rec.key.activity != null) { 6490 rec.key.activity.pendingResults.remove(rec.ref); 6491 } 6492 } 6493 6494 @Override 6495 public String getPackageForIntentSender(IIntentSender pendingResult) { 6496 if (!(pendingResult instanceof PendingIntentRecord)) { 6497 return null; 6498 } 6499 try { 6500 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6501 return res.key.packageName; 6502 } catch (ClassCastException e) { 6503 } 6504 return null; 6505 } 6506 6507 @Override 6508 public int getUidForIntentSender(IIntentSender sender) { 6509 if (sender instanceof PendingIntentRecord) { 6510 try { 6511 PendingIntentRecord res = (PendingIntentRecord)sender; 6512 return res.uid; 6513 } catch (ClassCastException e) { 6514 } 6515 } 6516 return -1; 6517 } 6518 6519 @Override 6520 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6521 if (!(pendingResult instanceof PendingIntentRecord)) { 6522 return false; 6523 } 6524 try { 6525 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6526 if (res.key.allIntents == null) { 6527 return false; 6528 } 6529 for (int i=0; i<res.key.allIntents.length; i++) { 6530 Intent intent = res.key.allIntents[i]; 6531 if (intent.getPackage() != null && intent.getComponent() != null) { 6532 return false; 6533 } 6534 } 6535 return true; 6536 } catch (ClassCastException e) { 6537 } 6538 return false; 6539 } 6540 6541 @Override 6542 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6543 if (!(pendingResult instanceof PendingIntentRecord)) { 6544 return false; 6545 } 6546 try { 6547 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6548 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6549 return true; 6550 } 6551 return false; 6552 } catch (ClassCastException e) { 6553 } 6554 return false; 6555 } 6556 6557 @Override 6558 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6559 if (!(pendingResult instanceof PendingIntentRecord)) { 6560 return null; 6561 } 6562 try { 6563 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6564 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6565 } catch (ClassCastException e) { 6566 } 6567 return null; 6568 } 6569 6570 @Override 6571 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6572 if (!(pendingResult instanceof PendingIntentRecord)) { 6573 return null; 6574 } 6575 try { 6576 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6577 Intent intent = res.key.requestIntent; 6578 if (intent != null) { 6579 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6580 || res.lastTagPrefix.equals(prefix))) { 6581 return res.lastTag; 6582 } 6583 res.lastTagPrefix = prefix; 6584 StringBuilder sb = new StringBuilder(128); 6585 if (prefix != null) { 6586 sb.append(prefix); 6587 } 6588 if (intent.getAction() != null) { 6589 sb.append(intent.getAction()); 6590 } else if (intent.getComponent() != null) { 6591 intent.getComponent().appendShortString(sb); 6592 } else { 6593 sb.append("?"); 6594 } 6595 return res.lastTag = sb.toString(); 6596 } 6597 } catch (ClassCastException e) { 6598 } 6599 return null; 6600 } 6601 6602 @Override 6603 public void setProcessLimit(int max) { 6604 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6605 "setProcessLimit()"); 6606 synchronized (this) { 6607 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6608 mProcessLimitOverride = max; 6609 } 6610 trimApplications(); 6611 } 6612 6613 @Override 6614 public int getProcessLimit() { 6615 synchronized (this) { 6616 return mProcessLimitOverride; 6617 } 6618 } 6619 6620 void foregroundTokenDied(ForegroundToken token) { 6621 synchronized (ActivityManagerService.this) { 6622 synchronized (mPidsSelfLocked) { 6623 ForegroundToken cur 6624 = mForegroundProcesses.get(token.pid); 6625 if (cur != token) { 6626 return; 6627 } 6628 mForegroundProcesses.remove(token.pid); 6629 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6630 if (pr == null) { 6631 return; 6632 } 6633 pr.forcingToForeground = null; 6634 updateProcessForegroundLocked(pr, false, false); 6635 } 6636 updateOomAdjLocked(); 6637 } 6638 } 6639 6640 @Override 6641 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6642 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6643 "setProcessForeground()"); 6644 synchronized(this) { 6645 boolean changed = false; 6646 6647 synchronized (mPidsSelfLocked) { 6648 ProcessRecord pr = mPidsSelfLocked.get(pid); 6649 if (pr == null && isForeground) { 6650 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6651 return; 6652 } 6653 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6654 if (oldToken != null) { 6655 oldToken.token.unlinkToDeath(oldToken, 0); 6656 mForegroundProcesses.remove(pid); 6657 if (pr != null) { 6658 pr.forcingToForeground = null; 6659 } 6660 changed = true; 6661 } 6662 if (isForeground && token != null) { 6663 ForegroundToken newToken = new ForegroundToken() { 6664 @Override 6665 public void binderDied() { 6666 foregroundTokenDied(this); 6667 } 6668 }; 6669 newToken.pid = pid; 6670 newToken.token = token; 6671 try { 6672 token.linkToDeath(newToken, 0); 6673 mForegroundProcesses.put(pid, newToken); 6674 pr.forcingToForeground = token; 6675 changed = true; 6676 } catch (RemoteException e) { 6677 // If the process died while doing this, we will later 6678 // do the cleanup with the process death link. 6679 } 6680 } 6681 } 6682 6683 if (changed) { 6684 updateOomAdjLocked(); 6685 } 6686 } 6687 } 6688 6689 // ========================================================= 6690 // PERMISSIONS 6691 // ========================================================= 6692 6693 static class PermissionController extends IPermissionController.Stub { 6694 ActivityManagerService mActivityManagerService; 6695 PermissionController(ActivityManagerService activityManagerService) { 6696 mActivityManagerService = activityManagerService; 6697 } 6698 6699 @Override 6700 public boolean checkPermission(String permission, int pid, int uid) { 6701 return mActivityManagerService.checkPermission(permission, pid, 6702 uid) == PackageManager.PERMISSION_GRANTED; 6703 } 6704 } 6705 6706 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6707 @Override 6708 public int checkComponentPermission(String permission, int pid, int uid, 6709 int owningUid, boolean exported) { 6710 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6711 owningUid, exported); 6712 } 6713 6714 @Override 6715 public Object getAMSLock() { 6716 return ActivityManagerService.this; 6717 } 6718 } 6719 6720 /** 6721 * This can be called with or without the global lock held. 6722 */ 6723 int checkComponentPermission(String permission, int pid, int uid, 6724 int owningUid, boolean exported) { 6725 // We might be performing an operation on behalf of an indirect binder 6726 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6727 // client identity accordingly before proceeding. 6728 Identity tlsIdentity = sCallerIdentity.get(); 6729 if (tlsIdentity != null) { 6730 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6731 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6732 uid = tlsIdentity.uid; 6733 pid = tlsIdentity.pid; 6734 } 6735 6736 if (pid == MY_PID) { 6737 return PackageManager.PERMISSION_GRANTED; 6738 } 6739 6740 return ActivityManager.checkComponentPermission(permission, uid, 6741 owningUid, exported); 6742 } 6743 6744 /** 6745 * As the only public entry point for permissions checking, this method 6746 * can enforce the semantic that requesting a check on a null global 6747 * permission is automatically denied. (Internally a null permission 6748 * string is used when calling {@link #checkComponentPermission} in cases 6749 * when only uid-based security is needed.) 6750 * 6751 * This can be called with or without the global lock held. 6752 */ 6753 @Override 6754 public int checkPermission(String permission, int pid, int uid) { 6755 if (permission == null) { 6756 return PackageManager.PERMISSION_DENIED; 6757 } 6758 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6759 } 6760 6761 /** 6762 * Binder IPC calls go through the public entry point. 6763 * This can be called with or without the global lock held. 6764 */ 6765 int checkCallingPermission(String permission) { 6766 return checkPermission(permission, 6767 Binder.getCallingPid(), 6768 UserHandle.getAppId(Binder.getCallingUid())); 6769 } 6770 6771 /** 6772 * This can be called with or without the global lock held. 6773 */ 6774 void enforceCallingPermission(String permission, String func) { 6775 if (checkCallingPermission(permission) 6776 == PackageManager.PERMISSION_GRANTED) { 6777 return; 6778 } 6779 6780 String msg = "Permission Denial: " + func + " from pid=" 6781 + Binder.getCallingPid() 6782 + ", uid=" + Binder.getCallingUid() 6783 + " requires " + permission; 6784 Slog.w(TAG, msg); 6785 throw new SecurityException(msg); 6786 } 6787 6788 /** 6789 * Determine if UID is holding permissions required to access {@link Uri} in 6790 * the given {@link ProviderInfo}. Final permission checking is always done 6791 * in {@link ContentProvider}. 6792 */ 6793 private final boolean checkHoldingPermissionsLocked( 6794 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6795 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6796 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6797 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6798 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6799 != PERMISSION_GRANTED) { 6800 return false; 6801 } 6802 } 6803 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6804 } 6805 6806 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6807 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6808 if (pi.applicationInfo.uid == uid) { 6809 return true; 6810 } else if (!pi.exported) { 6811 return false; 6812 } 6813 6814 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6815 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6816 try { 6817 // check if target holds top-level <provider> permissions 6818 if (!readMet && pi.readPermission != null && considerUidPermissions 6819 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6820 readMet = true; 6821 } 6822 if (!writeMet && pi.writePermission != null && considerUidPermissions 6823 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6824 writeMet = true; 6825 } 6826 6827 // track if unprotected read/write is allowed; any denied 6828 // <path-permission> below removes this ability 6829 boolean allowDefaultRead = pi.readPermission == null; 6830 boolean allowDefaultWrite = pi.writePermission == null; 6831 6832 // check if target holds any <path-permission> that match uri 6833 final PathPermission[] pps = pi.pathPermissions; 6834 if (pps != null) { 6835 final String path = grantUri.uri.getPath(); 6836 int i = pps.length; 6837 while (i > 0 && (!readMet || !writeMet)) { 6838 i--; 6839 PathPermission pp = pps[i]; 6840 if (pp.match(path)) { 6841 if (!readMet) { 6842 final String pprperm = pp.getReadPermission(); 6843 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6844 + pprperm + " for " + pp.getPath() 6845 + ": match=" + pp.match(path) 6846 + " check=" + pm.checkUidPermission(pprperm, uid)); 6847 if (pprperm != null) { 6848 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6849 == PERMISSION_GRANTED) { 6850 readMet = true; 6851 } else { 6852 allowDefaultRead = false; 6853 } 6854 } 6855 } 6856 if (!writeMet) { 6857 final String ppwperm = pp.getWritePermission(); 6858 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6859 + ppwperm + " for " + pp.getPath() 6860 + ": match=" + pp.match(path) 6861 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6862 if (ppwperm != null) { 6863 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6864 == PERMISSION_GRANTED) { 6865 writeMet = true; 6866 } else { 6867 allowDefaultWrite = false; 6868 } 6869 } 6870 } 6871 } 6872 } 6873 } 6874 6875 // grant unprotected <provider> read/write, if not blocked by 6876 // <path-permission> above 6877 if (allowDefaultRead) readMet = true; 6878 if (allowDefaultWrite) writeMet = true; 6879 6880 } catch (RemoteException e) { 6881 return false; 6882 } 6883 6884 return readMet && writeMet; 6885 } 6886 6887 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6888 ProviderInfo pi = null; 6889 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6890 if (cpr != null) { 6891 pi = cpr.info; 6892 } else { 6893 try { 6894 pi = AppGlobals.getPackageManager().resolveContentProvider( 6895 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6896 } catch (RemoteException ex) { 6897 } 6898 } 6899 return pi; 6900 } 6901 6902 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6903 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6904 if (targetUris != null) { 6905 return targetUris.get(grantUri); 6906 } 6907 return null; 6908 } 6909 6910 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6911 String targetPkg, int targetUid, GrantUri grantUri) { 6912 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6913 if (targetUris == null) { 6914 targetUris = Maps.newArrayMap(); 6915 mGrantedUriPermissions.put(targetUid, targetUris); 6916 } 6917 6918 UriPermission perm = targetUris.get(grantUri); 6919 if (perm == null) { 6920 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6921 targetUris.put(grantUri, perm); 6922 } 6923 6924 return perm; 6925 } 6926 6927 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6928 final int modeFlags) { 6929 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6930 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6931 : UriPermission.STRENGTH_OWNED; 6932 6933 // Root gets to do everything. 6934 if (uid == 0) { 6935 return true; 6936 } 6937 6938 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6939 if (perms == null) return false; 6940 6941 // First look for exact match 6942 final UriPermission exactPerm = perms.get(grantUri); 6943 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6944 return true; 6945 } 6946 6947 // No exact match, look for prefixes 6948 final int N = perms.size(); 6949 for (int i = 0; i < N; i++) { 6950 final UriPermission perm = perms.valueAt(i); 6951 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6952 && perm.getStrength(modeFlags) >= minStrength) { 6953 return true; 6954 } 6955 } 6956 6957 return false; 6958 } 6959 6960 /** 6961 * @param uri This uri must NOT contain an embedded userId. 6962 * @param userId The userId in which the uri is to be resolved. 6963 */ 6964 @Override 6965 public int checkUriPermission(Uri uri, int pid, int uid, 6966 final int modeFlags, int userId) { 6967 enforceNotIsolatedCaller("checkUriPermission"); 6968 6969 // Another redirected-binder-call permissions check as in 6970 // {@link checkComponentPermission}. 6971 Identity tlsIdentity = sCallerIdentity.get(); 6972 if (tlsIdentity != null) { 6973 uid = tlsIdentity.uid; 6974 pid = tlsIdentity.pid; 6975 } 6976 6977 // Our own process gets to do everything. 6978 if (pid == MY_PID) { 6979 return PackageManager.PERMISSION_GRANTED; 6980 } 6981 synchronized (this) { 6982 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6983 ? PackageManager.PERMISSION_GRANTED 6984 : PackageManager.PERMISSION_DENIED; 6985 } 6986 } 6987 6988 /** 6989 * Check if the targetPkg can be granted permission to access uri by 6990 * the callingUid using the given modeFlags. Throws a security exception 6991 * if callingUid is not allowed to do this. Returns the uid of the target 6992 * if the URI permission grant should be performed; returns -1 if it is not 6993 * needed (for example targetPkg already has permission to access the URI). 6994 * If you already know the uid of the target, you can supply it in 6995 * lastTargetUid else set that to -1. 6996 */ 6997 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6998 final int modeFlags, int lastTargetUid) { 6999 if (!Intent.isAccessUriMode(modeFlags)) { 7000 return -1; 7001 } 7002 7003 if (targetPkg != null) { 7004 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7005 "Checking grant " + targetPkg + " permission to " + grantUri); 7006 } 7007 7008 final IPackageManager pm = AppGlobals.getPackageManager(); 7009 7010 // If this is not a content: uri, we can't do anything with it. 7011 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7012 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7013 "Can't grant URI permission for non-content URI: " + grantUri); 7014 return -1; 7015 } 7016 7017 final String authority = grantUri.uri.getAuthority(); 7018 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7019 if (pi == null) { 7020 Slog.w(TAG, "No content provider found for permission check: " + 7021 grantUri.uri.toSafeString()); 7022 return -1; 7023 } 7024 7025 int targetUid = lastTargetUid; 7026 if (targetUid < 0 && targetPkg != null) { 7027 try { 7028 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7029 if (targetUid < 0) { 7030 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7031 "Can't grant URI permission no uid for: " + targetPkg); 7032 return -1; 7033 } 7034 } catch (RemoteException ex) { 7035 return -1; 7036 } 7037 } 7038 7039 if (targetUid >= 0) { 7040 // First... does the target actually need this permission? 7041 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7042 // No need to grant the target this permission. 7043 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7044 "Target " + targetPkg + " already has full permission to " + grantUri); 7045 return -1; 7046 } 7047 } else { 7048 // First... there is no target package, so can anyone access it? 7049 boolean allowed = pi.exported; 7050 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7051 if (pi.readPermission != null) { 7052 allowed = false; 7053 } 7054 } 7055 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7056 if (pi.writePermission != null) { 7057 allowed = false; 7058 } 7059 } 7060 if (allowed) { 7061 return -1; 7062 } 7063 } 7064 7065 /* There is a special cross user grant if: 7066 * - The target is on another user. 7067 * - Apps on the current user can access the uri without any uid permissions. 7068 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7069 * grant uri permissions. 7070 */ 7071 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7072 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7073 modeFlags, false /*without considering the uid permissions*/); 7074 7075 // Second... is the provider allowing granting of URI permissions? 7076 if (!specialCrossUserGrant) { 7077 if (!pi.grantUriPermissions) { 7078 throw new SecurityException("Provider " + pi.packageName 7079 + "/" + pi.name 7080 + " does not allow granting of Uri permissions (uri " 7081 + grantUri + ")"); 7082 } 7083 if (pi.uriPermissionPatterns != null) { 7084 final int N = pi.uriPermissionPatterns.length; 7085 boolean allowed = false; 7086 for (int i=0; i<N; i++) { 7087 if (pi.uriPermissionPatterns[i] != null 7088 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7089 allowed = true; 7090 break; 7091 } 7092 } 7093 if (!allowed) { 7094 throw new SecurityException("Provider " + pi.packageName 7095 + "/" + pi.name 7096 + " does not allow granting of permission to path of Uri " 7097 + grantUri); 7098 } 7099 } 7100 } 7101 7102 // Third... does the caller itself have permission to access 7103 // this uri? 7104 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7105 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7106 // Require they hold a strong enough Uri permission 7107 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7108 throw new SecurityException("Uid " + callingUid 7109 + " does not have permission to uri " + grantUri); 7110 } 7111 } 7112 } 7113 return targetUid; 7114 } 7115 7116 /** 7117 * @param uri This uri must NOT contain an embedded userId. 7118 * @param userId The userId in which the uri is to be resolved. 7119 */ 7120 @Override 7121 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7122 final int modeFlags, int userId) { 7123 enforceNotIsolatedCaller("checkGrantUriPermission"); 7124 synchronized(this) { 7125 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7126 new GrantUri(userId, uri, false), modeFlags, -1); 7127 } 7128 } 7129 7130 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7131 final int modeFlags, UriPermissionOwner owner) { 7132 if (!Intent.isAccessUriMode(modeFlags)) { 7133 return; 7134 } 7135 7136 // So here we are: the caller has the assumed permission 7137 // to the uri, and the target doesn't. Let's now give this to 7138 // the target. 7139 7140 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7141 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7142 7143 final String authority = grantUri.uri.getAuthority(); 7144 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7145 if (pi == null) { 7146 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7147 return; 7148 } 7149 7150 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7151 grantUri.prefix = true; 7152 } 7153 final UriPermission perm = findOrCreateUriPermissionLocked( 7154 pi.packageName, targetPkg, targetUid, grantUri); 7155 perm.grantModes(modeFlags, owner); 7156 } 7157 7158 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7159 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7160 if (targetPkg == null) { 7161 throw new NullPointerException("targetPkg"); 7162 } 7163 int targetUid; 7164 final IPackageManager pm = AppGlobals.getPackageManager(); 7165 try { 7166 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7167 } catch (RemoteException ex) { 7168 return; 7169 } 7170 7171 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7172 targetUid); 7173 if (targetUid < 0) { 7174 return; 7175 } 7176 7177 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7178 owner); 7179 } 7180 7181 static class NeededUriGrants extends ArrayList<GrantUri> { 7182 final String targetPkg; 7183 final int targetUid; 7184 final int flags; 7185 7186 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7187 this.targetPkg = targetPkg; 7188 this.targetUid = targetUid; 7189 this.flags = flags; 7190 } 7191 } 7192 7193 /** 7194 * Like checkGrantUriPermissionLocked, but takes an Intent. 7195 */ 7196 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7197 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7198 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7199 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7200 + " clip=" + (intent != null ? intent.getClipData() : null) 7201 + " from " + intent + "; flags=0x" 7202 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7203 7204 if (targetPkg == null) { 7205 throw new NullPointerException("targetPkg"); 7206 } 7207 7208 if (intent == null) { 7209 return null; 7210 } 7211 Uri data = intent.getData(); 7212 ClipData clip = intent.getClipData(); 7213 if (data == null && clip == null) { 7214 return null; 7215 } 7216 // Default userId for uris in the intent (if they don't specify it themselves) 7217 int contentUserHint = intent.getContentUserHint(); 7218 if (contentUserHint == UserHandle.USER_CURRENT) { 7219 contentUserHint = UserHandle.getUserId(callingUid); 7220 } 7221 final IPackageManager pm = AppGlobals.getPackageManager(); 7222 int targetUid; 7223 if (needed != null) { 7224 targetUid = needed.targetUid; 7225 } else { 7226 try { 7227 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7228 } catch (RemoteException ex) { 7229 return null; 7230 } 7231 if (targetUid < 0) { 7232 if (DEBUG_URI_PERMISSION) { 7233 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7234 + " on user " + targetUserId); 7235 } 7236 return null; 7237 } 7238 } 7239 if (data != null) { 7240 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7241 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7242 targetUid); 7243 if (targetUid > 0) { 7244 if (needed == null) { 7245 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7246 } 7247 needed.add(grantUri); 7248 } 7249 } 7250 if (clip != null) { 7251 for (int i=0; i<clip.getItemCount(); i++) { 7252 Uri uri = clip.getItemAt(i).getUri(); 7253 if (uri != null) { 7254 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7255 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7256 targetUid); 7257 if (targetUid > 0) { 7258 if (needed == null) { 7259 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7260 } 7261 needed.add(grantUri); 7262 } 7263 } else { 7264 Intent clipIntent = clip.getItemAt(i).getIntent(); 7265 if (clipIntent != null) { 7266 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7267 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7268 if (newNeeded != null) { 7269 needed = newNeeded; 7270 } 7271 } 7272 } 7273 } 7274 } 7275 7276 return needed; 7277 } 7278 7279 /** 7280 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7281 */ 7282 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7283 UriPermissionOwner owner) { 7284 if (needed != null) { 7285 for (int i=0; i<needed.size(); i++) { 7286 GrantUri grantUri = needed.get(i); 7287 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7288 grantUri, needed.flags, owner); 7289 } 7290 } 7291 } 7292 7293 void grantUriPermissionFromIntentLocked(int callingUid, 7294 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7295 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7296 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7297 if (needed == null) { 7298 return; 7299 } 7300 7301 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7302 } 7303 7304 /** 7305 * @param uri This uri must NOT contain an embedded userId. 7306 * @param userId The userId in which the uri is to be resolved. 7307 */ 7308 @Override 7309 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7310 final int modeFlags, int userId) { 7311 enforceNotIsolatedCaller("grantUriPermission"); 7312 GrantUri grantUri = new GrantUri(userId, uri, false); 7313 synchronized(this) { 7314 final ProcessRecord r = getRecordForAppLocked(caller); 7315 if (r == null) { 7316 throw new SecurityException("Unable to find app for caller " 7317 + caller 7318 + " when granting permission to uri " + grantUri); 7319 } 7320 if (targetPkg == null) { 7321 throw new IllegalArgumentException("null target"); 7322 } 7323 if (grantUri == null) { 7324 throw new IllegalArgumentException("null uri"); 7325 } 7326 7327 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7328 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7329 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7330 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7331 7332 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7333 UserHandle.getUserId(r.uid)); 7334 } 7335 } 7336 7337 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7338 if (perm.modeFlags == 0) { 7339 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7340 perm.targetUid); 7341 if (perms != null) { 7342 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7343 "Removing " + perm.targetUid + " permission to " + perm.uri); 7344 7345 perms.remove(perm.uri); 7346 if (perms.isEmpty()) { 7347 mGrantedUriPermissions.remove(perm.targetUid); 7348 } 7349 } 7350 } 7351 } 7352 7353 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7354 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7355 7356 final IPackageManager pm = AppGlobals.getPackageManager(); 7357 final String authority = grantUri.uri.getAuthority(); 7358 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7359 if (pi == null) { 7360 Slog.w(TAG, "No content provider found for permission revoke: " 7361 + grantUri.toSafeString()); 7362 return; 7363 } 7364 7365 // Does the caller have this permission on the URI? 7366 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7367 // If they don't have direct access to the URI, then revoke any 7368 // ownerless URI permissions that have been granted to them. 7369 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7370 if (perms != null) { 7371 boolean persistChanged = false; 7372 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7373 final UriPermission perm = it.next(); 7374 if (perm.uri.sourceUserId == grantUri.sourceUserId 7375 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7376 if (DEBUG_URI_PERMISSION) 7377 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7378 " permission to " + perm.uri); 7379 persistChanged |= perm.revokeModes( 7380 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7381 if (perm.modeFlags == 0) { 7382 it.remove(); 7383 } 7384 } 7385 } 7386 if (perms.isEmpty()) { 7387 mGrantedUriPermissions.remove(callingUid); 7388 } 7389 if (persistChanged) { 7390 schedulePersistUriGrants(); 7391 } 7392 } 7393 return; 7394 } 7395 7396 boolean persistChanged = false; 7397 7398 // Go through all of the permissions and remove any that match. 7399 int N = mGrantedUriPermissions.size(); 7400 for (int i = 0; i < N; i++) { 7401 final int targetUid = mGrantedUriPermissions.keyAt(i); 7402 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7403 7404 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7405 final UriPermission perm = it.next(); 7406 if (perm.uri.sourceUserId == grantUri.sourceUserId 7407 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7408 if (DEBUG_URI_PERMISSION) 7409 Slog.v(TAG, 7410 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7411 persistChanged |= perm.revokeModes( 7412 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7413 if (perm.modeFlags == 0) { 7414 it.remove(); 7415 } 7416 } 7417 } 7418 7419 if (perms.isEmpty()) { 7420 mGrantedUriPermissions.remove(targetUid); 7421 N--; 7422 i--; 7423 } 7424 } 7425 7426 if (persistChanged) { 7427 schedulePersistUriGrants(); 7428 } 7429 } 7430 7431 /** 7432 * @param uri This uri must NOT contain an embedded userId. 7433 * @param userId The userId in which the uri is to be resolved. 7434 */ 7435 @Override 7436 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7437 int userId) { 7438 enforceNotIsolatedCaller("revokeUriPermission"); 7439 synchronized(this) { 7440 final ProcessRecord r = getRecordForAppLocked(caller); 7441 if (r == null) { 7442 throw new SecurityException("Unable to find app for caller " 7443 + caller 7444 + " when revoking permission to uri " + uri); 7445 } 7446 if (uri == null) { 7447 Slog.w(TAG, "revokeUriPermission: null uri"); 7448 return; 7449 } 7450 7451 if (!Intent.isAccessUriMode(modeFlags)) { 7452 return; 7453 } 7454 7455 final IPackageManager pm = AppGlobals.getPackageManager(); 7456 final String authority = uri.getAuthority(); 7457 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7458 if (pi == null) { 7459 Slog.w(TAG, "No content provider found for permission revoke: " 7460 + uri.toSafeString()); 7461 return; 7462 } 7463 7464 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7465 } 7466 } 7467 7468 /** 7469 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7470 * given package. 7471 * 7472 * @param packageName Package name to match, or {@code null} to apply to all 7473 * packages. 7474 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7475 * to all users. 7476 * @param persistable If persistable grants should be removed. 7477 */ 7478 private void removeUriPermissionsForPackageLocked( 7479 String packageName, int userHandle, boolean persistable) { 7480 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7481 throw new IllegalArgumentException("Must narrow by either package or user"); 7482 } 7483 7484 boolean persistChanged = false; 7485 7486 int N = mGrantedUriPermissions.size(); 7487 for (int i = 0; i < N; i++) { 7488 final int targetUid = mGrantedUriPermissions.keyAt(i); 7489 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7490 7491 // Only inspect grants matching user 7492 if (userHandle == UserHandle.USER_ALL 7493 || userHandle == UserHandle.getUserId(targetUid)) { 7494 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7495 final UriPermission perm = it.next(); 7496 7497 // Only inspect grants matching package 7498 if (packageName == null || perm.sourcePkg.equals(packageName) 7499 || perm.targetPkg.equals(packageName)) { 7500 persistChanged |= perm.revokeModes(persistable 7501 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7502 7503 // Only remove when no modes remain; any persisted grants 7504 // will keep this alive. 7505 if (perm.modeFlags == 0) { 7506 it.remove(); 7507 } 7508 } 7509 } 7510 7511 if (perms.isEmpty()) { 7512 mGrantedUriPermissions.remove(targetUid); 7513 N--; 7514 i--; 7515 } 7516 } 7517 } 7518 7519 if (persistChanged) { 7520 schedulePersistUriGrants(); 7521 } 7522 } 7523 7524 @Override 7525 public IBinder newUriPermissionOwner(String name) { 7526 enforceNotIsolatedCaller("newUriPermissionOwner"); 7527 synchronized(this) { 7528 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7529 return owner.getExternalTokenLocked(); 7530 } 7531 } 7532 7533 /** 7534 * @param uri This uri must NOT contain an embedded userId. 7535 * @param sourceUserId The userId in which the uri is to be resolved. 7536 * @param targetUserId The userId of the app that receives the grant. 7537 */ 7538 @Override 7539 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7540 final int modeFlags, int sourceUserId, int targetUserId) { 7541 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7542 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7543 synchronized(this) { 7544 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7545 if (owner == null) { 7546 throw new IllegalArgumentException("Unknown owner: " + token); 7547 } 7548 if (fromUid != Binder.getCallingUid()) { 7549 if (Binder.getCallingUid() != Process.myUid()) { 7550 // Only system code can grant URI permissions on behalf 7551 // of other users. 7552 throw new SecurityException("nice try"); 7553 } 7554 } 7555 if (targetPkg == null) { 7556 throw new IllegalArgumentException("null target"); 7557 } 7558 if (uri == null) { 7559 throw new IllegalArgumentException("null uri"); 7560 } 7561 7562 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7563 modeFlags, owner, targetUserId); 7564 } 7565 } 7566 7567 /** 7568 * @param uri This uri must NOT contain an embedded userId. 7569 * @param userId The userId in which the uri is to be resolved. 7570 */ 7571 @Override 7572 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7573 synchronized(this) { 7574 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7575 if (owner == null) { 7576 throw new IllegalArgumentException("Unknown owner: " + token); 7577 } 7578 7579 if (uri == null) { 7580 owner.removeUriPermissionsLocked(mode); 7581 } else { 7582 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7583 } 7584 } 7585 } 7586 7587 private void schedulePersistUriGrants() { 7588 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7589 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7590 10 * DateUtils.SECOND_IN_MILLIS); 7591 } 7592 } 7593 7594 private void writeGrantedUriPermissions() { 7595 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7596 7597 // Snapshot permissions so we can persist without lock 7598 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7599 synchronized (this) { 7600 final int size = mGrantedUriPermissions.size(); 7601 for (int i = 0; i < size; i++) { 7602 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7603 for (UriPermission perm : perms.values()) { 7604 if (perm.persistedModeFlags != 0) { 7605 persist.add(perm.snapshot()); 7606 } 7607 } 7608 } 7609 } 7610 7611 FileOutputStream fos = null; 7612 try { 7613 fos = mGrantFile.startWrite(); 7614 7615 XmlSerializer out = new FastXmlSerializer(); 7616 out.setOutput(fos, "utf-8"); 7617 out.startDocument(null, true); 7618 out.startTag(null, TAG_URI_GRANTS); 7619 for (UriPermission.Snapshot perm : persist) { 7620 out.startTag(null, TAG_URI_GRANT); 7621 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7622 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7623 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7624 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7625 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7626 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7627 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7628 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7629 out.endTag(null, TAG_URI_GRANT); 7630 } 7631 out.endTag(null, TAG_URI_GRANTS); 7632 out.endDocument(); 7633 7634 mGrantFile.finishWrite(fos); 7635 } catch (IOException e) { 7636 if (fos != null) { 7637 mGrantFile.failWrite(fos); 7638 } 7639 } 7640 } 7641 7642 private void readGrantedUriPermissionsLocked() { 7643 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7644 7645 final long now = System.currentTimeMillis(); 7646 7647 FileInputStream fis = null; 7648 try { 7649 fis = mGrantFile.openRead(); 7650 final XmlPullParser in = Xml.newPullParser(); 7651 in.setInput(fis, null); 7652 7653 int type; 7654 while ((type = in.next()) != END_DOCUMENT) { 7655 final String tag = in.getName(); 7656 if (type == START_TAG) { 7657 if (TAG_URI_GRANT.equals(tag)) { 7658 final int sourceUserId; 7659 final int targetUserId; 7660 final int userHandle = readIntAttribute(in, 7661 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7662 if (userHandle != UserHandle.USER_NULL) { 7663 // For backwards compatibility. 7664 sourceUserId = userHandle; 7665 targetUserId = userHandle; 7666 } else { 7667 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7668 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7669 } 7670 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7671 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7672 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7673 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7674 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7675 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7676 7677 // Sanity check that provider still belongs to source package 7678 final ProviderInfo pi = getProviderInfoLocked( 7679 uri.getAuthority(), sourceUserId); 7680 if (pi != null && sourcePkg.equals(pi.packageName)) { 7681 int targetUid = -1; 7682 try { 7683 targetUid = AppGlobals.getPackageManager() 7684 .getPackageUid(targetPkg, targetUserId); 7685 } catch (RemoteException e) { 7686 } 7687 if (targetUid != -1) { 7688 final UriPermission perm = findOrCreateUriPermissionLocked( 7689 sourcePkg, targetPkg, targetUid, 7690 new GrantUri(sourceUserId, uri, prefix)); 7691 perm.initPersistedModes(modeFlags, createdTime); 7692 } 7693 } else { 7694 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7695 + " but instead found " + pi); 7696 } 7697 } 7698 } 7699 } 7700 } catch (FileNotFoundException e) { 7701 // Missing grants is okay 7702 } catch (IOException e) { 7703 Slog.wtf(TAG, "Failed reading Uri grants", e); 7704 } catch (XmlPullParserException e) { 7705 Slog.wtf(TAG, "Failed reading Uri grants", e); 7706 } finally { 7707 IoUtils.closeQuietly(fis); 7708 } 7709 } 7710 7711 /** 7712 * @param uri This uri must NOT contain an embedded userId. 7713 * @param userId The userId in which the uri is to be resolved. 7714 */ 7715 @Override 7716 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7717 enforceNotIsolatedCaller("takePersistableUriPermission"); 7718 7719 Preconditions.checkFlagsArgument(modeFlags, 7720 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7721 7722 synchronized (this) { 7723 final int callingUid = Binder.getCallingUid(); 7724 boolean persistChanged = false; 7725 GrantUri grantUri = new GrantUri(userId, uri, false); 7726 7727 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7728 new GrantUri(userId, uri, false)); 7729 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7730 new GrantUri(userId, uri, true)); 7731 7732 final boolean exactValid = (exactPerm != null) 7733 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7734 final boolean prefixValid = (prefixPerm != null) 7735 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7736 7737 if (!(exactValid || prefixValid)) { 7738 throw new SecurityException("No persistable permission grants found for UID " 7739 + callingUid + " and Uri " + grantUri.toSafeString()); 7740 } 7741 7742 if (exactValid) { 7743 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7744 } 7745 if (prefixValid) { 7746 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7747 } 7748 7749 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7750 7751 if (persistChanged) { 7752 schedulePersistUriGrants(); 7753 } 7754 } 7755 } 7756 7757 /** 7758 * @param uri This uri must NOT contain an embedded userId. 7759 * @param userId The userId in which the uri is to be resolved. 7760 */ 7761 @Override 7762 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7763 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7764 7765 Preconditions.checkFlagsArgument(modeFlags, 7766 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7767 7768 synchronized (this) { 7769 final int callingUid = Binder.getCallingUid(); 7770 boolean persistChanged = false; 7771 7772 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7773 new GrantUri(userId, uri, false)); 7774 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7775 new GrantUri(userId, uri, true)); 7776 if (exactPerm == null && prefixPerm == null) { 7777 throw new SecurityException("No permission grants found for UID " + callingUid 7778 + " and Uri " + uri.toSafeString()); 7779 } 7780 7781 if (exactPerm != null) { 7782 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7783 removeUriPermissionIfNeededLocked(exactPerm); 7784 } 7785 if (prefixPerm != null) { 7786 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7787 removeUriPermissionIfNeededLocked(prefixPerm); 7788 } 7789 7790 if (persistChanged) { 7791 schedulePersistUriGrants(); 7792 } 7793 } 7794 } 7795 7796 /** 7797 * Prune any older {@link UriPermission} for the given UID until outstanding 7798 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7799 * 7800 * @return if any mutations occured that require persisting. 7801 */ 7802 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7803 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7804 if (perms == null) return false; 7805 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7806 7807 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7808 for (UriPermission perm : perms.values()) { 7809 if (perm.persistedModeFlags != 0) { 7810 persisted.add(perm); 7811 } 7812 } 7813 7814 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7815 if (trimCount <= 0) return false; 7816 7817 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7818 for (int i = 0; i < trimCount; i++) { 7819 final UriPermission perm = persisted.get(i); 7820 7821 if (DEBUG_URI_PERMISSION) { 7822 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7823 } 7824 7825 perm.releasePersistableModes(~0); 7826 removeUriPermissionIfNeededLocked(perm); 7827 } 7828 7829 return true; 7830 } 7831 7832 @Override 7833 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7834 String packageName, boolean incoming) { 7835 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7836 Preconditions.checkNotNull(packageName, "packageName"); 7837 7838 final int callingUid = Binder.getCallingUid(); 7839 final IPackageManager pm = AppGlobals.getPackageManager(); 7840 try { 7841 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7842 if (packageUid != callingUid) { 7843 throw new SecurityException( 7844 "Package " + packageName + " does not belong to calling UID " + callingUid); 7845 } 7846 } catch (RemoteException e) { 7847 throw new SecurityException("Failed to verify package name ownership"); 7848 } 7849 7850 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7851 synchronized (this) { 7852 if (incoming) { 7853 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7854 callingUid); 7855 if (perms == null) { 7856 Slog.w(TAG, "No permission grants found for " + packageName); 7857 } else { 7858 for (UriPermission perm : perms.values()) { 7859 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7860 result.add(perm.buildPersistedPublicApiObject()); 7861 } 7862 } 7863 } 7864 } else { 7865 final int size = mGrantedUriPermissions.size(); 7866 for (int i = 0; i < size; i++) { 7867 final ArrayMap<GrantUri, UriPermission> perms = 7868 mGrantedUriPermissions.valueAt(i); 7869 for (UriPermission perm : perms.values()) { 7870 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7871 result.add(perm.buildPersistedPublicApiObject()); 7872 } 7873 } 7874 } 7875 } 7876 } 7877 return new ParceledListSlice<android.content.UriPermission>(result); 7878 } 7879 7880 @Override 7881 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7882 synchronized (this) { 7883 ProcessRecord app = 7884 who != null ? getRecordForAppLocked(who) : null; 7885 if (app == null) return; 7886 7887 Message msg = Message.obtain(); 7888 msg.what = WAIT_FOR_DEBUGGER_MSG; 7889 msg.obj = app; 7890 msg.arg1 = waiting ? 1 : 0; 7891 mHandler.sendMessage(msg); 7892 } 7893 } 7894 7895 @Override 7896 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7897 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7898 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7899 outInfo.availMem = Process.getFreeMemory(); 7900 outInfo.totalMem = Process.getTotalMemory(); 7901 outInfo.threshold = homeAppMem; 7902 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7903 outInfo.hiddenAppThreshold = cachedAppMem; 7904 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7905 ProcessList.SERVICE_ADJ); 7906 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7907 ProcessList.VISIBLE_APP_ADJ); 7908 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7909 ProcessList.FOREGROUND_APP_ADJ); 7910 } 7911 7912 // ========================================================= 7913 // TASK MANAGEMENT 7914 // ========================================================= 7915 7916 @Override 7917 public List<IAppTask> getAppTasks(String callingPackage) { 7918 int callingUid = Binder.getCallingUid(); 7919 long ident = Binder.clearCallingIdentity(); 7920 7921 synchronized(this) { 7922 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7923 try { 7924 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7925 7926 final int N = mRecentTasks.size(); 7927 for (int i = 0; i < N; i++) { 7928 TaskRecord tr = mRecentTasks.get(i); 7929 // Skip tasks that do not match the caller. We don't need to verify 7930 // callingPackage, because we are also limiting to callingUid and know 7931 // that will limit to the correct security sandbox. 7932 if (tr.effectiveUid != callingUid) { 7933 continue; 7934 } 7935 Intent intent = tr.getBaseIntent(); 7936 if (intent == null || 7937 !callingPackage.equals(intent.getComponent().getPackageName())) { 7938 continue; 7939 } 7940 ActivityManager.RecentTaskInfo taskInfo = 7941 createRecentTaskInfoFromTaskRecord(tr); 7942 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7943 list.add(taskImpl); 7944 } 7945 } finally { 7946 Binder.restoreCallingIdentity(ident); 7947 } 7948 return list; 7949 } 7950 } 7951 7952 @Override 7953 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7954 final int callingUid = Binder.getCallingUid(); 7955 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7956 7957 synchronized(this) { 7958 if (localLOGV) Slog.v( 7959 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7960 7961 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 7962 callingUid); 7963 7964 // TODO: Improve with MRU list from all ActivityStacks. 7965 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7966 } 7967 7968 return list; 7969 } 7970 7971 TaskRecord getMostRecentTask() { 7972 return mRecentTasks.get(0); 7973 } 7974 7975 /** 7976 * Creates a new RecentTaskInfo from a TaskRecord. 7977 */ 7978 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7979 // Update the task description to reflect any changes in the task stack 7980 tr.updateTaskDescription(); 7981 7982 // Compose the recent task info 7983 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7984 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7985 rti.persistentId = tr.taskId; 7986 rti.baseIntent = new Intent(tr.getBaseIntent()); 7987 rti.origActivity = tr.origActivity; 7988 rti.description = tr.lastDescription; 7989 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7990 rti.userId = tr.userId; 7991 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7992 rti.firstActiveTime = tr.firstActiveTime; 7993 rti.lastActiveTime = tr.lastActiveTime; 7994 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7995 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 7996 return rti; 7997 } 7998 7999 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8000 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8001 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8002 if (!allowed) { 8003 if (checkPermission(android.Manifest.permission.GET_TASKS, 8004 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8005 // Temporary compatibility: some existing apps on the system image may 8006 // still be requesting the old permission and not switched to the new 8007 // one; if so, we'll still allow them full access. This means we need 8008 // to see if they are holding the old permission and are a system app. 8009 try { 8010 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8011 allowed = true; 8012 Slog.w(TAG, caller + ": caller " + callingUid 8013 + " is using old GET_TASKS but privileged; allowing"); 8014 } 8015 } catch (RemoteException e) { 8016 } 8017 } 8018 } 8019 if (!allowed) { 8020 Slog.w(TAG, caller + ": caller " + callingUid 8021 + " does not hold GET_TASKS; limiting output"); 8022 } 8023 return allowed; 8024 } 8025 8026 @Override 8027 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8028 final int callingUid = Binder.getCallingUid(); 8029 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8030 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8031 8032 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8033 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8034 synchronized (this) { 8035 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8036 callingUid); 8037 final boolean detailed = checkCallingPermission( 8038 android.Manifest.permission.GET_DETAILED_TASKS) 8039 == PackageManager.PERMISSION_GRANTED; 8040 8041 final int N = mRecentTasks.size(); 8042 ArrayList<ActivityManager.RecentTaskInfo> res 8043 = new ArrayList<ActivityManager.RecentTaskInfo>( 8044 maxNum < N ? maxNum : N); 8045 8046 final Set<Integer> includedUsers; 8047 if (includeProfiles) { 8048 includedUsers = getProfileIdsLocked(userId); 8049 } else { 8050 includedUsers = new HashSet<Integer>(); 8051 } 8052 includedUsers.add(Integer.valueOf(userId)); 8053 8054 for (int i=0; i<N && maxNum > 0; i++) { 8055 TaskRecord tr = mRecentTasks.get(i); 8056 // Only add calling user or related users recent tasks 8057 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8058 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8059 continue; 8060 } 8061 8062 // Return the entry if desired by the caller. We always return 8063 // the first entry, because callers always expect this to be the 8064 // foreground app. We may filter others if the caller has 8065 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8066 // we should exclude the entry. 8067 8068 if (i == 0 8069 || withExcluded 8070 || (tr.intent == null) 8071 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8072 == 0)) { 8073 if (!allowed) { 8074 // If the caller doesn't have the GET_TASKS permission, then only 8075 // allow them to see a small subset of tasks -- their own and home. 8076 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8077 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8078 continue; 8079 } 8080 } 8081 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8082 if (tr.stack != null && tr.stack.isHomeStack()) { 8083 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8084 continue; 8085 } 8086 } 8087 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8088 // Don't include auto remove tasks that are finished or finishing. 8089 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8090 + tr); 8091 continue; 8092 } 8093 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8094 && !tr.isAvailable) { 8095 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8096 continue; 8097 } 8098 8099 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8100 if (!detailed) { 8101 rti.baseIntent.replaceExtras((Bundle)null); 8102 } 8103 8104 res.add(rti); 8105 maxNum--; 8106 } 8107 } 8108 return res; 8109 } 8110 } 8111 8112 private TaskRecord taskForIdLocked(int id) { 8113 final TaskRecord task = recentTaskForIdLocked(id); 8114 if (task != null) { 8115 return task; 8116 } 8117 8118 // Don't give up. Sometimes it just hasn't made it to recents yet. 8119 return mStackSupervisor.anyTaskForIdLocked(id); 8120 } 8121 8122 private TaskRecord recentTaskForIdLocked(int id) { 8123 final int N = mRecentTasks.size(); 8124 for (int i=0; i<N; i++) { 8125 TaskRecord tr = mRecentTasks.get(i); 8126 if (tr.taskId == id) { 8127 return tr; 8128 } 8129 } 8130 return null; 8131 } 8132 8133 @Override 8134 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8135 synchronized (this) { 8136 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8137 "getTaskThumbnail()"); 8138 TaskRecord tr = recentTaskForIdLocked(id); 8139 if (tr != null) { 8140 return tr.getTaskThumbnailLocked(); 8141 } 8142 } 8143 return null; 8144 } 8145 8146 @Override 8147 public int addAppTask(IBinder activityToken, Intent intent, 8148 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8149 final int callingUid = Binder.getCallingUid(); 8150 final long callingIdent = Binder.clearCallingIdentity(); 8151 8152 try { 8153 synchronized (this) { 8154 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8155 if (r == null) { 8156 throw new IllegalArgumentException("Activity does not exist; token=" 8157 + activityToken); 8158 } 8159 ComponentName comp = intent.getComponent(); 8160 if (comp == null) { 8161 throw new IllegalArgumentException("Intent " + intent 8162 + " must specify explicit component"); 8163 } 8164 if (thumbnail.getWidth() != mThumbnailWidth 8165 || thumbnail.getHeight() != mThumbnailHeight) { 8166 throw new IllegalArgumentException("Bad thumbnail size: got " 8167 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8168 + mThumbnailWidth + "x" + mThumbnailHeight); 8169 } 8170 if (intent.getSelector() != null) { 8171 intent.setSelector(null); 8172 } 8173 if (intent.getSourceBounds() != null) { 8174 intent.setSourceBounds(null); 8175 } 8176 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8177 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8178 // The caller has added this as an auto-remove task... that makes no 8179 // sense, so turn off auto-remove. 8180 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8181 } 8182 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8183 // Must be a new task. 8184 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8185 } 8186 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8187 mLastAddedTaskActivity = null; 8188 } 8189 ActivityInfo ainfo = mLastAddedTaskActivity; 8190 if (ainfo == null) { 8191 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8192 comp, 0, UserHandle.getUserId(callingUid)); 8193 if (ainfo.applicationInfo.uid != callingUid) { 8194 throw new SecurityException( 8195 "Can't add task for another application: target uid=" 8196 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8197 } 8198 } 8199 8200 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8201 intent, description); 8202 8203 int trimIdx = trimRecentsForTask(task, false); 8204 if (trimIdx >= 0) { 8205 // If this would have caused a trim, then we'll abort because that 8206 // means it would be added at the end of the list but then just removed. 8207 return -1; 8208 } 8209 8210 final int N = mRecentTasks.size(); 8211 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8212 final TaskRecord tr = mRecentTasks.remove(N - 1); 8213 tr.removedFromRecents(mTaskPersister); 8214 } 8215 8216 task.inRecents = true; 8217 mRecentTasks.add(task); 8218 r.task.stack.addTask(task, false, false); 8219 8220 task.setLastThumbnail(thumbnail); 8221 task.freeLastThumbnail(); 8222 8223 return task.taskId; 8224 } 8225 } finally { 8226 Binder.restoreCallingIdentity(callingIdent); 8227 } 8228 } 8229 8230 @Override 8231 public Point getAppTaskThumbnailSize() { 8232 synchronized (this) { 8233 return new Point(mThumbnailWidth, mThumbnailHeight); 8234 } 8235 } 8236 8237 @Override 8238 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8239 synchronized (this) { 8240 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8241 if (r != null) { 8242 r.setTaskDescription(td); 8243 r.task.updateTaskDescription(); 8244 } 8245 } 8246 } 8247 8248 @Override 8249 public Bitmap getTaskDescriptionIcon(String filename) { 8250 if (!FileUtils.isValidExtFilename(filename) 8251 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8252 throw new IllegalArgumentException("Bad filename: " + filename); 8253 } 8254 return mTaskPersister.getTaskDescriptionIcon(filename); 8255 } 8256 8257 @Override 8258 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8259 throws RemoteException { 8260 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8261 opts.getCustomInPlaceResId() == 0) { 8262 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8263 "with valid animation"); 8264 } 8265 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8266 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8267 opts.getCustomInPlaceResId()); 8268 mWindowManager.executeAppTransition(); 8269 } 8270 8271 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8272 mRecentTasks.remove(tr); 8273 tr.removedFromRecents(mTaskPersister); 8274 ComponentName component = tr.getBaseIntent().getComponent(); 8275 if (component == null) { 8276 Slog.w(TAG, "No component for base intent of task: " + tr); 8277 return; 8278 } 8279 8280 if (!killProcess) { 8281 return; 8282 } 8283 8284 // Determine if the process(es) for this task should be killed. 8285 final String pkg = component.getPackageName(); 8286 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8287 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8288 for (int i = 0; i < pmap.size(); i++) { 8289 8290 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8291 for (int j = 0; j < uids.size(); j++) { 8292 ProcessRecord proc = uids.valueAt(j); 8293 if (proc.userId != tr.userId) { 8294 // Don't kill process for a different user. 8295 continue; 8296 } 8297 if (proc == mHomeProcess) { 8298 // Don't kill the home process along with tasks from the same package. 8299 continue; 8300 } 8301 if (!proc.pkgList.containsKey(pkg)) { 8302 // Don't kill process that is not associated with this task. 8303 continue; 8304 } 8305 8306 for (int k = 0; k < proc.activities.size(); k++) { 8307 TaskRecord otherTask = proc.activities.get(k).task; 8308 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8309 // Don't kill process(es) that has an activity in a different task that is 8310 // also in recents. 8311 return; 8312 } 8313 } 8314 8315 // Add process to kill list. 8316 procsToKill.add(proc); 8317 } 8318 } 8319 8320 // Find any running services associated with this app and stop if needed. 8321 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8322 8323 // Kill the running processes. 8324 for (int i = 0; i < procsToKill.size(); i++) { 8325 ProcessRecord pr = procsToKill.get(i); 8326 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8327 pr.kill("remove task", true); 8328 } else { 8329 pr.waitingToKill = "remove task"; 8330 } 8331 } 8332 } 8333 8334 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8335 // Remove all tasks with activities in the specified package from the list of recent tasks 8336 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8337 TaskRecord tr = mRecentTasks.get(i); 8338 if (tr.userId != userId) continue; 8339 8340 ComponentName cn = tr.intent.getComponent(); 8341 if (cn != null && cn.getPackageName().equals(packageName)) { 8342 // If the package name matches, remove the task. 8343 removeTaskByIdLocked(tr.taskId, true); 8344 } 8345 } 8346 } 8347 8348 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8349 final IPackageManager pm = AppGlobals.getPackageManager(); 8350 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8351 8352 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8353 TaskRecord tr = mRecentTasks.get(i); 8354 if (tr.userId != userId) continue; 8355 8356 ComponentName cn = tr.intent.getComponent(); 8357 if (cn != null && cn.getPackageName().equals(packageName)) { 8358 // Skip if component still exists in the package. 8359 if (componentsKnownToExist.contains(cn)) continue; 8360 8361 try { 8362 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8363 if (info != null) { 8364 componentsKnownToExist.add(cn); 8365 } else { 8366 removeTaskByIdLocked(tr.taskId, false); 8367 } 8368 } catch (RemoteException e) { 8369 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8370 } 8371 } 8372 } 8373 } 8374 8375 /** 8376 * Removes the task with the specified task id. 8377 * 8378 * @param taskId Identifier of the task to be removed. 8379 * @param killProcess Kill any process associated with the task if possible. 8380 * @return Returns true if the given task was found and removed. 8381 */ 8382 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8383 TaskRecord tr = taskForIdLocked(taskId); 8384 if (tr != null) { 8385 tr.removeTaskActivitiesLocked(); 8386 cleanUpRemovedTaskLocked(tr, killProcess); 8387 if (tr.isPersistable) { 8388 notifyTaskPersisterLocked(null, true); 8389 } 8390 return true; 8391 } 8392 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8393 return false; 8394 } 8395 8396 @Override 8397 public boolean removeTask(int taskId) { 8398 synchronized (this) { 8399 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8400 "removeTask()"); 8401 long ident = Binder.clearCallingIdentity(); 8402 try { 8403 return removeTaskByIdLocked(taskId, true); 8404 } finally { 8405 Binder.restoreCallingIdentity(ident); 8406 } 8407 } 8408 } 8409 8410 /** 8411 * TODO: Add mController hook 8412 */ 8413 @Override 8414 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8415 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8416 "moveTaskToFront()"); 8417 8418 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8419 synchronized(this) { 8420 moveTaskToFrontLocked(taskId, flags, options); 8421 } 8422 } 8423 8424 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8425 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8426 Binder.getCallingUid(), -1, -1, "Task to front")) { 8427 ActivityOptions.abort(options); 8428 return; 8429 } 8430 final long origId = Binder.clearCallingIdentity(); 8431 try { 8432 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8433 if (task == null) { 8434 Slog.d(TAG, "Could not find task for id: "+ taskId); 8435 return; 8436 } 8437 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8438 mStackSupervisor.showLockTaskToast(); 8439 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8440 return; 8441 } 8442 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8443 if (prev != null && prev.isRecentsActivity()) { 8444 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8445 } 8446 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8447 } finally { 8448 Binder.restoreCallingIdentity(origId); 8449 } 8450 ActivityOptions.abort(options); 8451 } 8452 8453 @Override 8454 public void moveTaskToBack(int taskId) { 8455 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8456 "moveTaskToBack()"); 8457 8458 synchronized(this) { 8459 TaskRecord tr = taskForIdLocked(taskId); 8460 if (tr != null) { 8461 if (tr == mStackSupervisor.mLockTaskModeTask) { 8462 mStackSupervisor.showLockTaskToast(); 8463 return; 8464 } 8465 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8466 ActivityStack stack = tr.stack; 8467 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8468 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8469 Binder.getCallingUid(), -1, -1, "Task to back")) { 8470 return; 8471 } 8472 } 8473 final long origId = Binder.clearCallingIdentity(); 8474 try { 8475 stack.moveTaskToBackLocked(taskId, null); 8476 } finally { 8477 Binder.restoreCallingIdentity(origId); 8478 } 8479 } 8480 } 8481 } 8482 8483 /** 8484 * Moves an activity, and all of the other activities within the same task, to the bottom 8485 * of the history stack. The activity's order within the task is unchanged. 8486 * 8487 * @param token A reference to the activity we wish to move 8488 * @param nonRoot If false then this only works if the activity is the root 8489 * of a task; if true it will work for any activity in a task. 8490 * @return Returns true if the move completed, false if not. 8491 */ 8492 @Override 8493 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8494 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8495 synchronized(this) { 8496 final long origId = Binder.clearCallingIdentity(); 8497 try { 8498 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8499 if (taskId >= 0) { 8500 if ((mStackSupervisor.mLockTaskModeTask != null) 8501 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8502 mStackSupervisor.showLockTaskToast(); 8503 return false; 8504 } 8505 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8506 } 8507 } finally { 8508 Binder.restoreCallingIdentity(origId); 8509 } 8510 } 8511 return false; 8512 } 8513 8514 @Override 8515 public void moveTaskBackwards(int task) { 8516 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8517 "moveTaskBackwards()"); 8518 8519 synchronized(this) { 8520 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8521 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8522 return; 8523 } 8524 final long origId = Binder.clearCallingIdentity(); 8525 moveTaskBackwardsLocked(task); 8526 Binder.restoreCallingIdentity(origId); 8527 } 8528 } 8529 8530 private final void moveTaskBackwardsLocked(int task) { 8531 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8532 } 8533 8534 @Override 8535 public IBinder getHomeActivityToken() throws RemoteException { 8536 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8537 "getHomeActivityToken()"); 8538 synchronized (this) { 8539 return mStackSupervisor.getHomeActivityToken(); 8540 } 8541 } 8542 8543 @Override 8544 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8545 IActivityContainerCallback callback) throws RemoteException { 8546 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8547 "createActivityContainer()"); 8548 synchronized (this) { 8549 if (parentActivityToken == null) { 8550 throw new IllegalArgumentException("parent token must not be null"); 8551 } 8552 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8553 if (r == null) { 8554 return null; 8555 } 8556 if (callback == null) { 8557 throw new IllegalArgumentException("callback must not be null"); 8558 } 8559 return mStackSupervisor.createActivityContainer(r, callback); 8560 } 8561 } 8562 8563 @Override 8564 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8565 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8566 "deleteActivityContainer()"); 8567 synchronized (this) { 8568 mStackSupervisor.deleteActivityContainer(container); 8569 } 8570 } 8571 8572 @Override 8573 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8574 throws RemoteException { 8575 synchronized (this) { 8576 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8577 if (stack != null) { 8578 return stack.mActivityContainer; 8579 } 8580 return null; 8581 } 8582 } 8583 8584 @Override 8585 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8586 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8587 "moveTaskToStack()"); 8588 if (stackId == HOME_STACK_ID) { 8589 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8590 new RuntimeException("here").fillInStackTrace()); 8591 } 8592 synchronized (this) { 8593 long ident = Binder.clearCallingIdentity(); 8594 try { 8595 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8596 + stackId + " toTop=" + toTop); 8597 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8598 } finally { 8599 Binder.restoreCallingIdentity(ident); 8600 } 8601 } 8602 } 8603 8604 @Override 8605 public void resizeStack(int stackBoxId, Rect bounds) { 8606 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8607 "resizeStackBox()"); 8608 long ident = Binder.clearCallingIdentity(); 8609 try { 8610 mWindowManager.resizeStack(stackBoxId, bounds); 8611 } finally { 8612 Binder.restoreCallingIdentity(ident); 8613 } 8614 } 8615 8616 @Override 8617 public List<StackInfo> getAllStackInfos() { 8618 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8619 "getAllStackInfos()"); 8620 long ident = Binder.clearCallingIdentity(); 8621 try { 8622 synchronized (this) { 8623 return mStackSupervisor.getAllStackInfosLocked(); 8624 } 8625 } finally { 8626 Binder.restoreCallingIdentity(ident); 8627 } 8628 } 8629 8630 @Override 8631 public StackInfo getStackInfo(int stackId) { 8632 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8633 "getStackInfo()"); 8634 long ident = Binder.clearCallingIdentity(); 8635 try { 8636 synchronized (this) { 8637 return mStackSupervisor.getStackInfoLocked(stackId); 8638 } 8639 } finally { 8640 Binder.restoreCallingIdentity(ident); 8641 } 8642 } 8643 8644 @Override 8645 public boolean isInHomeStack(int taskId) { 8646 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8647 "getStackInfo()"); 8648 long ident = Binder.clearCallingIdentity(); 8649 try { 8650 synchronized (this) { 8651 TaskRecord tr = taskForIdLocked(taskId); 8652 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8653 } 8654 } finally { 8655 Binder.restoreCallingIdentity(ident); 8656 } 8657 } 8658 8659 @Override 8660 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8661 synchronized(this) { 8662 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8663 } 8664 } 8665 8666 private boolean isLockTaskAuthorized(String pkg) { 8667 final DevicePolicyManager dpm = (DevicePolicyManager) 8668 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8669 try { 8670 int uid = mContext.getPackageManager().getPackageUid(pkg, 8671 Binder.getCallingUserHandle().getIdentifier()); 8672 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8673 } catch (NameNotFoundException e) { 8674 return false; 8675 } 8676 } 8677 8678 void startLockTaskMode(TaskRecord task) { 8679 final String pkg; 8680 synchronized (this) { 8681 pkg = task.intent.getComponent().getPackageName(); 8682 } 8683 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8684 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8685 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8686 StatusBarManagerInternal.class); 8687 if (statusBarManager != null) { 8688 statusBarManager.showScreenPinningRequest(); 8689 } 8690 return; 8691 } 8692 long ident = Binder.clearCallingIdentity(); 8693 try { 8694 synchronized (this) { 8695 // Since we lost lock on task, make sure it is still there. 8696 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8697 if (task != null) { 8698 if (!isSystemInitiated 8699 && ((mStackSupervisor.getFocusedStack() == null) 8700 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8701 throw new IllegalArgumentException("Invalid task, not in foreground"); 8702 } 8703 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8704 } 8705 } 8706 } finally { 8707 Binder.restoreCallingIdentity(ident); 8708 } 8709 } 8710 8711 @Override 8712 public void startLockTaskMode(int taskId) { 8713 final TaskRecord task; 8714 long ident = Binder.clearCallingIdentity(); 8715 try { 8716 synchronized (this) { 8717 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8718 } 8719 } finally { 8720 Binder.restoreCallingIdentity(ident); 8721 } 8722 if (task != null) { 8723 startLockTaskMode(task); 8724 } 8725 } 8726 8727 @Override 8728 public void startLockTaskMode(IBinder token) { 8729 final TaskRecord task; 8730 long ident = Binder.clearCallingIdentity(); 8731 try { 8732 synchronized (this) { 8733 final ActivityRecord r = ActivityRecord.forToken(token); 8734 if (r == null) { 8735 return; 8736 } 8737 task = r.task; 8738 } 8739 } finally { 8740 Binder.restoreCallingIdentity(ident); 8741 } 8742 if (task != null) { 8743 startLockTaskMode(task); 8744 } 8745 } 8746 8747 @Override 8748 public void startLockTaskModeOnCurrent() throws RemoteException { 8749 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8750 "startLockTaskModeOnCurrent"); 8751 long ident = Binder.clearCallingIdentity(); 8752 try { 8753 ActivityRecord r = null; 8754 synchronized (this) { 8755 r = mStackSupervisor.topRunningActivityLocked(); 8756 } 8757 startLockTaskMode(r.task); 8758 } finally { 8759 Binder.restoreCallingIdentity(ident); 8760 } 8761 } 8762 8763 @Override 8764 public void stopLockTaskMode() { 8765 // Verify that the user matches the package of the intent for the TaskRecord 8766 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8767 // and stopLockTaskMode. 8768 final int callingUid = Binder.getCallingUid(); 8769 if (callingUid != Process.SYSTEM_UID) { 8770 try { 8771 String pkg = 8772 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8773 int uid = mContext.getPackageManager().getPackageUid(pkg, 8774 Binder.getCallingUserHandle().getIdentifier()); 8775 if (uid != callingUid) { 8776 throw new SecurityException("Invalid uid, expected " + uid); 8777 } 8778 } catch (NameNotFoundException e) { 8779 Log.d(TAG, "stopLockTaskMode " + e); 8780 return; 8781 } 8782 } 8783 long ident = Binder.clearCallingIdentity(); 8784 try { 8785 Log.d(TAG, "stopLockTaskMode"); 8786 // Stop lock task 8787 synchronized (this) { 8788 mStackSupervisor.setLockTaskModeLocked(null, false); 8789 } 8790 } finally { 8791 Binder.restoreCallingIdentity(ident); 8792 } 8793 } 8794 8795 @Override 8796 public void stopLockTaskModeOnCurrent() throws RemoteException { 8797 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8798 "stopLockTaskModeOnCurrent"); 8799 long ident = Binder.clearCallingIdentity(); 8800 try { 8801 stopLockTaskMode(); 8802 } finally { 8803 Binder.restoreCallingIdentity(ident); 8804 } 8805 } 8806 8807 @Override 8808 public boolean isInLockTaskMode() { 8809 synchronized (this) { 8810 return mStackSupervisor.isInLockTaskMode(); 8811 } 8812 } 8813 8814 // ========================================================= 8815 // CONTENT PROVIDERS 8816 // ========================================================= 8817 8818 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8819 List<ProviderInfo> providers = null; 8820 try { 8821 providers = AppGlobals.getPackageManager(). 8822 queryContentProviders(app.processName, app.uid, 8823 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8824 } catch (RemoteException ex) { 8825 } 8826 if (DEBUG_MU) 8827 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8828 int userId = app.userId; 8829 if (providers != null) { 8830 int N = providers.size(); 8831 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8832 for (int i=0; i<N; i++) { 8833 ProviderInfo cpi = 8834 (ProviderInfo)providers.get(i); 8835 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8836 cpi.name, cpi.flags); 8837 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8838 // This is a singleton provider, but a user besides the 8839 // default user is asking to initialize a process it runs 8840 // in... well, no, it doesn't actually run in this process, 8841 // it runs in the process of the default user. Get rid of it. 8842 providers.remove(i); 8843 N--; 8844 i--; 8845 continue; 8846 } 8847 8848 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8849 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8850 if (cpr == null) { 8851 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8852 mProviderMap.putProviderByClass(comp, cpr); 8853 } 8854 if (DEBUG_MU) 8855 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8856 app.pubProviders.put(cpi.name, cpr); 8857 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8858 // Don't add this if it is a platform component that is marked 8859 // to run in multiple processes, because this is actually 8860 // part of the framework so doesn't make sense to track as a 8861 // separate apk in the process. 8862 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8863 mProcessStats); 8864 } 8865 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8866 } 8867 } 8868 return providers; 8869 } 8870 8871 /** 8872 * Check if {@link ProcessRecord} has a possible chance at accessing the 8873 * given {@link ProviderInfo}. Final permission checking is always done 8874 * in {@link ContentProvider}. 8875 */ 8876 private final String checkContentProviderPermissionLocked( 8877 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8878 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8879 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8880 boolean checkedGrants = false; 8881 if (checkUser) { 8882 // Looking for cross-user grants before enforcing the typical cross-users permissions 8883 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8884 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8885 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8886 return null; 8887 } 8888 checkedGrants = true; 8889 } 8890 userId = handleIncomingUser(callingPid, callingUid, userId, 8891 false, ALLOW_NON_FULL, 8892 "checkContentProviderPermissionLocked " + cpi.authority, null); 8893 if (userId != tmpTargetUserId) { 8894 // When we actually went to determine the final targer user ID, this ended 8895 // up different than our initial check for the authority. This is because 8896 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8897 // SELF. So we need to re-check the grants again. 8898 checkedGrants = false; 8899 } 8900 } 8901 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8902 cpi.applicationInfo.uid, cpi.exported) 8903 == PackageManager.PERMISSION_GRANTED) { 8904 return null; 8905 } 8906 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8907 cpi.applicationInfo.uid, cpi.exported) 8908 == PackageManager.PERMISSION_GRANTED) { 8909 return null; 8910 } 8911 8912 PathPermission[] pps = cpi.pathPermissions; 8913 if (pps != null) { 8914 int i = pps.length; 8915 while (i > 0) { 8916 i--; 8917 PathPermission pp = pps[i]; 8918 String pprperm = pp.getReadPermission(); 8919 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8920 cpi.applicationInfo.uid, cpi.exported) 8921 == PackageManager.PERMISSION_GRANTED) { 8922 return null; 8923 } 8924 String ppwperm = pp.getWritePermission(); 8925 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8926 cpi.applicationInfo.uid, cpi.exported) 8927 == PackageManager.PERMISSION_GRANTED) { 8928 return null; 8929 } 8930 } 8931 } 8932 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8933 return null; 8934 } 8935 8936 String msg; 8937 if (!cpi.exported) { 8938 msg = "Permission Denial: opening provider " + cpi.name 8939 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8940 + ", uid=" + callingUid + ") that is not exported from uid " 8941 + cpi.applicationInfo.uid; 8942 } else { 8943 msg = "Permission Denial: opening provider " + cpi.name 8944 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8945 + ", uid=" + callingUid + ") requires " 8946 + cpi.readPermission + " or " + cpi.writePermission; 8947 } 8948 Slog.w(TAG, msg); 8949 return msg; 8950 } 8951 8952 /** 8953 * Returns if the ContentProvider has granted a uri to callingUid 8954 */ 8955 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8956 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8957 if (perms != null) { 8958 for (int i=perms.size()-1; i>=0; i--) { 8959 GrantUri grantUri = perms.keyAt(i); 8960 if (grantUri.sourceUserId == userId || !checkUser) { 8961 if (matchesProvider(grantUri.uri, cpi)) { 8962 return true; 8963 } 8964 } 8965 } 8966 } 8967 return false; 8968 } 8969 8970 /** 8971 * Returns true if the uri authority is one of the authorities specified in the provider. 8972 */ 8973 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8974 String uriAuth = uri.getAuthority(); 8975 String cpiAuth = cpi.authority; 8976 if (cpiAuth.indexOf(';') == -1) { 8977 return cpiAuth.equals(uriAuth); 8978 } 8979 String[] cpiAuths = cpiAuth.split(";"); 8980 int length = cpiAuths.length; 8981 for (int i = 0; i < length; i++) { 8982 if (cpiAuths[i].equals(uriAuth)) return true; 8983 } 8984 return false; 8985 } 8986 8987 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8988 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8989 if (r != null) { 8990 for (int i=0; i<r.conProviders.size(); i++) { 8991 ContentProviderConnection conn = r.conProviders.get(i); 8992 if (conn.provider == cpr) { 8993 if (DEBUG_PROVIDER) Slog.v(TAG, 8994 "Adding provider requested by " 8995 + r.processName + " from process " 8996 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8997 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8998 if (stable) { 8999 conn.stableCount++; 9000 conn.numStableIncs++; 9001 } else { 9002 conn.unstableCount++; 9003 conn.numUnstableIncs++; 9004 } 9005 return conn; 9006 } 9007 } 9008 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9009 if (stable) { 9010 conn.stableCount = 1; 9011 conn.numStableIncs = 1; 9012 } else { 9013 conn.unstableCount = 1; 9014 conn.numUnstableIncs = 1; 9015 } 9016 cpr.connections.add(conn); 9017 r.conProviders.add(conn); 9018 return conn; 9019 } 9020 cpr.addExternalProcessHandleLocked(externalProcessToken); 9021 return null; 9022 } 9023 9024 boolean decProviderCountLocked(ContentProviderConnection conn, 9025 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9026 if (conn != null) { 9027 cpr = conn.provider; 9028 if (DEBUG_PROVIDER) Slog.v(TAG, 9029 "Removing provider requested by " 9030 + conn.client.processName + " from process " 9031 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9032 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9033 if (stable) { 9034 conn.stableCount--; 9035 } else { 9036 conn.unstableCount--; 9037 } 9038 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9039 cpr.connections.remove(conn); 9040 conn.client.conProviders.remove(conn); 9041 return true; 9042 } 9043 return false; 9044 } 9045 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9046 return false; 9047 } 9048 9049 private void checkTime(long startTime, String where) { 9050 long now = SystemClock.elapsedRealtime(); 9051 if ((now-startTime) > 1000) { 9052 // If we are taking more than a second, log about it. 9053 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9054 } 9055 } 9056 9057 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9058 String name, IBinder token, boolean stable, int userId) { 9059 ContentProviderRecord cpr; 9060 ContentProviderConnection conn = null; 9061 ProviderInfo cpi = null; 9062 9063 synchronized(this) { 9064 long startTime = SystemClock.elapsedRealtime(); 9065 9066 ProcessRecord r = null; 9067 if (caller != null) { 9068 r = getRecordForAppLocked(caller); 9069 if (r == null) { 9070 throw new SecurityException( 9071 "Unable to find app for caller " + caller 9072 + " (pid=" + Binder.getCallingPid() 9073 + ") when getting content provider " + name); 9074 } 9075 } 9076 9077 boolean checkCrossUser = true; 9078 9079 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9080 9081 // First check if this content provider has been published... 9082 cpr = mProviderMap.getProviderByName(name, userId); 9083 // If that didn't work, check if it exists for user 0 and then 9084 // verify that it's a singleton provider before using it. 9085 if (cpr == null && userId != UserHandle.USER_OWNER) { 9086 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9087 if (cpr != null) { 9088 cpi = cpr.info; 9089 if (isSingleton(cpi.processName, cpi.applicationInfo, 9090 cpi.name, cpi.flags) 9091 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9092 userId = UserHandle.USER_OWNER; 9093 checkCrossUser = false; 9094 } else { 9095 cpr = null; 9096 cpi = null; 9097 } 9098 } 9099 } 9100 9101 boolean providerRunning = cpr != null; 9102 if (providerRunning) { 9103 cpi = cpr.info; 9104 String msg; 9105 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9106 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9107 != null) { 9108 throw new SecurityException(msg); 9109 } 9110 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9111 9112 if (r != null && cpr.canRunHere(r)) { 9113 // This provider has been published or is in the process 9114 // of being published... but it is also allowed to run 9115 // in the caller's process, so don't make a connection 9116 // and just let the caller instantiate its own instance. 9117 ContentProviderHolder holder = cpr.newHolder(null); 9118 // don't give caller the provider object, it needs 9119 // to make its own. 9120 holder.provider = null; 9121 return holder; 9122 } 9123 9124 final long origId = Binder.clearCallingIdentity(); 9125 9126 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9127 9128 // In this case the provider instance already exists, so we can 9129 // return it right away. 9130 conn = incProviderCountLocked(r, cpr, token, stable); 9131 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9132 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9133 // If this is a perceptible app accessing the provider, 9134 // make sure to count it as being accessed and thus 9135 // back up on the LRU list. This is good because 9136 // content providers are often expensive to start. 9137 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9138 updateLruProcessLocked(cpr.proc, false, null); 9139 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9140 } 9141 } 9142 9143 if (cpr.proc != null) { 9144 if (false) { 9145 if (cpr.name.flattenToShortString().equals( 9146 "com.android.providers.calendar/.CalendarProvider2")) { 9147 Slog.v(TAG, "****************** KILLING " 9148 + cpr.name.flattenToShortString()); 9149 Process.killProcess(cpr.proc.pid); 9150 } 9151 } 9152 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9153 boolean success = updateOomAdjLocked(cpr.proc); 9154 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9155 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9156 // NOTE: there is still a race here where a signal could be 9157 // pending on the process even though we managed to update its 9158 // adj level. Not sure what to do about this, but at least 9159 // the race is now smaller. 9160 if (!success) { 9161 // Uh oh... it looks like the provider's process 9162 // has been killed on us. We need to wait for a new 9163 // process to be started, and make sure its death 9164 // doesn't kill our process. 9165 Slog.i(TAG, 9166 "Existing provider " + cpr.name.flattenToShortString() 9167 + " is crashing; detaching " + r); 9168 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9169 checkTime(startTime, "getContentProviderImpl: before appDied"); 9170 appDiedLocked(cpr.proc); 9171 checkTime(startTime, "getContentProviderImpl: after appDied"); 9172 if (!lastRef) { 9173 // This wasn't the last ref our process had on 9174 // the provider... we have now been killed, bail. 9175 return null; 9176 } 9177 providerRunning = false; 9178 conn = null; 9179 } 9180 } 9181 9182 Binder.restoreCallingIdentity(origId); 9183 } 9184 9185 boolean singleton; 9186 if (!providerRunning) { 9187 try { 9188 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9189 cpi = AppGlobals.getPackageManager(). 9190 resolveContentProvider(name, 9191 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9192 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9193 } catch (RemoteException ex) { 9194 } 9195 if (cpi == null) { 9196 return null; 9197 } 9198 // If the provider is a singleton AND 9199 // (it's a call within the same user || the provider is a 9200 // privileged app) 9201 // Then allow connecting to the singleton provider 9202 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9203 cpi.name, cpi.flags) 9204 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9205 if (singleton) { 9206 userId = UserHandle.USER_OWNER; 9207 } 9208 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9209 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9210 9211 String msg; 9212 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9213 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9214 != null) { 9215 throw new SecurityException(msg); 9216 } 9217 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9218 9219 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9220 && !cpi.processName.equals("system")) { 9221 // If this content provider does not run in the system 9222 // process, and the system is not yet ready to run other 9223 // processes, then fail fast instead of hanging. 9224 throw new IllegalArgumentException( 9225 "Attempt to launch content provider before system ready"); 9226 } 9227 9228 // Make sure that the user who owns this provider is started. If not, 9229 // we don't want to allow it to run. 9230 if (mStartedUsers.get(userId) == null) { 9231 Slog.w(TAG, "Unable to launch app " 9232 + cpi.applicationInfo.packageName + "/" 9233 + cpi.applicationInfo.uid + " for provider " 9234 + name + ": user " + userId + " is stopped"); 9235 return null; 9236 } 9237 9238 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9239 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9240 cpr = mProviderMap.getProviderByClass(comp, userId); 9241 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9242 final boolean firstClass = cpr == null; 9243 if (firstClass) { 9244 final long ident = Binder.clearCallingIdentity(); 9245 try { 9246 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9247 ApplicationInfo ai = 9248 AppGlobals.getPackageManager(). 9249 getApplicationInfo( 9250 cpi.applicationInfo.packageName, 9251 STOCK_PM_FLAGS, userId); 9252 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9253 if (ai == null) { 9254 Slog.w(TAG, "No package info for content provider " 9255 + cpi.name); 9256 return null; 9257 } 9258 ai = getAppInfoForUser(ai, userId); 9259 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9260 } catch (RemoteException ex) { 9261 // pm is in same process, this will never happen. 9262 } finally { 9263 Binder.restoreCallingIdentity(ident); 9264 } 9265 } 9266 9267 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9268 9269 if (r != null && cpr.canRunHere(r)) { 9270 // If this is a multiprocess provider, then just return its 9271 // info and allow the caller to instantiate it. Only do 9272 // this if the provider is the same user as the caller's 9273 // process, or can run as root (so can be in any process). 9274 return cpr.newHolder(null); 9275 } 9276 9277 if (DEBUG_PROVIDER) { 9278 RuntimeException e = new RuntimeException("here"); 9279 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9280 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9281 } 9282 9283 // This is single process, and our app is now connecting to it. 9284 // See if we are already in the process of launching this 9285 // provider. 9286 final int N = mLaunchingProviders.size(); 9287 int i; 9288 for (i=0; i<N; i++) { 9289 if (mLaunchingProviders.get(i) == cpr) { 9290 break; 9291 } 9292 } 9293 9294 // If the provider is not already being launched, then get it 9295 // started. 9296 if (i >= N) { 9297 final long origId = Binder.clearCallingIdentity(); 9298 9299 try { 9300 // Content provider is now in use, its package can't be stopped. 9301 try { 9302 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9303 AppGlobals.getPackageManager().setPackageStoppedState( 9304 cpr.appInfo.packageName, false, userId); 9305 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9306 } catch (RemoteException e) { 9307 } catch (IllegalArgumentException e) { 9308 Slog.w(TAG, "Failed trying to unstop package " 9309 + cpr.appInfo.packageName + ": " + e); 9310 } 9311 9312 // Use existing process if already started 9313 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9314 ProcessRecord proc = getProcessRecordLocked( 9315 cpi.processName, cpr.appInfo.uid, false); 9316 if (proc != null && proc.thread != null) { 9317 if (DEBUG_PROVIDER) { 9318 Slog.d(TAG, "Installing in existing process " + proc); 9319 } 9320 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9321 proc.pubProviders.put(cpi.name, cpr); 9322 try { 9323 proc.thread.scheduleInstallProvider(cpi); 9324 } catch (RemoteException e) { 9325 } 9326 } else { 9327 checkTime(startTime, "getContentProviderImpl: before start process"); 9328 proc = startProcessLocked(cpi.processName, 9329 cpr.appInfo, false, 0, "content provider", 9330 new ComponentName(cpi.applicationInfo.packageName, 9331 cpi.name), false, false, false); 9332 checkTime(startTime, "getContentProviderImpl: after start process"); 9333 if (proc == null) { 9334 Slog.w(TAG, "Unable to launch app " 9335 + cpi.applicationInfo.packageName + "/" 9336 + cpi.applicationInfo.uid + " for provider " 9337 + name + ": process is bad"); 9338 return null; 9339 } 9340 } 9341 cpr.launchingApp = proc; 9342 mLaunchingProviders.add(cpr); 9343 } finally { 9344 Binder.restoreCallingIdentity(origId); 9345 } 9346 } 9347 9348 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9349 9350 // Make sure the provider is published (the same provider class 9351 // may be published under multiple names). 9352 if (firstClass) { 9353 mProviderMap.putProviderByClass(comp, cpr); 9354 } 9355 9356 mProviderMap.putProviderByName(name, cpr); 9357 conn = incProviderCountLocked(r, cpr, token, stable); 9358 if (conn != null) { 9359 conn.waiting = true; 9360 } 9361 } 9362 checkTime(startTime, "getContentProviderImpl: done!"); 9363 } 9364 9365 // Wait for the provider to be published... 9366 synchronized (cpr) { 9367 while (cpr.provider == null) { 9368 if (cpr.launchingApp == null) { 9369 Slog.w(TAG, "Unable to launch app " 9370 + cpi.applicationInfo.packageName + "/" 9371 + cpi.applicationInfo.uid + " for provider " 9372 + name + ": launching app became null"); 9373 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9374 UserHandle.getUserId(cpi.applicationInfo.uid), 9375 cpi.applicationInfo.packageName, 9376 cpi.applicationInfo.uid, name); 9377 return null; 9378 } 9379 try { 9380 if (DEBUG_MU) { 9381 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9382 + cpr.launchingApp); 9383 } 9384 if (conn != null) { 9385 conn.waiting = true; 9386 } 9387 cpr.wait(); 9388 } catch (InterruptedException ex) { 9389 } finally { 9390 if (conn != null) { 9391 conn.waiting = false; 9392 } 9393 } 9394 } 9395 } 9396 return cpr != null ? cpr.newHolder(conn) : null; 9397 } 9398 9399 @Override 9400 public final ContentProviderHolder getContentProvider( 9401 IApplicationThread caller, String name, int userId, boolean stable) { 9402 enforceNotIsolatedCaller("getContentProvider"); 9403 if (caller == null) { 9404 String msg = "null IApplicationThread when getting content provider " 9405 + name; 9406 Slog.w(TAG, msg); 9407 throw new SecurityException(msg); 9408 } 9409 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9410 // with cross-user grant. 9411 return getContentProviderImpl(caller, name, null, stable, userId); 9412 } 9413 9414 public ContentProviderHolder getContentProviderExternal( 9415 String name, int userId, IBinder token) { 9416 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9417 "Do not have permission in call getContentProviderExternal()"); 9418 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9419 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9420 return getContentProviderExternalUnchecked(name, token, userId); 9421 } 9422 9423 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9424 IBinder token, int userId) { 9425 return getContentProviderImpl(null, name, token, true, userId); 9426 } 9427 9428 /** 9429 * Drop a content provider from a ProcessRecord's bookkeeping 9430 */ 9431 public void removeContentProvider(IBinder connection, boolean stable) { 9432 enforceNotIsolatedCaller("removeContentProvider"); 9433 long ident = Binder.clearCallingIdentity(); 9434 try { 9435 synchronized (this) { 9436 ContentProviderConnection conn; 9437 try { 9438 conn = (ContentProviderConnection)connection; 9439 } catch (ClassCastException e) { 9440 String msg ="removeContentProvider: " + connection 9441 + " not a ContentProviderConnection"; 9442 Slog.w(TAG, msg); 9443 throw new IllegalArgumentException(msg); 9444 } 9445 if (conn == null) { 9446 throw new NullPointerException("connection is null"); 9447 } 9448 if (decProviderCountLocked(conn, null, null, stable)) { 9449 updateOomAdjLocked(); 9450 } 9451 } 9452 } finally { 9453 Binder.restoreCallingIdentity(ident); 9454 } 9455 } 9456 9457 public void removeContentProviderExternal(String name, IBinder token) { 9458 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9459 "Do not have permission in call removeContentProviderExternal()"); 9460 int userId = UserHandle.getCallingUserId(); 9461 long ident = Binder.clearCallingIdentity(); 9462 try { 9463 removeContentProviderExternalUnchecked(name, token, userId); 9464 } finally { 9465 Binder.restoreCallingIdentity(ident); 9466 } 9467 } 9468 9469 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9470 synchronized (this) { 9471 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9472 if(cpr == null) { 9473 //remove from mProvidersByClass 9474 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9475 return; 9476 } 9477 9478 //update content provider record entry info 9479 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9480 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9481 if (localCpr.hasExternalProcessHandles()) { 9482 if (localCpr.removeExternalProcessHandleLocked(token)) { 9483 updateOomAdjLocked(); 9484 } else { 9485 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9486 + " with no external reference for token: " 9487 + token + "."); 9488 } 9489 } else { 9490 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9491 + " with no external references."); 9492 } 9493 } 9494 } 9495 9496 public final void publishContentProviders(IApplicationThread caller, 9497 List<ContentProviderHolder> providers) { 9498 if (providers == null) { 9499 return; 9500 } 9501 9502 enforceNotIsolatedCaller("publishContentProviders"); 9503 synchronized (this) { 9504 final ProcessRecord r = getRecordForAppLocked(caller); 9505 if (DEBUG_MU) 9506 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9507 if (r == null) { 9508 throw new SecurityException( 9509 "Unable to find app for caller " + caller 9510 + " (pid=" + Binder.getCallingPid() 9511 + ") when publishing content providers"); 9512 } 9513 9514 final long origId = Binder.clearCallingIdentity(); 9515 9516 final int N = providers.size(); 9517 for (int i=0; i<N; i++) { 9518 ContentProviderHolder src = providers.get(i); 9519 if (src == null || src.info == null || src.provider == null) { 9520 continue; 9521 } 9522 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9523 if (DEBUG_MU) 9524 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9525 if (dst != null) { 9526 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9527 mProviderMap.putProviderByClass(comp, dst); 9528 String names[] = dst.info.authority.split(";"); 9529 for (int j = 0; j < names.length; j++) { 9530 mProviderMap.putProviderByName(names[j], dst); 9531 } 9532 9533 int NL = mLaunchingProviders.size(); 9534 int j; 9535 for (j=0; j<NL; j++) { 9536 if (mLaunchingProviders.get(j) == dst) { 9537 mLaunchingProviders.remove(j); 9538 j--; 9539 NL--; 9540 } 9541 } 9542 synchronized (dst) { 9543 dst.provider = src.provider; 9544 dst.proc = r; 9545 dst.notifyAll(); 9546 } 9547 updateOomAdjLocked(r); 9548 } 9549 } 9550 9551 Binder.restoreCallingIdentity(origId); 9552 } 9553 } 9554 9555 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9556 ContentProviderConnection conn; 9557 try { 9558 conn = (ContentProviderConnection)connection; 9559 } catch (ClassCastException e) { 9560 String msg ="refContentProvider: " + connection 9561 + " not a ContentProviderConnection"; 9562 Slog.w(TAG, msg); 9563 throw new IllegalArgumentException(msg); 9564 } 9565 if (conn == null) { 9566 throw new NullPointerException("connection is null"); 9567 } 9568 9569 synchronized (this) { 9570 if (stable > 0) { 9571 conn.numStableIncs += stable; 9572 } 9573 stable = conn.stableCount + stable; 9574 if (stable < 0) { 9575 throw new IllegalStateException("stableCount < 0: " + stable); 9576 } 9577 9578 if (unstable > 0) { 9579 conn.numUnstableIncs += unstable; 9580 } 9581 unstable = conn.unstableCount + unstable; 9582 if (unstable < 0) { 9583 throw new IllegalStateException("unstableCount < 0: " + unstable); 9584 } 9585 9586 if ((stable+unstable) <= 0) { 9587 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9588 + stable + " unstable=" + unstable); 9589 } 9590 conn.stableCount = stable; 9591 conn.unstableCount = unstable; 9592 return !conn.dead; 9593 } 9594 } 9595 9596 public void unstableProviderDied(IBinder connection) { 9597 ContentProviderConnection conn; 9598 try { 9599 conn = (ContentProviderConnection)connection; 9600 } catch (ClassCastException e) { 9601 String msg ="refContentProvider: " + connection 9602 + " not a ContentProviderConnection"; 9603 Slog.w(TAG, msg); 9604 throw new IllegalArgumentException(msg); 9605 } 9606 if (conn == null) { 9607 throw new NullPointerException("connection is null"); 9608 } 9609 9610 // Safely retrieve the content provider associated with the connection. 9611 IContentProvider provider; 9612 synchronized (this) { 9613 provider = conn.provider.provider; 9614 } 9615 9616 if (provider == null) { 9617 // Um, yeah, we're way ahead of you. 9618 return; 9619 } 9620 9621 // Make sure the caller is being honest with us. 9622 if (provider.asBinder().pingBinder()) { 9623 // Er, no, still looks good to us. 9624 synchronized (this) { 9625 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9626 + " says " + conn + " died, but we don't agree"); 9627 return; 9628 } 9629 } 9630 9631 // Well look at that! It's dead! 9632 synchronized (this) { 9633 if (conn.provider.provider != provider) { 9634 // But something changed... good enough. 9635 return; 9636 } 9637 9638 ProcessRecord proc = conn.provider.proc; 9639 if (proc == null || proc.thread == null) { 9640 // Seems like the process is already cleaned up. 9641 return; 9642 } 9643 9644 // As far as we're concerned, this is just like receiving a 9645 // death notification... just a bit prematurely. 9646 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9647 + ") early provider death"); 9648 final long ident = Binder.clearCallingIdentity(); 9649 try { 9650 appDiedLocked(proc); 9651 } finally { 9652 Binder.restoreCallingIdentity(ident); 9653 } 9654 } 9655 } 9656 9657 @Override 9658 public void appNotRespondingViaProvider(IBinder connection) { 9659 enforceCallingPermission( 9660 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9661 9662 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9663 if (conn == null) { 9664 Slog.w(TAG, "ContentProviderConnection is null"); 9665 return; 9666 } 9667 9668 final ProcessRecord host = conn.provider.proc; 9669 if (host == null) { 9670 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9671 return; 9672 } 9673 9674 final long token = Binder.clearCallingIdentity(); 9675 try { 9676 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9677 } finally { 9678 Binder.restoreCallingIdentity(token); 9679 } 9680 } 9681 9682 public final void installSystemProviders() { 9683 List<ProviderInfo> providers; 9684 synchronized (this) { 9685 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9686 providers = generateApplicationProvidersLocked(app); 9687 if (providers != null) { 9688 for (int i=providers.size()-1; i>=0; i--) { 9689 ProviderInfo pi = (ProviderInfo)providers.get(i); 9690 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9691 Slog.w(TAG, "Not installing system proc provider " + pi.name 9692 + ": not system .apk"); 9693 providers.remove(i); 9694 } 9695 } 9696 } 9697 } 9698 if (providers != null) { 9699 mSystemThread.installSystemProviders(providers); 9700 } 9701 9702 mCoreSettingsObserver = new CoreSettingsObserver(this); 9703 9704 //mUsageStatsService.monitorPackages(); 9705 } 9706 9707 /** 9708 * Allows apps to retrieve the MIME type of a URI. 9709 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9710 * users, then it does not need permission to access the ContentProvider. 9711 * Either, it needs cross-user uri grants. 9712 * 9713 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9714 * 9715 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9716 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9717 */ 9718 public String getProviderMimeType(Uri uri, int userId) { 9719 enforceNotIsolatedCaller("getProviderMimeType"); 9720 final String name = uri.getAuthority(); 9721 int callingUid = Binder.getCallingUid(); 9722 int callingPid = Binder.getCallingPid(); 9723 long ident = 0; 9724 boolean clearedIdentity = false; 9725 userId = unsafeConvertIncomingUser(userId); 9726 if (canClearIdentity(callingPid, callingUid, userId)) { 9727 clearedIdentity = true; 9728 ident = Binder.clearCallingIdentity(); 9729 } 9730 ContentProviderHolder holder = null; 9731 try { 9732 holder = getContentProviderExternalUnchecked(name, null, userId); 9733 if (holder != null) { 9734 return holder.provider.getType(uri); 9735 } 9736 } catch (RemoteException e) { 9737 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9738 return null; 9739 } finally { 9740 // We need to clear the identity to call removeContentProviderExternalUnchecked 9741 if (!clearedIdentity) { 9742 ident = Binder.clearCallingIdentity(); 9743 } 9744 try { 9745 if (holder != null) { 9746 removeContentProviderExternalUnchecked(name, null, userId); 9747 } 9748 } finally { 9749 Binder.restoreCallingIdentity(ident); 9750 } 9751 } 9752 9753 return null; 9754 } 9755 9756 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9757 if (UserHandle.getUserId(callingUid) == userId) { 9758 return true; 9759 } 9760 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9761 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9762 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9763 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9764 return true; 9765 } 9766 return false; 9767 } 9768 9769 // ========================================================= 9770 // GLOBAL MANAGEMENT 9771 // ========================================================= 9772 9773 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9774 boolean isolated, int isolatedUid) { 9775 String proc = customProcess != null ? customProcess : info.processName; 9776 BatteryStatsImpl.Uid.Proc ps = null; 9777 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9778 int uid = info.uid; 9779 if (isolated) { 9780 if (isolatedUid == 0) { 9781 int userId = UserHandle.getUserId(uid); 9782 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9783 while (true) { 9784 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9785 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9786 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9787 } 9788 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9789 mNextIsolatedProcessUid++; 9790 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9791 // No process for this uid, use it. 9792 break; 9793 } 9794 stepsLeft--; 9795 if (stepsLeft <= 0) { 9796 return null; 9797 } 9798 } 9799 } else { 9800 // Special case for startIsolatedProcess (internal only), where 9801 // the uid of the isolated process is specified by the caller. 9802 uid = isolatedUid; 9803 } 9804 } 9805 return new ProcessRecord(stats, info, proc, uid); 9806 } 9807 9808 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9809 String abiOverride) { 9810 ProcessRecord app; 9811 if (!isolated) { 9812 app = getProcessRecordLocked(info.processName, info.uid, true); 9813 } else { 9814 app = null; 9815 } 9816 9817 if (app == null) { 9818 app = newProcessRecordLocked(info, null, isolated, 0); 9819 mProcessNames.put(info.processName, app.uid, app); 9820 if (isolated) { 9821 mIsolatedProcesses.put(app.uid, app); 9822 } 9823 updateLruProcessLocked(app, false, null); 9824 updateOomAdjLocked(); 9825 } 9826 9827 // This package really, really can not be stopped. 9828 try { 9829 AppGlobals.getPackageManager().setPackageStoppedState( 9830 info.packageName, false, UserHandle.getUserId(app.uid)); 9831 } catch (RemoteException e) { 9832 } catch (IllegalArgumentException e) { 9833 Slog.w(TAG, "Failed trying to unstop package " 9834 + info.packageName + ": " + e); 9835 } 9836 9837 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9838 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9839 app.persistent = true; 9840 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9841 } 9842 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9843 mPersistentStartingProcesses.add(app); 9844 startProcessLocked(app, "added application", app.processName, abiOverride, 9845 null /* entryPoint */, null /* entryPointArgs */); 9846 } 9847 9848 return app; 9849 } 9850 9851 public void unhandledBack() { 9852 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9853 "unhandledBack()"); 9854 9855 synchronized(this) { 9856 final long origId = Binder.clearCallingIdentity(); 9857 try { 9858 getFocusedStack().unhandledBackLocked(); 9859 } finally { 9860 Binder.restoreCallingIdentity(origId); 9861 } 9862 } 9863 } 9864 9865 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9866 enforceNotIsolatedCaller("openContentUri"); 9867 final int userId = UserHandle.getCallingUserId(); 9868 String name = uri.getAuthority(); 9869 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9870 ParcelFileDescriptor pfd = null; 9871 if (cph != null) { 9872 // We record the binder invoker's uid in thread-local storage before 9873 // going to the content provider to open the file. Later, in the code 9874 // that handles all permissions checks, we look for this uid and use 9875 // that rather than the Activity Manager's own uid. The effect is that 9876 // we do the check against the caller's permissions even though it looks 9877 // to the content provider like the Activity Manager itself is making 9878 // the request. 9879 sCallerIdentity.set(new Identity( 9880 Binder.getCallingPid(), Binder.getCallingUid())); 9881 try { 9882 pfd = cph.provider.openFile(null, uri, "r", null); 9883 } catch (FileNotFoundException e) { 9884 // do nothing; pfd will be returned null 9885 } finally { 9886 // Ensure that whatever happens, we clean up the identity state 9887 sCallerIdentity.remove(); 9888 } 9889 9890 // We've got the fd now, so we're done with the provider. 9891 removeContentProviderExternalUnchecked(name, null, userId); 9892 } else { 9893 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9894 } 9895 return pfd; 9896 } 9897 9898 // Actually is sleeping or shutting down or whatever else in the future 9899 // is an inactive state. 9900 public boolean isSleepingOrShuttingDown() { 9901 return isSleeping() || mShuttingDown; 9902 } 9903 9904 public boolean isSleeping() { 9905 return mSleeping; 9906 } 9907 9908 void goingToSleep() { 9909 synchronized(this) { 9910 mWentToSleep = true; 9911 goToSleepIfNeededLocked(); 9912 } 9913 } 9914 9915 void finishRunningVoiceLocked() { 9916 if (mRunningVoice) { 9917 mRunningVoice = false; 9918 goToSleepIfNeededLocked(); 9919 } 9920 } 9921 9922 void goToSleepIfNeededLocked() { 9923 if (mWentToSleep && !mRunningVoice) { 9924 if (!mSleeping) { 9925 mSleeping = true; 9926 mStackSupervisor.goingToSleepLocked(); 9927 9928 // Initialize the wake times of all processes. 9929 checkExcessivePowerUsageLocked(false); 9930 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9931 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9932 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9933 } 9934 } 9935 } 9936 9937 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9938 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9939 // Never persist the home stack. 9940 return; 9941 } 9942 mTaskPersister.wakeup(task, flush); 9943 } 9944 9945 @Override 9946 public boolean shutdown(int timeout) { 9947 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9948 != PackageManager.PERMISSION_GRANTED) { 9949 throw new SecurityException("Requires permission " 9950 + android.Manifest.permission.SHUTDOWN); 9951 } 9952 9953 boolean timedout = false; 9954 9955 synchronized(this) { 9956 mShuttingDown = true; 9957 updateEventDispatchingLocked(); 9958 timedout = mStackSupervisor.shutdownLocked(timeout); 9959 } 9960 9961 mAppOpsService.shutdown(); 9962 if (mUsageStatsService != null) { 9963 mUsageStatsService.prepareShutdown(); 9964 } 9965 mBatteryStatsService.shutdown(); 9966 synchronized (this) { 9967 mProcessStats.shutdownLocked(); 9968 } 9969 notifyTaskPersisterLocked(null, true); 9970 9971 return timedout; 9972 } 9973 9974 public final void activitySlept(IBinder token) { 9975 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9976 9977 final long origId = Binder.clearCallingIdentity(); 9978 9979 synchronized (this) { 9980 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9981 if (r != null) { 9982 mStackSupervisor.activitySleptLocked(r); 9983 } 9984 } 9985 9986 Binder.restoreCallingIdentity(origId); 9987 } 9988 9989 private String lockScreenShownToString() { 9990 switch (mLockScreenShown) { 9991 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 9992 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 9993 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 9994 default: return "Unknown=" + mLockScreenShown; 9995 } 9996 } 9997 9998 void logLockScreen(String msg) { 9999 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10000 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 10001 mWentToSleep + " mSleeping=" + mSleeping); 10002 } 10003 10004 void comeOutOfSleepIfNeededLocked() { 10005 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 10006 if (mSleeping) { 10007 mSleeping = false; 10008 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10009 } 10010 } 10011 } 10012 10013 void wakingUp() { 10014 synchronized(this) { 10015 mWentToSleep = false; 10016 comeOutOfSleepIfNeededLocked(); 10017 } 10018 } 10019 10020 void startRunningVoiceLocked() { 10021 if (!mRunningVoice) { 10022 mRunningVoice = true; 10023 comeOutOfSleepIfNeededLocked(); 10024 } 10025 } 10026 10027 private void updateEventDispatchingLocked() { 10028 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10029 } 10030 10031 public void setLockScreenShown(boolean shown) { 10032 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10033 != PackageManager.PERMISSION_GRANTED) { 10034 throw new SecurityException("Requires permission " 10035 + android.Manifest.permission.DEVICE_POWER); 10036 } 10037 10038 synchronized(this) { 10039 long ident = Binder.clearCallingIdentity(); 10040 try { 10041 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10042 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10043 comeOutOfSleepIfNeededLocked(); 10044 } finally { 10045 Binder.restoreCallingIdentity(ident); 10046 } 10047 } 10048 } 10049 10050 @Override 10051 public void stopAppSwitches() { 10052 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10053 != PackageManager.PERMISSION_GRANTED) { 10054 throw new SecurityException("Requires permission " 10055 + android.Manifest.permission.STOP_APP_SWITCHES); 10056 } 10057 10058 synchronized(this) { 10059 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10060 + APP_SWITCH_DELAY_TIME; 10061 mDidAppSwitch = false; 10062 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10063 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10064 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10065 } 10066 } 10067 10068 public void resumeAppSwitches() { 10069 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10070 != PackageManager.PERMISSION_GRANTED) { 10071 throw new SecurityException("Requires permission " 10072 + android.Manifest.permission.STOP_APP_SWITCHES); 10073 } 10074 10075 synchronized(this) { 10076 // Note that we don't execute any pending app switches... we will 10077 // let those wait until either the timeout, or the next start 10078 // activity request. 10079 mAppSwitchesAllowedTime = 0; 10080 } 10081 } 10082 10083 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10084 int callingPid, int callingUid, String name) { 10085 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10086 return true; 10087 } 10088 10089 int perm = checkComponentPermission( 10090 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10091 sourceUid, -1, true); 10092 if (perm == PackageManager.PERMISSION_GRANTED) { 10093 return true; 10094 } 10095 10096 // If the actual IPC caller is different from the logical source, then 10097 // also see if they are allowed to control app switches. 10098 if (callingUid != -1 && callingUid != sourceUid) { 10099 perm = checkComponentPermission( 10100 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10101 callingUid, -1, true); 10102 if (perm == PackageManager.PERMISSION_GRANTED) { 10103 return true; 10104 } 10105 } 10106 10107 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10108 return false; 10109 } 10110 10111 public void setDebugApp(String packageName, boolean waitForDebugger, 10112 boolean persistent) { 10113 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10114 "setDebugApp()"); 10115 10116 long ident = Binder.clearCallingIdentity(); 10117 try { 10118 // Note that this is not really thread safe if there are multiple 10119 // callers into it at the same time, but that's not a situation we 10120 // care about. 10121 if (persistent) { 10122 final ContentResolver resolver = mContext.getContentResolver(); 10123 Settings.Global.putString( 10124 resolver, Settings.Global.DEBUG_APP, 10125 packageName); 10126 Settings.Global.putInt( 10127 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10128 waitForDebugger ? 1 : 0); 10129 } 10130 10131 synchronized (this) { 10132 if (!persistent) { 10133 mOrigDebugApp = mDebugApp; 10134 mOrigWaitForDebugger = mWaitForDebugger; 10135 } 10136 mDebugApp = packageName; 10137 mWaitForDebugger = waitForDebugger; 10138 mDebugTransient = !persistent; 10139 if (packageName != null) { 10140 forceStopPackageLocked(packageName, -1, false, false, true, true, 10141 false, UserHandle.USER_ALL, "set debug app"); 10142 } 10143 } 10144 } finally { 10145 Binder.restoreCallingIdentity(ident); 10146 } 10147 } 10148 10149 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10150 synchronized (this) { 10151 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10152 if (!isDebuggable) { 10153 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10154 throw new SecurityException("Process not debuggable: " + app.packageName); 10155 } 10156 } 10157 10158 mOpenGlTraceApp = processName; 10159 } 10160 } 10161 10162 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10163 synchronized (this) { 10164 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10165 if (!isDebuggable) { 10166 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10167 throw new SecurityException("Process not debuggable: " + app.packageName); 10168 } 10169 } 10170 mProfileApp = processName; 10171 mProfileFile = profilerInfo.profileFile; 10172 if (mProfileFd != null) { 10173 try { 10174 mProfileFd.close(); 10175 } catch (IOException e) { 10176 } 10177 mProfileFd = null; 10178 } 10179 mProfileFd = profilerInfo.profileFd; 10180 mSamplingInterval = profilerInfo.samplingInterval; 10181 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10182 mProfileType = 0; 10183 } 10184 } 10185 10186 @Override 10187 public void setAlwaysFinish(boolean enabled) { 10188 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10189 "setAlwaysFinish()"); 10190 10191 Settings.Global.putInt( 10192 mContext.getContentResolver(), 10193 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10194 10195 synchronized (this) { 10196 mAlwaysFinishActivities = enabled; 10197 } 10198 } 10199 10200 @Override 10201 public void setActivityController(IActivityController controller) { 10202 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10203 "setActivityController()"); 10204 synchronized (this) { 10205 mController = controller; 10206 Watchdog.getInstance().setActivityController(controller); 10207 } 10208 } 10209 10210 @Override 10211 public void setUserIsMonkey(boolean userIsMonkey) { 10212 synchronized (this) { 10213 synchronized (mPidsSelfLocked) { 10214 final int callingPid = Binder.getCallingPid(); 10215 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10216 if (precessRecord == null) { 10217 throw new SecurityException("Unknown process: " + callingPid); 10218 } 10219 if (precessRecord.instrumentationUiAutomationConnection == null) { 10220 throw new SecurityException("Only an instrumentation process " 10221 + "with a UiAutomation can call setUserIsMonkey"); 10222 } 10223 } 10224 mUserIsMonkey = userIsMonkey; 10225 } 10226 } 10227 10228 @Override 10229 public boolean isUserAMonkey() { 10230 synchronized (this) { 10231 // If there is a controller also implies the user is a monkey. 10232 return (mUserIsMonkey || mController != null); 10233 } 10234 } 10235 10236 public void requestBugReport() { 10237 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10238 SystemProperties.set("ctl.start", "bugreport"); 10239 } 10240 10241 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10242 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10243 } 10244 10245 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10246 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10247 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10248 } 10249 return KEY_DISPATCHING_TIMEOUT; 10250 } 10251 10252 @Override 10253 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10254 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10255 != PackageManager.PERMISSION_GRANTED) { 10256 throw new SecurityException("Requires permission " 10257 + android.Manifest.permission.FILTER_EVENTS); 10258 } 10259 ProcessRecord proc; 10260 long timeout; 10261 synchronized (this) { 10262 synchronized (mPidsSelfLocked) { 10263 proc = mPidsSelfLocked.get(pid); 10264 } 10265 timeout = getInputDispatchingTimeoutLocked(proc); 10266 } 10267 10268 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10269 return -1; 10270 } 10271 10272 return timeout; 10273 } 10274 10275 /** 10276 * Handle input dispatching timeouts. 10277 * Returns whether input dispatching should be aborted or not. 10278 */ 10279 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10280 final ActivityRecord activity, final ActivityRecord parent, 10281 final boolean aboveSystem, String reason) { 10282 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10283 != PackageManager.PERMISSION_GRANTED) { 10284 throw new SecurityException("Requires permission " 10285 + android.Manifest.permission.FILTER_EVENTS); 10286 } 10287 10288 final String annotation; 10289 if (reason == null) { 10290 annotation = "Input dispatching timed out"; 10291 } else { 10292 annotation = "Input dispatching timed out (" + reason + ")"; 10293 } 10294 10295 if (proc != null) { 10296 synchronized (this) { 10297 if (proc.debugging) { 10298 return false; 10299 } 10300 10301 if (mDidDexOpt) { 10302 // Give more time since we were dexopting. 10303 mDidDexOpt = false; 10304 return false; 10305 } 10306 10307 if (proc.instrumentationClass != null) { 10308 Bundle info = new Bundle(); 10309 info.putString("shortMsg", "keyDispatchingTimedOut"); 10310 info.putString("longMsg", annotation); 10311 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10312 return true; 10313 } 10314 } 10315 mHandler.post(new Runnable() { 10316 @Override 10317 public void run() { 10318 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10319 } 10320 }); 10321 } 10322 10323 return true; 10324 } 10325 10326 public Bundle getAssistContextExtras(int requestType) { 10327 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10328 UserHandle.getCallingUserId()); 10329 if (pae == null) { 10330 return null; 10331 } 10332 synchronized (pae) { 10333 while (!pae.haveResult) { 10334 try { 10335 pae.wait(); 10336 } catch (InterruptedException e) { 10337 } 10338 } 10339 if (pae.result != null) { 10340 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10341 } 10342 } 10343 synchronized (this) { 10344 mPendingAssistExtras.remove(pae); 10345 mHandler.removeCallbacks(pae); 10346 } 10347 return pae.extras; 10348 } 10349 10350 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10351 int userHandle) { 10352 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10353 "getAssistContextExtras()"); 10354 PendingAssistExtras pae; 10355 Bundle extras = new Bundle(); 10356 synchronized (this) { 10357 ActivityRecord activity = getFocusedStack().mResumedActivity; 10358 if (activity == null) { 10359 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10360 return null; 10361 } 10362 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10363 if (activity.app == null || activity.app.thread == null) { 10364 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10365 return null; 10366 } 10367 if (activity.app.pid == Binder.getCallingPid()) { 10368 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10369 return null; 10370 } 10371 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10372 try { 10373 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10374 requestType); 10375 mPendingAssistExtras.add(pae); 10376 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10377 } catch (RemoteException e) { 10378 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10379 return null; 10380 } 10381 return pae; 10382 } 10383 } 10384 10385 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10386 PendingAssistExtras pae = (PendingAssistExtras)token; 10387 synchronized (pae) { 10388 pae.result = extras; 10389 pae.haveResult = true; 10390 pae.notifyAll(); 10391 if (pae.intent == null) { 10392 // Caller is just waiting for the result. 10393 return; 10394 } 10395 } 10396 10397 // We are now ready to launch the assist activity. 10398 synchronized (this) { 10399 boolean exists = mPendingAssistExtras.remove(pae); 10400 mHandler.removeCallbacks(pae); 10401 if (!exists) { 10402 // Timed out. 10403 return; 10404 } 10405 } 10406 pae.intent.replaceExtras(extras); 10407 if (pae.hint != null) { 10408 pae.intent.putExtra(pae.hint, true); 10409 } 10410 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10411 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10412 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10413 closeSystemDialogs("assist"); 10414 try { 10415 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10416 } catch (ActivityNotFoundException e) { 10417 Slog.w(TAG, "No activity to handle assist action.", e); 10418 } 10419 } 10420 10421 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10422 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10423 } 10424 10425 public void registerProcessObserver(IProcessObserver observer) { 10426 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10427 "registerProcessObserver()"); 10428 synchronized (this) { 10429 mProcessObservers.register(observer); 10430 } 10431 } 10432 10433 @Override 10434 public void unregisterProcessObserver(IProcessObserver observer) { 10435 synchronized (this) { 10436 mProcessObservers.unregister(observer); 10437 } 10438 } 10439 10440 @Override 10441 public boolean convertFromTranslucent(IBinder token) { 10442 final long origId = Binder.clearCallingIdentity(); 10443 try { 10444 synchronized (this) { 10445 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10446 if (r == null) { 10447 return false; 10448 } 10449 final boolean translucentChanged = r.changeWindowTranslucency(true); 10450 if (translucentChanged) { 10451 r.task.stack.releaseBackgroundResources(); 10452 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10453 } 10454 mWindowManager.setAppFullscreen(token, true); 10455 return translucentChanged; 10456 } 10457 } finally { 10458 Binder.restoreCallingIdentity(origId); 10459 } 10460 } 10461 10462 @Override 10463 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10464 final long origId = Binder.clearCallingIdentity(); 10465 try { 10466 synchronized (this) { 10467 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10468 if (r == null) { 10469 return false; 10470 } 10471 int index = r.task.mActivities.lastIndexOf(r); 10472 if (index > 0) { 10473 ActivityRecord under = r.task.mActivities.get(index - 1); 10474 under.returningOptions = options; 10475 } 10476 final boolean translucentChanged = r.changeWindowTranslucency(false); 10477 if (translucentChanged) { 10478 r.task.stack.convertToTranslucent(r); 10479 } 10480 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10481 mWindowManager.setAppFullscreen(token, false); 10482 return translucentChanged; 10483 } 10484 } finally { 10485 Binder.restoreCallingIdentity(origId); 10486 } 10487 } 10488 10489 @Override 10490 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10491 final long origId = Binder.clearCallingIdentity(); 10492 try { 10493 synchronized (this) { 10494 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10495 if (r != null) { 10496 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10497 } 10498 } 10499 return false; 10500 } finally { 10501 Binder.restoreCallingIdentity(origId); 10502 } 10503 } 10504 10505 @Override 10506 public boolean isBackgroundVisibleBehind(IBinder token) { 10507 final long origId = Binder.clearCallingIdentity(); 10508 try { 10509 synchronized (this) { 10510 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10511 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10512 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10513 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10514 return visible; 10515 } 10516 } finally { 10517 Binder.restoreCallingIdentity(origId); 10518 } 10519 } 10520 10521 @Override 10522 public ActivityOptions getActivityOptions(IBinder token) { 10523 final long origId = Binder.clearCallingIdentity(); 10524 try { 10525 synchronized (this) { 10526 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10527 if (r != null) { 10528 final ActivityOptions activityOptions = r.pendingOptions; 10529 r.pendingOptions = null; 10530 return activityOptions; 10531 } 10532 return null; 10533 } 10534 } finally { 10535 Binder.restoreCallingIdentity(origId); 10536 } 10537 } 10538 10539 @Override 10540 public void setImmersive(IBinder token, boolean immersive) { 10541 synchronized(this) { 10542 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10543 if (r == null) { 10544 throw new IllegalArgumentException(); 10545 } 10546 r.immersive = immersive; 10547 10548 // update associated state if we're frontmost 10549 if (r == mFocusedActivity) { 10550 if (DEBUG_IMMERSIVE) { 10551 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10552 } 10553 applyUpdateLockStateLocked(r); 10554 } 10555 } 10556 } 10557 10558 @Override 10559 public boolean isImmersive(IBinder token) { 10560 synchronized (this) { 10561 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10562 if (r == null) { 10563 throw new IllegalArgumentException(); 10564 } 10565 return r.immersive; 10566 } 10567 } 10568 10569 public boolean isTopActivityImmersive() { 10570 enforceNotIsolatedCaller("startActivity"); 10571 synchronized (this) { 10572 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10573 return (r != null) ? r.immersive : false; 10574 } 10575 } 10576 10577 @Override 10578 public boolean isTopOfTask(IBinder token) { 10579 synchronized (this) { 10580 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10581 if (r == null) { 10582 throw new IllegalArgumentException(); 10583 } 10584 return r.task.getTopActivity() == r; 10585 } 10586 } 10587 10588 public final void enterSafeMode() { 10589 synchronized(this) { 10590 // It only makes sense to do this before the system is ready 10591 // and started launching other packages. 10592 if (!mSystemReady) { 10593 try { 10594 AppGlobals.getPackageManager().enterSafeMode(); 10595 } catch (RemoteException e) { 10596 } 10597 } 10598 10599 mSafeMode = true; 10600 } 10601 } 10602 10603 public final void showSafeModeOverlay() { 10604 View v = LayoutInflater.from(mContext).inflate( 10605 com.android.internal.R.layout.safe_mode, null); 10606 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10607 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10608 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10609 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10610 lp.gravity = Gravity.BOTTOM | Gravity.START; 10611 lp.format = v.getBackground().getOpacity(); 10612 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10613 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10614 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10615 ((WindowManager)mContext.getSystemService( 10616 Context.WINDOW_SERVICE)).addView(v, lp); 10617 } 10618 10619 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10620 if (!(sender instanceof PendingIntentRecord)) { 10621 return; 10622 } 10623 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10624 synchronized (stats) { 10625 if (mBatteryStatsService.isOnBattery()) { 10626 mBatteryStatsService.enforceCallingPermission(); 10627 PendingIntentRecord rec = (PendingIntentRecord)sender; 10628 int MY_UID = Binder.getCallingUid(); 10629 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10630 BatteryStatsImpl.Uid.Pkg pkg = 10631 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10632 sourcePkg != null ? sourcePkg : rec.key.packageName); 10633 pkg.incWakeupsLocked(); 10634 } 10635 } 10636 } 10637 10638 public boolean killPids(int[] pids, String pReason, boolean secure) { 10639 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10640 throw new SecurityException("killPids only available to the system"); 10641 } 10642 String reason = (pReason == null) ? "Unknown" : pReason; 10643 // XXX Note: don't acquire main activity lock here, because the window 10644 // manager calls in with its locks held. 10645 10646 boolean killed = false; 10647 synchronized (mPidsSelfLocked) { 10648 int[] types = new int[pids.length]; 10649 int worstType = 0; 10650 for (int i=0; i<pids.length; i++) { 10651 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10652 if (proc != null) { 10653 int type = proc.setAdj; 10654 types[i] = type; 10655 if (type > worstType) { 10656 worstType = type; 10657 } 10658 } 10659 } 10660 10661 // If the worst oom_adj is somewhere in the cached proc LRU range, 10662 // then constrain it so we will kill all cached procs. 10663 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10664 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10665 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10666 } 10667 10668 // If this is not a secure call, don't let it kill processes that 10669 // are important. 10670 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10671 worstType = ProcessList.SERVICE_ADJ; 10672 } 10673 10674 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10675 for (int i=0; i<pids.length; i++) { 10676 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10677 if (proc == null) { 10678 continue; 10679 } 10680 int adj = proc.setAdj; 10681 if (adj >= worstType && !proc.killedByAm) { 10682 proc.kill(reason, true); 10683 killed = true; 10684 } 10685 } 10686 } 10687 return killed; 10688 } 10689 10690 @Override 10691 public void killUid(int uid, String reason) { 10692 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10693 throw new SecurityException("killUid only available to the system"); 10694 } 10695 synchronized (this) { 10696 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10697 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10698 reason != null ? reason : "kill uid"); 10699 } 10700 } 10701 10702 @Override 10703 public boolean killProcessesBelowForeground(String reason) { 10704 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10705 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10706 } 10707 10708 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10709 } 10710 10711 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10712 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10713 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10714 } 10715 10716 boolean killed = false; 10717 synchronized (mPidsSelfLocked) { 10718 final int size = mPidsSelfLocked.size(); 10719 for (int i = 0; i < size; i++) { 10720 final int pid = mPidsSelfLocked.keyAt(i); 10721 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10722 if (proc == null) continue; 10723 10724 final int adj = proc.setAdj; 10725 if (adj > belowAdj && !proc.killedByAm) { 10726 proc.kill(reason, true); 10727 killed = true; 10728 } 10729 } 10730 } 10731 return killed; 10732 } 10733 10734 @Override 10735 public void hang(final IBinder who, boolean allowRestart) { 10736 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10737 != PackageManager.PERMISSION_GRANTED) { 10738 throw new SecurityException("Requires permission " 10739 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10740 } 10741 10742 final IBinder.DeathRecipient death = new DeathRecipient() { 10743 @Override 10744 public void binderDied() { 10745 synchronized (this) { 10746 notifyAll(); 10747 } 10748 } 10749 }; 10750 10751 try { 10752 who.linkToDeath(death, 0); 10753 } catch (RemoteException e) { 10754 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10755 return; 10756 } 10757 10758 synchronized (this) { 10759 Watchdog.getInstance().setAllowRestart(allowRestart); 10760 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10761 synchronized (death) { 10762 while (who.isBinderAlive()) { 10763 try { 10764 death.wait(); 10765 } catch (InterruptedException e) { 10766 } 10767 } 10768 } 10769 Watchdog.getInstance().setAllowRestart(true); 10770 } 10771 } 10772 10773 @Override 10774 public void restart() { 10775 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10776 != PackageManager.PERMISSION_GRANTED) { 10777 throw new SecurityException("Requires permission " 10778 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10779 } 10780 10781 Log.i(TAG, "Sending shutdown broadcast..."); 10782 10783 BroadcastReceiver br = new BroadcastReceiver() { 10784 @Override public void onReceive(Context context, Intent intent) { 10785 // Now the broadcast is done, finish up the low-level shutdown. 10786 Log.i(TAG, "Shutting down activity manager..."); 10787 shutdown(10000); 10788 Log.i(TAG, "Shutdown complete, restarting!"); 10789 Process.killProcess(Process.myPid()); 10790 System.exit(10); 10791 } 10792 }; 10793 10794 // First send the high-level shut down broadcast. 10795 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10796 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10797 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10798 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10799 mContext.sendOrderedBroadcastAsUser(intent, 10800 UserHandle.ALL, null, br, mHandler, 0, null, null); 10801 */ 10802 br.onReceive(mContext, intent); 10803 } 10804 10805 private long getLowRamTimeSinceIdle(long now) { 10806 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10807 } 10808 10809 @Override 10810 public void performIdleMaintenance() { 10811 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10812 != PackageManager.PERMISSION_GRANTED) { 10813 throw new SecurityException("Requires permission " 10814 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10815 } 10816 10817 synchronized (this) { 10818 final long now = SystemClock.uptimeMillis(); 10819 final long timeSinceLastIdle = now - mLastIdleTime; 10820 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10821 mLastIdleTime = now; 10822 mLowRamTimeSinceLastIdle = 0; 10823 if (mLowRamStartTime != 0) { 10824 mLowRamStartTime = now; 10825 } 10826 10827 StringBuilder sb = new StringBuilder(128); 10828 sb.append("Idle maintenance over "); 10829 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10830 sb.append(" low RAM for "); 10831 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10832 Slog.i(TAG, sb.toString()); 10833 10834 // If at least 1/3 of our time since the last idle period has been spent 10835 // with RAM low, then we want to kill processes. 10836 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10837 10838 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10839 ProcessRecord proc = mLruProcesses.get(i); 10840 if (proc.notCachedSinceIdle) { 10841 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10842 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10843 if (doKilling && proc.initialIdlePss != 0 10844 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10845 proc.kill("idle maint (pss " + proc.lastPss 10846 + " from " + proc.initialIdlePss + ")", true); 10847 } 10848 } 10849 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10850 proc.notCachedSinceIdle = true; 10851 proc.initialIdlePss = 0; 10852 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10853 isSleeping(), now); 10854 } 10855 } 10856 10857 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10858 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10859 } 10860 } 10861 10862 private void retrieveSettings() { 10863 final ContentResolver resolver = mContext.getContentResolver(); 10864 String debugApp = Settings.Global.getString( 10865 resolver, Settings.Global.DEBUG_APP); 10866 boolean waitForDebugger = Settings.Global.getInt( 10867 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10868 boolean alwaysFinishActivities = Settings.Global.getInt( 10869 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10870 boolean forceRtl = Settings.Global.getInt( 10871 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10872 // Transfer any global setting for forcing RTL layout, into a System Property 10873 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10874 10875 Configuration configuration = new Configuration(); 10876 Settings.System.getConfiguration(resolver, configuration); 10877 if (forceRtl) { 10878 // This will take care of setting the correct layout direction flags 10879 configuration.setLayoutDirection(configuration.locale); 10880 } 10881 10882 synchronized (this) { 10883 mDebugApp = mOrigDebugApp = debugApp; 10884 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10885 mAlwaysFinishActivities = alwaysFinishActivities; 10886 // This happens before any activities are started, so we can 10887 // change mConfiguration in-place. 10888 updateConfigurationLocked(configuration, null, false, true); 10889 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10890 } 10891 } 10892 10893 /** Loads resources after the current configuration has been set. */ 10894 private void loadResourcesOnSystemReady() { 10895 final Resources res = mContext.getResources(); 10896 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10897 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10898 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10899 } 10900 10901 public boolean testIsSystemReady() { 10902 // no need to synchronize(this) just to read & return the value 10903 return mSystemReady; 10904 } 10905 10906 private static File getCalledPreBootReceiversFile() { 10907 File dataDir = Environment.getDataDirectory(); 10908 File systemDir = new File(dataDir, "system"); 10909 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10910 return fname; 10911 } 10912 10913 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10914 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10915 File file = getCalledPreBootReceiversFile(); 10916 FileInputStream fis = null; 10917 try { 10918 fis = new FileInputStream(file); 10919 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10920 int fvers = dis.readInt(); 10921 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10922 String vers = dis.readUTF(); 10923 String codename = dis.readUTF(); 10924 String build = dis.readUTF(); 10925 if (android.os.Build.VERSION.RELEASE.equals(vers) 10926 && android.os.Build.VERSION.CODENAME.equals(codename) 10927 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10928 int num = dis.readInt(); 10929 while (num > 0) { 10930 num--; 10931 String pkg = dis.readUTF(); 10932 String cls = dis.readUTF(); 10933 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10934 } 10935 } 10936 } 10937 } catch (FileNotFoundException e) { 10938 } catch (IOException e) { 10939 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10940 } finally { 10941 if (fis != null) { 10942 try { 10943 fis.close(); 10944 } catch (IOException e) { 10945 } 10946 } 10947 } 10948 return lastDoneReceivers; 10949 } 10950 10951 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10952 File file = getCalledPreBootReceiversFile(); 10953 FileOutputStream fos = null; 10954 DataOutputStream dos = null; 10955 try { 10956 fos = new FileOutputStream(file); 10957 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10958 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10959 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10960 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10961 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10962 dos.writeInt(list.size()); 10963 for (int i=0; i<list.size(); i++) { 10964 dos.writeUTF(list.get(i).getPackageName()); 10965 dos.writeUTF(list.get(i).getClassName()); 10966 } 10967 } catch (IOException e) { 10968 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10969 file.delete(); 10970 } finally { 10971 FileUtils.sync(fos); 10972 if (dos != null) { 10973 try { 10974 dos.close(); 10975 } catch (IOException e) { 10976 // TODO Auto-generated catch block 10977 e.printStackTrace(); 10978 } 10979 } 10980 } 10981 } 10982 10983 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10984 ArrayList<ComponentName> doneReceivers, int userId) { 10985 boolean waitingUpdate = false; 10986 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10987 List<ResolveInfo> ris = null; 10988 try { 10989 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10990 intent, null, 0, userId); 10991 } catch (RemoteException e) { 10992 } 10993 if (ris != null) { 10994 for (int i=ris.size()-1; i>=0; i--) { 10995 if ((ris.get(i).activityInfo.applicationInfo.flags 10996 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10997 ris.remove(i); 10998 } 10999 } 11000 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11001 11002 // For User 0, load the version number. When delivering to a new user, deliver 11003 // to all receivers. 11004 if (userId == UserHandle.USER_OWNER) { 11005 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11006 for (int i=0; i<ris.size(); i++) { 11007 ActivityInfo ai = ris.get(i).activityInfo; 11008 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11009 if (lastDoneReceivers.contains(comp)) { 11010 // We already did the pre boot receiver for this app with the current 11011 // platform version, so don't do it again... 11012 ris.remove(i); 11013 i--; 11014 // ...however, do keep it as one that has been done, so we don't 11015 // forget about it when rewriting the file of last done receivers. 11016 doneReceivers.add(comp); 11017 } 11018 } 11019 } 11020 11021 // If primary user, send broadcast to all available users, else just to userId 11022 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11023 : new int[] { userId }; 11024 for (int i = 0; i < ris.size(); i++) { 11025 ActivityInfo ai = ris.get(i).activityInfo; 11026 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11027 doneReceivers.add(comp); 11028 intent.setComponent(comp); 11029 for (int j=0; j<users.length; j++) { 11030 IIntentReceiver finisher = null; 11031 // On last receiver and user, set up a completion callback 11032 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11033 finisher = new IIntentReceiver.Stub() { 11034 public void performReceive(Intent intent, int resultCode, 11035 String data, Bundle extras, boolean ordered, 11036 boolean sticky, int sendingUser) { 11037 // The raw IIntentReceiver interface is called 11038 // with the AM lock held, so redispatch to 11039 // execute our code without the lock. 11040 mHandler.post(onFinishCallback); 11041 } 11042 }; 11043 } 11044 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11045 + " for user " + users[j]); 11046 broadcastIntentLocked(null, null, intent, null, finisher, 11047 0, null, null, null, AppOpsManager.OP_NONE, 11048 true, false, MY_PID, Process.SYSTEM_UID, 11049 users[j]); 11050 if (finisher != null) { 11051 waitingUpdate = true; 11052 } 11053 } 11054 } 11055 } 11056 11057 return waitingUpdate; 11058 } 11059 11060 public void systemReady(final Runnable goingCallback) { 11061 synchronized(this) { 11062 if (mSystemReady) { 11063 // If we're done calling all the receivers, run the next "boot phase" passed in 11064 // by the SystemServer 11065 if (goingCallback != null) { 11066 goingCallback.run(); 11067 } 11068 return; 11069 } 11070 11071 // Make sure we have the current profile info, since it is needed for 11072 // security checks. 11073 updateCurrentProfileIdsLocked(); 11074 11075 if (mRecentTasks == null) { 11076 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11077 if (!mRecentTasks.isEmpty()) { 11078 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11079 } 11080 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11081 mTaskPersister.startPersisting(); 11082 } 11083 11084 // Check to see if there are any update receivers to run. 11085 if (!mDidUpdate) { 11086 if (mWaitingUpdate) { 11087 return; 11088 } 11089 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11090 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11091 public void run() { 11092 synchronized (ActivityManagerService.this) { 11093 mDidUpdate = true; 11094 } 11095 writeLastDonePreBootReceivers(doneReceivers); 11096 showBootMessage(mContext.getText( 11097 R.string.android_upgrading_complete), 11098 false); 11099 systemReady(goingCallback); 11100 } 11101 }, doneReceivers, UserHandle.USER_OWNER); 11102 11103 if (mWaitingUpdate) { 11104 return; 11105 } 11106 mDidUpdate = true; 11107 } 11108 11109 mAppOpsService.systemReady(); 11110 mSystemReady = true; 11111 } 11112 11113 ArrayList<ProcessRecord> procsToKill = null; 11114 synchronized(mPidsSelfLocked) { 11115 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11116 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11117 if (!isAllowedWhileBooting(proc.info)){ 11118 if (procsToKill == null) { 11119 procsToKill = new ArrayList<ProcessRecord>(); 11120 } 11121 procsToKill.add(proc); 11122 } 11123 } 11124 } 11125 11126 synchronized(this) { 11127 if (procsToKill != null) { 11128 for (int i=procsToKill.size()-1; i>=0; i--) { 11129 ProcessRecord proc = procsToKill.get(i); 11130 Slog.i(TAG, "Removing system update proc: " + proc); 11131 removeProcessLocked(proc, true, false, "system update done"); 11132 } 11133 } 11134 11135 // Now that we have cleaned up any update processes, we 11136 // are ready to start launching real processes and know that 11137 // we won't trample on them any more. 11138 mProcessesReady = true; 11139 } 11140 11141 Slog.i(TAG, "System now ready"); 11142 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11143 SystemClock.uptimeMillis()); 11144 11145 synchronized(this) { 11146 // Make sure we have no pre-ready processes sitting around. 11147 11148 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11149 ResolveInfo ri = mContext.getPackageManager() 11150 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11151 STOCK_PM_FLAGS); 11152 CharSequence errorMsg = null; 11153 if (ri != null) { 11154 ActivityInfo ai = ri.activityInfo; 11155 ApplicationInfo app = ai.applicationInfo; 11156 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11157 mTopAction = Intent.ACTION_FACTORY_TEST; 11158 mTopData = null; 11159 mTopComponent = new ComponentName(app.packageName, 11160 ai.name); 11161 } else { 11162 errorMsg = mContext.getResources().getText( 11163 com.android.internal.R.string.factorytest_not_system); 11164 } 11165 } else { 11166 errorMsg = mContext.getResources().getText( 11167 com.android.internal.R.string.factorytest_no_action); 11168 } 11169 if (errorMsg != null) { 11170 mTopAction = null; 11171 mTopData = null; 11172 mTopComponent = null; 11173 Message msg = Message.obtain(); 11174 msg.what = SHOW_FACTORY_ERROR_MSG; 11175 msg.getData().putCharSequence("msg", errorMsg); 11176 mHandler.sendMessage(msg); 11177 } 11178 } 11179 } 11180 11181 retrieveSettings(); 11182 loadResourcesOnSystemReady(); 11183 11184 synchronized (this) { 11185 readGrantedUriPermissionsLocked(); 11186 } 11187 11188 if (goingCallback != null) goingCallback.run(); 11189 11190 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11191 Integer.toString(mCurrentUserId), mCurrentUserId); 11192 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11193 Integer.toString(mCurrentUserId), mCurrentUserId); 11194 mSystemServiceManager.startUser(mCurrentUserId); 11195 11196 synchronized (this) { 11197 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11198 try { 11199 List apps = AppGlobals.getPackageManager(). 11200 getPersistentApplications(STOCK_PM_FLAGS); 11201 if (apps != null) { 11202 int N = apps.size(); 11203 int i; 11204 for (i=0; i<N; i++) { 11205 ApplicationInfo info 11206 = (ApplicationInfo)apps.get(i); 11207 if (info != null && 11208 !info.packageName.equals("android")) { 11209 addAppLocked(info, false, null /* ABI override */); 11210 } 11211 } 11212 } 11213 } catch (RemoteException ex) { 11214 // pm is in same process, this will never happen. 11215 } 11216 } 11217 11218 // Start up initial activity. 11219 mBooting = true; 11220 startHomeActivityLocked(mCurrentUserId); 11221 11222 try { 11223 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11224 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11225 + " data partition or your device will be unstable."); 11226 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11227 } 11228 } catch (RemoteException e) { 11229 } 11230 11231 if (!Build.isFingerprintConsistent()) { 11232 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11233 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11234 } 11235 11236 long ident = Binder.clearCallingIdentity(); 11237 try { 11238 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11239 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11240 | Intent.FLAG_RECEIVER_FOREGROUND); 11241 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11242 broadcastIntentLocked(null, null, intent, 11243 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11244 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11245 intent = new Intent(Intent.ACTION_USER_STARTING); 11246 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11247 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11248 broadcastIntentLocked(null, null, intent, 11249 null, new IIntentReceiver.Stub() { 11250 @Override 11251 public void performReceive(Intent intent, int resultCode, String data, 11252 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11253 throws RemoteException { 11254 } 11255 }, 0, null, null, 11256 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11257 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11258 } catch (Throwable t) { 11259 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11260 } finally { 11261 Binder.restoreCallingIdentity(ident); 11262 } 11263 mStackSupervisor.resumeTopActivitiesLocked(); 11264 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11265 } 11266 } 11267 11268 private boolean makeAppCrashingLocked(ProcessRecord app, 11269 String shortMsg, String longMsg, String stackTrace) { 11270 app.crashing = true; 11271 app.crashingReport = generateProcessError(app, 11272 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11273 startAppProblemLocked(app); 11274 app.stopFreezingAllLocked(); 11275 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11276 } 11277 11278 private void makeAppNotRespondingLocked(ProcessRecord app, 11279 String activity, String shortMsg, String longMsg) { 11280 app.notResponding = true; 11281 app.notRespondingReport = generateProcessError(app, 11282 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11283 activity, shortMsg, longMsg, null); 11284 startAppProblemLocked(app); 11285 app.stopFreezingAllLocked(); 11286 } 11287 11288 /** 11289 * Generate a process error record, suitable for attachment to a ProcessRecord. 11290 * 11291 * @param app The ProcessRecord in which the error occurred. 11292 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11293 * ActivityManager.AppErrorStateInfo 11294 * @param activity The activity associated with the crash, if known. 11295 * @param shortMsg Short message describing the crash. 11296 * @param longMsg Long message describing the crash. 11297 * @param stackTrace Full crash stack trace, may be null. 11298 * 11299 * @return Returns a fully-formed AppErrorStateInfo record. 11300 */ 11301 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11302 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11303 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11304 11305 report.condition = condition; 11306 report.processName = app.processName; 11307 report.pid = app.pid; 11308 report.uid = app.info.uid; 11309 report.tag = activity; 11310 report.shortMsg = shortMsg; 11311 report.longMsg = longMsg; 11312 report.stackTrace = stackTrace; 11313 11314 return report; 11315 } 11316 11317 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11318 synchronized (this) { 11319 app.crashing = false; 11320 app.crashingReport = null; 11321 app.notResponding = false; 11322 app.notRespondingReport = null; 11323 if (app.anrDialog == fromDialog) { 11324 app.anrDialog = null; 11325 } 11326 if (app.waitDialog == fromDialog) { 11327 app.waitDialog = null; 11328 } 11329 if (app.pid > 0 && app.pid != MY_PID) { 11330 handleAppCrashLocked(app, null, null, null); 11331 app.kill("user request after error", true); 11332 } 11333 } 11334 } 11335 11336 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11337 String stackTrace) { 11338 long now = SystemClock.uptimeMillis(); 11339 11340 Long crashTime; 11341 if (!app.isolated) { 11342 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11343 } else { 11344 crashTime = null; 11345 } 11346 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11347 // This process loses! 11348 Slog.w(TAG, "Process " + app.info.processName 11349 + " has crashed too many times: killing!"); 11350 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11351 app.userId, app.info.processName, app.uid); 11352 mStackSupervisor.handleAppCrashLocked(app); 11353 if (!app.persistent) { 11354 // We don't want to start this process again until the user 11355 // explicitly does so... but for persistent process, we really 11356 // need to keep it running. If a persistent process is actually 11357 // repeatedly crashing, then badness for everyone. 11358 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11359 app.info.processName); 11360 if (!app.isolated) { 11361 // XXX We don't have a way to mark isolated processes 11362 // as bad, since they don't have a peristent identity. 11363 mBadProcesses.put(app.info.processName, app.uid, 11364 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11365 mProcessCrashTimes.remove(app.info.processName, app.uid); 11366 } 11367 app.bad = true; 11368 app.removed = true; 11369 // Don't let services in this process be restarted and potentially 11370 // annoy the user repeatedly. Unless it is persistent, since those 11371 // processes run critical code. 11372 removeProcessLocked(app, false, false, "crash"); 11373 mStackSupervisor.resumeTopActivitiesLocked(); 11374 return false; 11375 } 11376 mStackSupervisor.resumeTopActivitiesLocked(); 11377 } else { 11378 mStackSupervisor.finishTopRunningActivityLocked(app); 11379 } 11380 11381 // Bump up the crash count of any services currently running in the proc. 11382 for (int i=app.services.size()-1; i>=0; i--) { 11383 // Any services running in the application need to be placed 11384 // back in the pending list. 11385 ServiceRecord sr = app.services.valueAt(i); 11386 sr.crashCount++; 11387 } 11388 11389 // If the crashing process is what we consider to be the "home process" and it has been 11390 // replaced by a third-party app, clear the package preferred activities from packages 11391 // with a home activity running in the process to prevent a repeatedly crashing app 11392 // from blocking the user to manually clear the list. 11393 final ArrayList<ActivityRecord> activities = app.activities; 11394 if (app == mHomeProcess && activities.size() > 0 11395 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11396 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11397 final ActivityRecord r = activities.get(activityNdx); 11398 if (r.isHomeActivity()) { 11399 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11400 try { 11401 ActivityThread.getPackageManager() 11402 .clearPackagePreferredActivities(r.packageName); 11403 } catch (RemoteException c) { 11404 // pm is in same process, this will never happen. 11405 } 11406 } 11407 } 11408 } 11409 11410 if (!app.isolated) { 11411 // XXX Can't keep track of crash times for isolated processes, 11412 // because they don't have a perisistent identity. 11413 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11414 } 11415 11416 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11417 return true; 11418 } 11419 11420 void startAppProblemLocked(ProcessRecord app) { 11421 // If this app is not running under the current user, then we 11422 // can't give it a report button because that would require 11423 // launching the report UI under a different user. 11424 app.errorReportReceiver = null; 11425 11426 for (int userId : mCurrentProfileIds) { 11427 if (app.userId == userId) { 11428 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11429 mContext, app.info.packageName, app.info.flags); 11430 } 11431 } 11432 skipCurrentReceiverLocked(app); 11433 } 11434 11435 void skipCurrentReceiverLocked(ProcessRecord app) { 11436 for (BroadcastQueue queue : mBroadcastQueues) { 11437 queue.skipCurrentReceiverLocked(app); 11438 } 11439 } 11440 11441 /** 11442 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11443 * The application process will exit immediately after this call returns. 11444 * @param app object of the crashing app, null for the system server 11445 * @param crashInfo describing the exception 11446 */ 11447 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11448 ProcessRecord r = findAppProcess(app, "Crash"); 11449 final String processName = app == null ? "system_server" 11450 : (r == null ? "unknown" : r.processName); 11451 11452 handleApplicationCrashInner("crash", r, processName, crashInfo); 11453 } 11454 11455 /* Native crash reporting uses this inner version because it needs to be somewhat 11456 * decoupled from the AM-managed cleanup lifecycle 11457 */ 11458 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11459 ApplicationErrorReport.CrashInfo crashInfo) { 11460 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11461 UserHandle.getUserId(Binder.getCallingUid()), processName, 11462 r == null ? -1 : r.info.flags, 11463 crashInfo.exceptionClassName, 11464 crashInfo.exceptionMessage, 11465 crashInfo.throwFileName, 11466 crashInfo.throwLineNumber); 11467 11468 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11469 11470 crashApplication(r, crashInfo); 11471 } 11472 11473 public void handleApplicationStrictModeViolation( 11474 IBinder app, 11475 int violationMask, 11476 StrictMode.ViolationInfo info) { 11477 ProcessRecord r = findAppProcess(app, "StrictMode"); 11478 if (r == null) { 11479 return; 11480 } 11481 11482 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11483 Integer stackFingerprint = info.hashCode(); 11484 boolean logIt = true; 11485 synchronized (mAlreadyLoggedViolatedStacks) { 11486 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11487 logIt = false; 11488 // TODO: sub-sample into EventLog for these, with 11489 // the info.durationMillis? Then we'd get 11490 // the relative pain numbers, without logging all 11491 // the stack traces repeatedly. We'd want to do 11492 // likewise in the client code, which also does 11493 // dup suppression, before the Binder call. 11494 } else { 11495 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11496 mAlreadyLoggedViolatedStacks.clear(); 11497 } 11498 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11499 } 11500 } 11501 if (logIt) { 11502 logStrictModeViolationToDropBox(r, info); 11503 } 11504 } 11505 11506 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11507 AppErrorResult result = new AppErrorResult(); 11508 synchronized (this) { 11509 final long origId = Binder.clearCallingIdentity(); 11510 11511 Message msg = Message.obtain(); 11512 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11513 HashMap<String, Object> data = new HashMap<String, Object>(); 11514 data.put("result", result); 11515 data.put("app", r); 11516 data.put("violationMask", violationMask); 11517 data.put("info", info); 11518 msg.obj = data; 11519 mHandler.sendMessage(msg); 11520 11521 Binder.restoreCallingIdentity(origId); 11522 } 11523 int res = result.get(); 11524 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11525 } 11526 } 11527 11528 // Depending on the policy in effect, there could be a bunch of 11529 // these in quick succession so we try to batch these together to 11530 // minimize disk writes, number of dropbox entries, and maximize 11531 // compression, by having more fewer, larger records. 11532 private void logStrictModeViolationToDropBox( 11533 ProcessRecord process, 11534 StrictMode.ViolationInfo info) { 11535 if (info == null) { 11536 return; 11537 } 11538 final boolean isSystemApp = process == null || 11539 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11540 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11541 final String processName = process == null ? "unknown" : process.processName; 11542 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11543 final DropBoxManager dbox = (DropBoxManager) 11544 mContext.getSystemService(Context.DROPBOX_SERVICE); 11545 11546 // Exit early if the dropbox isn't configured to accept this report type. 11547 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11548 11549 boolean bufferWasEmpty; 11550 boolean needsFlush; 11551 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11552 synchronized (sb) { 11553 bufferWasEmpty = sb.length() == 0; 11554 appendDropBoxProcessHeaders(process, processName, sb); 11555 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11556 sb.append("System-App: ").append(isSystemApp).append("\n"); 11557 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11558 if (info.violationNumThisLoop != 0) { 11559 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11560 } 11561 if (info.numAnimationsRunning != 0) { 11562 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11563 } 11564 if (info.broadcastIntentAction != null) { 11565 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11566 } 11567 if (info.durationMillis != -1) { 11568 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11569 } 11570 if (info.numInstances != -1) { 11571 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11572 } 11573 if (info.tags != null) { 11574 for (String tag : info.tags) { 11575 sb.append("Span-Tag: ").append(tag).append("\n"); 11576 } 11577 } 11578 sb.append("\n"); 11579 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11580 sb.append(info.crashInfo.stackTrace); 11581 } 11582 sb.append("\n"); 11583 11584 // Only buffer up to ~64k. Various logging bits truncate 11585 // things at 128k. 11586 needsFlush = (sb.length() > 64 * 1024); 11587 } 11588 11589 // Flush immediately if the buffer's grown too large, or this 11590 // is a non-system app. Non-system apps are isolated with a 11591 // different tag & policy and not batched. 11592 // 11593 // Batching is useful during internal testing with 11594 // StrictMode settings turned up high. Without batching, 11595 // thousands of separate files could be created on boot. 11596 if (!isSystemApp || needsFlush) { 11597 new Thread("Error dump: " + dropboxTag) { 11598 @Override 11599 public void run() { 11600 String report; 11601 synchronized (sb) { 11602 report = sb.toString(); 11603 sb.delete(0, sb.length()); 11604 sb.trimToSize(); 11605 } 11606 if (report.length() != 0) { 11607 dbox.addText(dropboxTag, report); 11608 } 11609 } 11610 }.start(); 11611 return; 11612 } 11613 11614 // System app batching: 11615 if (!bufferWasEmpty) { 11616 // An existing dropbox-writing thread is outstanding, so 11617 // we don't need to start it up. The existing thread will 11618 // catch the buffer appends we just did. 11619 return; 11620 } 11621 11622 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11623 // (After this point, we shouldn't access AMS internal data structures.) 11624 new Thread("Error dump: " + dropboxTag) { 11625 @Override 11626 public void run() { 11627 // 5 second sleep to let stacks arrive and be batched together 11628 try { 11629 Thread.sleep(5000); // 5 seconds 11630 } catch (InterruptedException e) {} 11631 11632 String errorReport; 11633 synchronized (mStrictModeBuffer) { 11634 errorReport = mStrictModeBuffer.toString(); 11635 if (errorReport.length() == 0) { 11636 return; 11637 } 11638 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11639 mStrictModeBuffer.trimToSize(); 11640 } 11641 dbox.addText(dropboxTag, errorReport); 11642 } 11643 }.start(); 11644 } 11645 11646 /** 11647 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11648 * @param app object of the crashing app, null for the system server 11649 * @param tag reported by the caller 11650 * @param system whether this wtf is coming from the system 11651 * @param crashInfo describing the context of the error 11652 * @return true if the process should exit immediately (WTF is fatal) 11653 */ 11654 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11655 final ApplicationErrorReport.CrashInfo crashInfo) { 11656 final int callingUid = Binder.getCallingUid(); 11657 final int callingPid = Binder.getCallingPid(); 11658 11659 if (system) { 11660 // If this is coming from the system, we could very well have low-level 11661 // system locks held, so we want to do this all asynchronously. And we 11662 // never want this to become fatal, so there is that too. 11663 mHandler.post(new Runnable() { 11664 @Override public void run() { 11665 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11666 } 11667 }); 11668 return false; 11669 } 11670 11671 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11672 crashInfo); 11673 11674 if (r != null && r.pid != Process.myPid() && 11675 Settings.Global.getInt(mContext.getContentResolver(), 11676 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11677 crashApplication(r, crashInfo); 11678 return true; 11679 } else { 11680 return false; 11681 } 11682 } 11683 11684 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11685 final ApplicationErrorReport.CrashInfo crashInfo) { 11686 final ProcessRecord r = findAppProcess(app, "WTF"); 11687 final String processName = app == null ? "system_server" 11688 : (r == null ? "unknown" : r.processName); 11689 11690 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11691 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11692 11693 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11694 11695 return r; 11696 } 11697 11698 /** 11699 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11700 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11701 */ 11702 private ProcessRecord findAppProcess(IBinder app, String reason) { 11703 if (app == null) { 11704 return null; 11705 } 11706 11707 synchronized (this) { 11708 final int NP = mProcessNames.getMap().size(); 11709 for (int ip=0; ip<NP; ip++) { 11710 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11711 final int NA = apps.size(); 11712 for (int ia=0; ia<NA; ia++) { 11713 ProcessRecord p = apps.valueAt(ia); 11714 if (p.thread != null && p.thread.asBinder() == app) { 11715 return p; 11716 } 11717 } 11718 } 11719 11720 Slog.w(TAG, "Can't find mystery application for " + reason 11721 + " from pid=" + Binder.getCallingPid() 11722 + " uid=" + Binder.getCallingUid() + ": " + app); 11723 return null; 11724 } 11725 } 11726 11727 /** 11728 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11729 * to append various headers to the dropbox log text. 11730 */ 11731 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11732 StringBuilder sb) { 11733 // Watchdog thread ends up invoking this function (with 11734 // a null ProcessRecord) to add the stack file to dropbox. 11735 // Do not acquire a lock on this (am) in such cases, as it 11736 // could cause a potential deadlock, if and when watchdog 11737 // is invoked due to unavailability of lock on am and it 11738 // would prevent watchdog from killing system_server. 11739 if (process == null) { 11740 sb.append("Process: ").append(processName).append("\n"); 11741 return; 11742 } 11743 // Note: ProcessRecord 'process' is guarded by the service 11744 // instance. (notably process.pkgList, which could otherwise change 11745 // concurrently during execution of this method) 11746 synchronized (this) { 11747 sb.append("Process: ").append(processName).append("\n"); 11748 int flags = process.info.flags; 11749 IPackageManager pm = AppGlobals.getPackageManager(); 11750 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11751 for (int ip=0; ip<process.pkgList.size(); ip++) { 11752 String pkg = process.pkgList.keyAt(ip); 11753 sb.append("Package: ").append(pkg); 11754 try { 11755 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11756 if (pi != null) { 11757 sb.append(" v").append(pi.versionCode); 11758 if (pi.versionName != null) { 11759 sb.append(" (").append(pi.versionName).append(")"); 11760 } 11761 } 11762 } catch (RemoteException e) { 11763 Slog.e(TAG, "Error getting package info: " + pkg, e); 11764 } 11765 sb.append("\n"); 11766 } 11767 } 11768 } 11769 11770 private static String processClass(ProcessRecord process) { 11771 if (process == null || process.pid == MY_PID) { 11772 return "system_server"; 11773 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11774 return "system_app"; 11775 } else { 11776 return "data_app"; 11777 } 11778 } 11779 11780 /** 11781 * Write a description of an error (crash, WTF, ANR) to the drop box. 11782 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11783 * @param process which caused the error, null means the system server 11784 * @param activity which triggered the error, null if unknown 11785 * @param parent activity related to the error, null if unknown 11786 * @param subject line related to the error, null if absent 11787 * @param report in long form describing the error, null if absent 11788 * @param logFile to include in the report, null if none 11789 * @param crashInfo giving an application stack trace, null if absent 11790 */ 11791 public void addErrorToDropBox(String eventType, 11792 ProcessRecord process, String processName, ActivityRecord activity, 11793 ActivityRecord parent, String subject, 11794 final String report, final File logFile, 11795 final ApplicationErrorReport.CrashInfo crashInfo) { 11796 // NOTE -- this must never acquire the ActivityManagerService lock, 11797 // otherwise the watchdog may be prevented from resetting the system. 11798 11799 final String dropboxTag = processClass(process) + "_" + eventType; 11800 final DropBoxManager dbox = (DropBoxManager) 11801 mContext.getSystemService(Context.DROPBOX_SERVICE); 11802 11803 // Exit early if the dropbox isn't configured to accept this report type. 11804 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11805 11806 final StringBuilder sb = new StringBuilder(1024); 11807 appendDropBoxProcessHeaders(process, processName, sb); 11808 if (activity != null) { 11809 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11810 } 11811 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11812 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11813 } 11814 if (parent != null && parent != activity) { 11815 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11816 } 11817 if (subject != null) { 11818 sb.append("Subject: ").append(subject).append("\n"); 11819 } 11820 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11821 if (Debug.isDebuggerConnected()) { 11822 sb.append("Debugger: Connected\n"); 11823 } 11824 sb.append("\n"); 11825 11826 // Do the rest in a worker thread to avoid blocking the caller on I/O 11827 // (After this point, we shouldn't access AMS internal data structures.) 11828 Thread worker = new Thread("Error dump: " + dropboxTag) { 11829 @Override 11830 public void run() { 11831 if (report != null) { 11832 sb.append(report); 11833 } 11834 if (logFile != null) { 11835 try { 11836 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11837 "\n\n[[TRUNCATED]]")); 11838 } catch (IOException e) { 11839 Slog.e(TAG, "Error reading " + logFile, e); 11840 } 11841 } 11842 if (crashInfo != null && crashInfo.stackTrace != null) { 11843 sb.append(crashInfo.stackTrace); 11844 } 11845 11846 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11847 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11848 if (lines > 0) { 11849 sb.append("\n"); 11850 11851 // Merge several logcat streams, and take the last N lines 11852 InputStreamReader input = null; 11853 try { 11854 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11855 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11856 "-b", "crash", 11857 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11858 11859 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11860 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11861 input = new InputStreamReader(logcat.getInputStream()); 11862 11863 int num; 11864 char[] buf = new char[8192]; 11865 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11866 } catch (IOException e) { 11867 Slog.e(TAG, "Error running logcat", e); 11868 } finally { 11869 if (input != null) try { input.close(); } catch (IOException e) {} 11870 } 11871 } 11872 11873 dbox.addText(dropboxTag, sb.toString()); 11874 } 11875 }; 11876 11877 if (process == null) { 11878 // If process is null, we are being called from some internal code 11879 // and may be about to die -- run this synchronously. 11880 worker.run(); 11881 } else { 11882 worker.start(); 11883 } 11884 } 11885 11886 /** 11887 * Bring up the "unexpected error" dialog box for a crashing app. 11888 * Deal with edge cases (intercepts from instrumented applications, 11889 * ActivityController, error intent receivers, that sort of thing). 11890 * @param r the application crashing 11891 * @param crashInfo describing the failure 11892 */ 11893 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11894 long timeMillis = System.currentTimeMillis(); 11895 String shortMsg = crashInfo.exceptionClassName; 11896 String longMsg = crashInfo.exceptionMessage; 11897 String stackTrace = crashInfo.stackTrace; 11898 if (shortMsg != null && longMsg != null) { 11899 longMsg = shortMsg + ": " + longMsg; 11900 } else if (shortMsg != null) { 11901 longMsg = shortMsg; 11902 } 11903 11904 AppErrorResult result = new AppErrorResult(); 11905 synchronized (this) { 11906 if (mController != null) { 11907 try { 11908 String name = r != null ? r.processName : null; 11909 int pid = r != null ? r.pid : Binder.getCallingPid(); 11910 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11911 if (!mController.appCrashed(name, pid, 11912 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11913 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11914 && "Native crash".equals(crashInfo.exceptionClassName)) { 11915 Slog.w(TAG, "Skip killing native crashed app " + name 11916 + "(" + pid + ") during testing"); 11917 } else { 11918 Slog.w(TAG, "Force-killing crashed app " + name 11919 + " at watcher's request"); 11920 if (r != null) { 11921 r.kill("crash", true); 11922 } else { 11923 // Huh. 11924 Process.killProcess(pid); 11925 Process.killProcessGroup(uid, pid); 11926 } 11927 } 11928 return; 11929 } 11930 } catch (RemoteException e) { 11931 mController = null; 11932 Watchdog.getInstance().setActivityController(null); 11933 } 11934 } 11935 11936 final long origId = Binder.clearCallingIdentity(); 11937 11938 // If this process is running instrumentation, finish it. 11939 if (r != null && r.instrumentationClass != null) { 11940 Slog.w(TAG, "Error in app " + r.processName 11941 + " running instrumentation " + r.instrumentationClass + ":"); 11942 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11943 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11944 Bundle info = new Bundle(); 11945 info.putString("shortMsg", shortMsg); 11946 info.putString("longMsg", longMsg); 11947 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11948 Binder.restoreCallingIdentity(origId); 11949 return; 11950 } 11951 11952 // If we can't identify the process or it's already exceeded its crash quota, 11953 // quit right away without showing a crash dialog. 11954 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11955 Binder.restoreCallingIdentity(origId); 11956 return; 11957 } 11958 11959 Message msg = Message.obtain(); 11960 msg.what = SHOW_ERROR_MSG; 11961 HashMap data = new HashMap(); 11962 data.put("result", result); 11963 data.put("app", r); 11964 msg.obj = data; 11965 mHandler.sendMessage(msg); 11966 11967 Binder.restoreCallingIdentity(origId); 11968 } 11969 11970 int res = result.get(); 11971 11972 Intent appErrorIntent = null; 11973 synchronized (this) { 11974 if (r != null && !r.isolated) { 11975 // XXX Can't keep track of crash time for isolated processes, 11976 // since they don't have a persistent identity. 11977 mProcessCrashTimes.put(r.info.processName, r.uid, 11978 SystemClock.uptimeMillis()); 11979 } 11980 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11981 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11982 } 11983 } 11984 11985 if (appErrorIntent != null) { 11986 try { 11987 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11988 } catch (ActivityNotFoundException e) { 11989 Slog.w(TAG, "bug report receiver dissappeared", e); 11990 } 11991 } 11992 } 11993 11994 Intent createAppErrorIntentLocked(ProcessRecord r, 11995 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11996 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11997 if (report == null) { 11998 return null; 11999 } 12000 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12001 result.setComponent(r.errorReportReceiver); 12002 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12003 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12004 return result; 12005 } 12006 12007 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12008 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12009 if (r.errorReportReceiver == null) { 12010 return null; 12011 } 12012 12013 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12014 return null; 12015 } 12016 12017 ApplicationErrorReport report = new ApplicationErrorReport(); 12018 report.packageName = r.info.packageName; 12019 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12020 report.processName = r.processName; 12021 report.time = timeMillis; 12022 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12023 12024 if (r.crashing || r.forceCrashReport) { 12025 report.type = ApplicationErrorReport.TYPE_CRASH; 12026 report.crashInfo = crashInfo; 12027 } else if (r.notResponding) { 12028 report.type = ApplicationErrorReport.TYPE_ANR; 12029 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12030 12031 report.anrInfo.activity = r.notRespondingReport.tag; 12032 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12033 report.anrInfo.info = r.notRespondingReport.longMsg; 12034 } 12035 12036 return report; 12037 } 12038 12039 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12040 enforceNotIsolatedCaller("getProcessesInErrorState"); 12041 // assume our apps are happy - lazy create the list 12042 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12043 12044 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12045 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12046 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12047 12048 synchronized (this) { 12049 12050 // iterate across all processes 12051 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12052 ProcessRecord app = mLruProcesses.get(i); 12053 if (!allUsers && app.userId != userId) { 12054 continue; 12055 } 12056 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12057 // This one's in trouble, so we'll generate a report for it 12058 // crashes are higher priority (in case there's a crash *and* an anr) 12059 ActivityManager.ProcessErrorStateInfo report = null; 12060 if (app.crashing) { 12061 report = app.crashingReport; 12062 } else if (app.notResponding) { 12063 report = app.notRespondingReport; 12064 } 12065 12066 if (report != null) { 12067 if (errList == null) { 12068 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12069 } 12070 errList.add(report); 12071 } else { 12072 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12073 " crashing = " + app.crashing + 12074 " notResponding = " + app.notResponding); 12075 } 12076 } 12077 } 12078 } 12079 12080 return errList; 12081 } 12082 12083 static int procStateToImportance(int procState, int memAdj, 12084 ActivityManager.RunningAppProcessInfo currApp) { 12085 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12086 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12087 currApp.lru = memAdj; 12088 } else { 12089 currApp.lru = 0; 12090 } 12091 return imp; 12092 } 12093 12094 private void fillInProcMemInfo(ProcessRecord app, 12095 ActivityManager.RunningAppProcessInfo outInfo) { 12096 outInfo.pid = app.pid; 12097 outInfo.uid = app.info.uid; 12098 if (mHeavyWeightProcess == app) { 12099 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12100 } 12101 if (app.persistent) { 12102 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12103 } 12104 if (app.activities.size() > 0) { 12105 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12106 } 12107 outInfo.lastTrimLevel = app.trimMemoryLevel; 12108 int adj = app.curAdj; 12109 int procState = app.curProcState; 12110 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12111 outInfo.importanceReasonCode = app.adjTypeCode; 12112 outInfo.processState = app.curProcState; 12113 } 12114 12115 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12116 enforceNotIsolatedCaller("getRunningAppProcesses"); 12117 // Lazy instantiation of list 12118 List<ActivityManager.RunningAppProcessInfo> runList = null; 12119 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12120 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12121 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12122 synchronized (this) { 12123 // Iterate across all processes 12124 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12125 ProcessRecord app = mLruProcesses.get(i); 12126 if (!allUsers && app.userId != userId) { 12127 continue; 12128 } 12129 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12130 // Generate process state info for running application 12131 ActivityManager.RunningAppProcessInfo currApp = 12132 new ActivityManager.RunningAppProcessInfo(app.processName, 12133 app.pid, app.getPackageList()); 12134 fillInProcMemInfo(app, currApp); 12135 if (app.adjSource instanceof ProcessRecord) { 12136 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12137 currApp.importanceReasonImportance = 12138 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12139 app.adjSourceProcState); 12140 } else if (app.adjSource instanceof ActivityRecord) { 12141 ActivityRecord r = (ActivityRecord)app.adjSource; 12142 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12143 } 12144 if (app.adjTarget instanceof ComponentName) { 12145 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12146 } 12147 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12148 // + " lru=" + currApp.lru); 12149 if (runList == null) { 12150 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12151 } 12152 runList.add(currApp); 12153 } 12154 } 12155 } 12156 return runList; 12157 } 12158 12159 public List<ApplicationInfo> getRunningExternalApplications() { 12160 enforceNotIsolatedCaller("getRunningExternalApplications"); 12161 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12162 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12163 if (runningApps != null && runningApps.size() > 0) { 12164 Set<String> extList = new HashSet<String>(); 12165 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12166 if (app.pkgList != null) { 12167 for (String pkg : app.pkgList) { 12168 extList.add(pkg); 12169 } 12170 } 12171 } 12172 IPackageManager pm = AppGlobals.getPackageManager(); 12173 for (String pkg : extList) { 12174 try { 12175 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12176 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12177 retList.add(info); 12178 } 12179 } catch (RemoteException e) { 12180 } 12181 } 12182 } 12183 return retList; 12184 } 12185 12186 @Override 12187 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12188 enforceNotIsolatedCaller("getMyMemoryState"); 12189 synchronized (this) { 12190 ProcessRecord proc; 12191 synchronized (mPidsSelfLocked) { 12192 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12193 } 12194 fillInProcMemInfo(proc, outInfo); 12195 } 12196 } 12197 12198 @Override 12199 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12200 if (checkCallingPermission(android.Manifest.permission.DUMP) 12201 != PackageManager.PERMISSION_GRANTED) { 12202 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12203 + Binder.getCallingPid() 12204 + ", uid=" + Binder.getCallingUid() 12205 + " without permission " 12206 + android.Manifest.permission.DUMP); 12207 return; 12208 } 12209 12210 boolean dumpAll = false; 12211 boolean dumpClient = false; 12212 String dumpPackage = null; 12213 12214 int opti = 0; 12215 while (opti < args.length) { 12216 String opt = args[opti]; 12217 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12218 break; 12219 } 12220 opti++; 12221 if ("-a".equals(opt)) { 12222 dumpAll = true; 12223 } else if ("-c".equals(opt)) { 12224 dumpClient = true; 12225 } else if ("-h".equals(opt)) { 12226 pw.println("Activity manager dump options:"); 12227 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12228 pw.println(" cmd may be one of:"); 12229 pw.println(" a[ctivities]: activity stack state"); 12230 pw.println(" r[recents]: recent activities state"); 12231 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12232 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12233 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12234 pw.println(" o[om]: out of memory management"); 12235 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12236 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12237 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12238 pw.println(" service [COMP_SPEC]: service client-side state"); 12239 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12240 pw.println(" all: dump all activities"); 12241 pw.println(" top: dump the top activity"); 12242 pw.println(" write: write all pending state to storage"); 12243 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12244 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12245 pw.println(" a partial substring in a component name, a"); 12246 pw.println(" hex object identifier."); 12247 pw.println(" -a: include all available server state."); 12248 pw.println(" -c: include client state."); 12249 return; 12250 } else { 12251 pw.println("Unknown argument: " + opt + "; use -h for help"); 12252 } 12253 } 12254 12255 long origId = Binder.clearCallingIdentity(); 12256 boolean more = false; 12257 // Is the caller requesting to dump a particular piece of data? 12258 if (opti < args.length) { 12259 String cmd = args[opti]; 12260 opti++; 12261 if ("activities".equals(cmd) || "a".equals(cmd)) { 12262 synchronized (this) { 12263 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12264 } 12265 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12266 synchronized (this) { 12267 dumpRecentsLocked(fd, pw, args, opti, true, null); 12268 } 12269 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12270 String[] newArgs; 12271 String name; 12272 if (opti >= args.length) { 12273 name = null; 12274 newArgs = EMPTY_STRING_ARRAY; 12275 } else { 12276 name = args[opti]; 12277 opti++; 12278 newArgs = new String[args.length - opti]; 12279 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12280 args.length - opti); 12281 } 12282 synchronized (this) { 12283 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12284 } 12285 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12286 String[] newArgs; 12287 String name; 12288 if (opti >= args.length) { 12289 name = null; 12290 newArgs = EMPTY_STRING_ARRAY; 12291 } else { 12292 name = args[opti]; 12293 opti++; 12294 newArgs = new String[args.length - opti]; 12295 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12296 args.length - opti); 12297 } 12298 synchronized (this) { 12299 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12300 } 12301 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12302 String[] newArgs; 12303 String name; 12304 if (opti >= args.length) { 12305 name = null; 12306 newArgs = EMPTY_STRING_ARRAY; 12307 } else { 12308 name = args[opti]; 12309 opti++; 12310 newArgs = new String[args.length - opti]; 12311 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12312 args.length - opti); 12313 } 12314 synchronized (this) { 12315 dumpProcessesLocked(fd, pw, args, opti, true, name); 12316 } 12317 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12318 synchronized (this) { 12319 dumpOomLocked(fd, pw, args, opti, true); 12320 } 12321 } else if ("provider".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, args.length - opti); 12332 } 12333 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12334 pw.println("No providers match: " + name); 12335 pw.println("Use -h for help."); 12336 } 12337 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12338 synchronized (this) { 12339 dumpProvidersLocked(fd, pw, args, opti, true, null); 12340 } 12341 } else if ("service".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, 12352 args.length - opti); 12353 } 12354 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12355 pw.println("No services match: " + name); 12356 pw.println("Use -h for help."); 12357 } 12358 } else if ("package".equals(cmd)) { 12359 String[] newArgs; 12360 if (opti >= args.length) { 12361 pw.println("package: no package name specified"); 12362 pw.println("Use -h for help."); 12363 } else { 12364 dumpPackage = args[opti]; 12365 opti++; 12366 newArgs = new String[args.length - opti]; 12367 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12368 args.length - opti); 12369 args = newArgs; 12370 opti = 0; 12371 more = true; 12372 } 12373 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12374 synchronized (this) { 12375 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12376 } 12377 } else if ("write".equals(cmd)) { 12378 mTaskPersister.flush(); 12379 pw.println("All tasks persisted."); 12380 return; 12381 } else { 12382 // Dumping a single activity? 12383 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12384 pw.println("Bad activity command, or no activities match: " + cmd); 12385 pw.println("Use -h for help."); 12386 } 12387 } 12388 if (!more) { 12389 Binder.restoreCallingIdentity(origId); 12390 return; 12391 } 12392 } 12393 12394 // No piece of data specified, dump everything. 12395 synchronized (this) { 12396 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12397 pw.println(); 12398 if (dumpAll) { 12399 pw.println("-------------------------------------------------------------------------------"); 12400 } 12401 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12402 pw.println(); 12403 if (dumpAll) { 12404 pw.println("-------------------------------------------------------------------------------"); 12405 } 12406 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12407 pw.println(); 12408 if (dumpAll) { 12409 pw.println("-------------------------------------------------------------------------------"); 12410 } 12411 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12412 pw.println(); 12413 if (dumpAll) { 12414 pw.println("-------------------------------------------------------------------------------"); 12415 } 12416 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12417 pw.println(); 12418 if (dumpAll) { 12419 pw.println("-------------------------------------------------------------------------------"); 12420 } 12421 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12422 pw.println(); 12423 if (dumpAll) { 12424 pw.println("-------------------------------------------------------------------------------"); 12425 } 12426 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12427 } 12428 Binder.restoreCallingIdentity(origId); 12429 } 12430 12431 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12432 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12433 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12434 12435 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12436 dumpPackage); 12437 boolean needSep = printedAnything; 12438 12439 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12440 dumpPackage, needSep, " mFocusedActivity: "); 12441 if (printed) { 12442 printedAnything = true; 12443 needSep = false; 12444 } 12445 12446 if (dumpPackage == null) { 12447 if (needSep) { 12448 pw.println(); 12449 } 12450 needSep = true; 12451 printedAnything = true; 12452 mStackSupervisor.dump(pw, " "); 12453 } 12454 12455 if (!printedAnything) { 12456 pw.println(" (nothing)"); 12457 } 12458 } 12459 12460 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12461 int opti, boolean dumpAll, String dumpPackage) { 12462 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12463 12464 boolean printedAnything = false; 12465 12466 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12467 boolean printedHeader = false; 12468 12469 final int N = mRecentTasks.size(); 12470 for (int i=0; i<N; i++) { 12471 TaskRecord tr = mRecentTasks.get(i); 12472 if (dumpPackage != null) { 12473 if (tr.realActivity == null || 12474 !dumpPackage.equals(tr.realActivity)) { 12475 continue; 12476 } 12477 } 12478 if (!printedHeader) { 12479 pw.println(" Recent tasks:"); 12480 printedHeader = true; 12481 printedAnything = true; 12482 } 12483 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12484 pw.println(tr); 12485 if (dumpAll) { 12486 mRecentTasks.get(i).dump(pw, " "); 12487 } 12488 } 12489 } 12490 12491 if (!printedAnything) { 12492 pw.println(" (nothing)"); 12493 } 12494 } 12495 12496 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12497 int opti, boolean dumpAll, String dumpPackage) { 12498 boolean needSep = false; 12499 boolean printedAnything = false; 12500 int numPers = 0; 12501 12502 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12503 12504 if (dumpAll) { 12505 final int NP = mProcessNames.getMap().size(); 12506 for (int ip=0; ip<NP; ip++) { 12507 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12508 final int NA = procs.size(); 12509 for (int ia=0; ia<NA; ia++) { 12510 ProcessRecord r = procs.valueAt(ia); 12511 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12512 continue; 12513 } 12514 if (!needSep) { 12515 pw.println(" All known processes:"); 12516 needSep = true; 12517 printedAnything = true; 12518 } 12519 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12520 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12521 pw.print(" "); pw.println(r); 12522 r.dump(pw, " "); 12523 if (r.persistent) { 12524 numPers++; 12525 } 12526 } 12527 } 12528 } 12529 12530 if (mIsolatedProcesses.size() > 0) { 12531 boolean printed = false; 12532 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12533 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12534 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12535 continue; 12536 } 12537 if (!printed) { 12538 if (needSep) { 12539 pw.println(); 12540 } 12541 pw.println(" Isolated process list (sorted by uid):"); 12542 printedAnything = true; 12543 printed = true; 12544 needSep = true; 12545 } 12546 pw.println(String.format("%sIsolated #%2d: %s", 12547 " ", i, r.toString())); 12548 } 12549 } 12550 12551 if (mLruProcesses.size() > 0) { 12552 if (needSep) { 12553 pw.println(); 12554 } 12555 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12556 pw.print(" total, non-act at "); 12557 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12558 pw.print(", non-svc at "); 12559 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12560 pw.println("):"); 12561 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12562 needSep = true; 12563 printedAnything = true; 12564 } 12565 12566 if (dumpAll || dumpPackage != null) { 12567 synchronized (mPidsSelfLocked) { 12568 boolean printed = false; 12569 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12570 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12571 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12572 continue; 12573 } 12574 if (!printed) { 12575 if (needSep) pw.println(); 12576 needSep = true; 12577 pw.println(" PID mappings:"); 12578 printed = true; 12579 printedAnything = true; 12580 } 12581 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12582 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12583 } 12584 } 12585 } 12586 12587 if (mForegroundProcesses.size() > 0) { 12588 synchronized (mPidsSelfLocked) { 12589 boolean printed = false; 12590 for (int i=0; i<mForegroundProcesses.size(); i++) { 12591 ProcessRecord r = mPidsSelfLocked.get( 12592 mForegroundProcesses.valueAt(i).pid); 12593 if (dumpPackage != null && (r == null 12594 || !r.pkgList.containsKey(dumpPackage))) { 12595 continue; 12596 } 12597 if (!printed) { 12598 if (needSep) pw.println(); 12599 needSep = true; 12600 pw.println(" Foreground Processes:"); 12601 printed = true; 12602 printedAnything = true; 12603 } 12604 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12605 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12606 } 12607 } 12608 } 12609 12610 if (mPersistentStartingProcesses.size() > 0) { 12611 if (needSep) pw.println(); 12612 needSep = true; 12613 printedAnything = true; 12614 pw.println(" Persisent processes that are starting:"); 12615 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12616 "Starting Norm", "Restarting PERS", dumpPackage); 12617 } 12618 12619 if (mRemovedProcesses.size() > 0) { 12620 if (needSep) pw.println(); 12621 needSep = true; 12622 printedAnything = true; 12623 pw.println(" Processes that are being removed:"); 12624 dumpProcessList(pw, this, mRemovedProcesses, " ", 12625 "Removed Norm", "Removed PERS", dumpPackage); 12626 } 12627 12628 if (mProcessesOnHold.size() > 0) { 12629 if (needSep) pw.println(); 12630 needSep = true; 12631 printedAnything = true; 12632 pw.println(" Processes that are on old until the system is ready:"); 12633 dumpProcessList(pw, this, mProcessesOnHold, " ", 12634 "OnHold Norm", "OnHold PERS", dumpPackage); 12635 } 12636 12637 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12638 12639 if (mProcessCrashTimes.getMap().size() > 0) { 12640 boolean printed = false; 12641 long now = SystemClock.uptimeMillis(); 12642 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12643 final int NP = pmap.size(); 12644 for (int ip=0; ip<NP; ip++) { 12645 String pname = pmap.keyAt(ip); 12646 SparseArray<Long> uids = pmap.valueAt(ip); 12647 final int N = uids.size(); 12648 for (int i=0; i<N; i++) { 12649 int puid = uids.keyAt(i); 12650 ProcessRecord r = mProcessNames.get(pname, puid); 12651 if (dumpPackage != null && (r == null 12652 || !r.pkgList.containsKey(dumpPackage))) { 12653 continue; 12654 } 12655 if (!printed) { 12656 if (needSep) pw.println(); 12657 needSep = true; 12658 pw.println(" Time since processes crashed:"); 12659 printed = true; 12660 printedAnything = true; 12661 } 12662 pw.print(" Process "); pw.print(pname); 12663 pw.print(" uid "); pw.print(puid); 12664 pw.print(": last crashed "); 12665 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12666 pw.println(" ago"); 12667 } 12668 } 12669 } 12670 12671 if (mBadProcesses.getMap().size() > 0) { 12672 boolean printed = false; 12673 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12674 final int NP = pmap.size(); 12675 for (int ip=0; ip<NP; ip++) { 12676 String pname = pmap.keyAt(ip); 12677 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12678 final int N = uids.size(); 12679 for (int i=0; i<N; i++) { 12680 int puid = uids.keyAt(i); 12681 ProcessRecord r = mProcessNames.get(pname, puid); 12682 if (dumpPackage != null && (r == null 12683 || !r.pkgList.containsKey(dumpPackage))) { 12684 continue; 12685 } 12686 if (!printed) { 12687 if (needSep) pw.println(); 12688 needSep = true; 12689 pw.println(" Bad processes:"); 12690 printedAnything = true; 12691 } 12692 BadProcessInfo info = uids.valueAt(i); 12693 pw.print(" Bad process "); pw.print(pname); 12694 pw.print(" uid "); pw.print(puid); 12695 pw.print(": crashed at time "); pw.println(info.time); 12696 if (info.shortMsg != null) { 12697 pw.print(" Short msg: "); pw.println(info.shortMsg); 12698 } 12699 if (info.longMsg != null) { 12700 pw.print(" Long msg: "); pw.println(info.longMsg); 12701 } 12702 if (info.stack != null) { 12703 pw.println(" Stack:"); 12704 int lastPos = 0; 12705 for (int pos=0; pos<info.stack.length(); pos++) { 12706 if (info.stack.charAt(pos) == '\n') { 12707 pw.print(" "); 12708 pw.write(info.stack, lastPos, pos-lastPos); 12709 pw.println(); 12710 lastPos = pos+1; 12711 } 12712 } 12713 if (lastPos < info.stack.length()) { 12714 pw.print(" "); 12715 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12716 pw.println(); 12717 } 12718 } 12719 } 12720 } 12721 } 12722 12723 if (dumpPackage == null) { 12724 pw.println(); 12725 needSep = false; 12726 pw.println(" mStartedUsers:"); 12727 for (int i=0; i<mStartedUsers.size(); i++) { 12728 UserStartedState uss = mStartedUsers.valueAt(i); 12729 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12730 pw.print(": "); uss.dump("", pw); 12731 } 12732 pw.print(" mStartedUserArray: ["); 12733 for (int i=0; i<mStartedUserArray.length; i++) { 12734 if (i > 0) pw.print(", "); 12735 pw.print(mStartedUserArray[i]); 12736 } 12737 pw.println("]"); 12738 pw.print(" mUserLru: ["); 12739 for (int i=0; i<mUserLru.size(); i++) { 12740 if (i > 0) pw.print(", "); 12741 pw.print(mUserLru.get(i)); 12742 } 12743 pw.println("]"); 12744 if (dumpAll) { 12745 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12746 } 12747 synchronized (mUserProfileGroupIdsSelfLocked) { 12748 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12749 pw.println(" mUserProfileGroupIds:"); 12750 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12751 pw.print(" User #"); 12752 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12753 pw.print(" -> profile #"); 12754 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12755 } 12756 } 12757 } 12758 } 12759 if (mHomeProcess != null && (dumpPackage == null 12760 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12761 if (needSep) { 12762 pw.println(); 12763 needSep = false; 12764 } 12765 pw.println(" mHomeProcess: " + mHomeProcess); 12766 } 12767 if (mPreviousProcess != null && (dumpPackage == null 12768 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12769 if (needSep) { 12770 pw.println(); 12771 needSep = false; 12772 } 12773 pw.println(" mPreviousProcess: " + mPreviousProcess); 12774 } 12775 if (dumpAll) { 12776 StringBuilder sb = new StringBuilder(128); 12777 sb.append(" mPreviousProcessVisibleTime: "); 12778 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12779 pw.println(sb); 12780 } 12781 if (mHeavyWeightProcess != null && (dumpPackage == null 12782 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12783 if (needSep) { 12784 pw.println(); 12785 needSep = false; 12786 } 12787 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12788 } 12789 if (dumpPackage == null) { 12790 pw.println(" mConfiguration: " + mConfiguration); 12791 } 12792 if (dumpAll) { 12793 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12794 if (mCompatModePackages.getPackages().size() > 0) { 12795 boolean printed = false; 12796 for (Map.Entry<String, Integer> entry 12797 : mCompatModePackages.getPackages().entrySet()) { 12798 String pkg = entry.getKey(); 12799 int mode = entry.getValue(); 12800 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12801 continue; 12802 } 12803 if (!printed) { 12804 pw.println(" mScreenCompatPackages:"); 12805 printed = true; 12806 } 12807 pw.print(" "); pw.print(pkg); pw.print(": "); 12808 pw.print(mode); pw.println(); 12809 } 12810 } 12811 } 12812 if (dumpPackage == null) { 12813 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12814 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12815 + " mLockScreenShown " + lockScreenShownToString()); 12816 } 12817 if (mShuttingDown || mRunningVoice) { 12818 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12819 } 12820 } 12821 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12822 || mOrigWaitForDebugger) { 12823 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12824 || dumpPackage.equals(mOrigDebugApp)) { 12825 if (needSep) { 12826 pw.println(); 12827 needSep = false; 12828 } 12829 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12830 + " mDebugTransient=" + mDebugTransient 12831 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12832 } 12833 } 12834 if (mOpenGlTraceApp != null) { 12835 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12836 if (needSep) { 12837 pw.println(); 12838 needSep = false; 12839 } 12840 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12841 } 12842 } 12843 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12844 || mProfileFd != null) { 12845 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12846 if (needSep) { 12847 pw.println(); 12848 needSep = false; 12849 } 12850 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12851 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12852 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12853 + mAutoStopProfiler); 12854 pw.println(" mProfileType=" + mProfileType); 12855 } 12856 } 12857 if (dumpPackage == null) { 12858 if (mAlwaysFinishActivities || mController != null) { 12859 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12860 + " mController=" + mController); 12861 } 12862 if (dumpAll) { 12863 pw.println(" Total persistent processes: " + numPers); 12864 pw.println(" mProcessesReady=" + mProcessesReady 12865 + " mSystemReady=" + mSystemReady 12866 + " mBooted=" + mBooted 12867 + " mFactoryTest=" + mFactoryTest); 12868 pw.println(" mBooting=" + mBooting 12869 + " mCallFinishBooting=" + mCallFinishBooting 12870 + " mBootAnimationComplete=" + mBootAnimationComplete); 12871 pw.print(" mLastPowerCheckRealtime="); 12872 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12873 pw.println(""); 12874 pw.print(" mLastPowerCheckUptime="); 12875 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12876 pw.println(""); 12877 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12878 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12879 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12880 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12881 + " (" + mLruProcesses.size() + " total)" 12882 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12883 + " mNumServiceProcs=" + mNumServiceProcs 12884 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12885 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12886 + " mLastMemoryLevel" + mLastMemoryLevel 12887 + " mLastNumProcesses" + mLastNumProcesses); 12888 long now = SystemClock.uptimeMillis(); 12889 pw.print(" mLastIdleTime="); 12890 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12891 pw.print(" mLowRamSinceLastIdle="); 12892 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12893 pw.println(); 12894 } 12895 } 12896 12897 if (!printedAnything) { 12898 pw.println(" (nothing)"); 12899 } 12900 } 12901 12902 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12903 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12904 if (mProcessesToGc.size() > 0) { 12905 boolean printed = false; 12906 long now = SystemClock.uptimeMillis(); 12907 for (int i=0; i<mProcessesToGc.size(); i++) { 12908 ProcessRecord proc = mProcessesToGc.get(i); 12909 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12910 continue; 12911 } 12912 if (!printed) { 12913 if (needSep) pw.println(); 12914 needSep = true; 12915 pw.println(" Processes that are waiting to GC:"); 12916 printed = true; 12917 } 12918 pw.print(" Process "); pw.println(proc); 12919 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12920 pw.print(", last gced="); 12921 pw.print(now-proc.lastRequestedGc); 12922 pw.print(" ms ago, last lowMem="); 12923 pw.print(now-proc.lastLowMemory); 12924 pw.println(" ms ago"); 12925 12926 } 12927 } 12928 return needSep; 12929 } 12930 12931 void printOomLevel(PrintWriter pw, String name, int adj) { 12932 pw.print(" "); 12933 if (adj >= 0) { 12934 pw.print(' '); 12935 if (adj < 10) pw.print(' '); 12936 } else { 12937 if (adj > -10) pw.print(' '); 12938 } 12939 pw.print(adj); 12940 pw.print(": "); 12941 pw.print(name); 12942 pw.print(" ("); 12943 pw.print(mProcessList.getMemLevel(adj)/1024); 12944 pw.println(" kB)"); 12945 } 12946 12947 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12948 int opti, boolean dumpAll) { 12949 boolean needSep = false; 12950 12951 if (mLruProcesses.size() > 0) { 12952 if (needSep) pw.println(); 12953 needSep = true; 12954 pw.println(" OOM levels:"); 12955 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12956 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12957 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12958 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12959 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12960 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12961 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12962 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12963 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12964 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12965 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12966 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12967 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12968 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12969 12970 if (needSep) pw.println(); 12971 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12972 pw.print(" total, non-act at "); 12973 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12974 pw.print(", non-svc at "); 12975 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12976 pw.println("):"); 12977 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12978 needSep = true; 12979 } 12980 12981 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12982 12983 pw.println(); 12984 pw.println(" mHomeProcess: " + mHomeProcess); 12985 pw.println(" mPreviousProcess: " + mPreviousProcess); 12986 if (mHeavyWeightProcess != null) { 12987 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12988 } 12989 12990 return true; 12991 } 12992 12993 /** 12994 * There are three ways to call this: 12995 * - no provider specified: dump all the providers 12996 * - a flattened component name that matched an existing provider was specified as the 12997 * first arg: dump that one provider 12998 * - the first arg isn't the flattened component name of an existing provider: 12999 * dump all providers whose component contains the first arg as a substring 13000 */ 13001 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13002 int opti, boolean dumpAll) { 13003 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13004 } 13005 13006 static class ItemMatcher { 13007 ArrayList<ComponentName> components; 13008 ArrayList<String> strings; 13009 ArrayList<Integer> objects; 13010 boolean all; 13011 13012 ItemMatcher() { 13013 all = true; 13014 } 13015 13016 void build(String name) { 13017 ComponentName componentName = ComponentName.unflattenFromString(name); 13018 if (componentName != null) { 13019 if (components == null) { 13020 components = new ArrayList<ComponentName>(); 13021 } 13022 components.add(componentName); 13023 all = false; 13024 } else { 13025 int objectId = 0; 13026 // Not a '/' separated full component name; maybe an object ID? 13027 try { 13028 objectId = Integer.parseInt(name, 16); 13029 if (objects == null) { 13030 objects = new ArrayList<Integer>(); 13031 } 13032 objects.add(objectId); 13033 all = false; 13034 } catch (RuntimeException e) { 13035 // Not an integer; just do string match. 13036 if (strings == null) { 13037 strings = new ArrayList<String>(); 13038 } 13039 strings.add(name); 13040 all = false; 13041 } 13042 } 13043 } 13044 13045 int build(String[] args, int opti) { 13046 for (; opti<args.length; opti++) { 13047 String name = args[opti]; 13048 if ("--".equals(name)) { 13049 return opti+1; 13050 } 13051 build(name); 13052 } 13053 return opti; 13054 } 13055 13056 boolean match(Object object, ComponentName comp) { 13057 if (all) { 13058 return true; 13059 } 13060 if (components != null) { 13061 for (int i=0; i<components.size(); i++) { 13062 if (components.get(i).equals(comp)) { 13063 return true; 13064 } 13065 } 13066 } 13067 if (objects != null) { 13068 for (int i=0; i<objects.size(); i++) { 13069 if (System.identityHashCode(object) == objects.get(i)) { 13070 return true; 13071 } 13072 } 13073 } 13074 if (strings != null) { 13075 String flat = comp.flattenToString(); 13076 for (int i=0; i<strings.size(); i++) { 13077 if (flat.contains(strings.get(i))) { 13078 return true; 13079 } 13080 } 13081 } 13082 return false; 13083 } 13084 } 13085 13086 /** 13087 * There are three things that cmd can be: 13088 * - a flattened component name that matches an existing activity 13089 * - the cmd arg isn't the flattened component name of an existing activity: 13090 * dump all activity whose component contains the cmd as a substring 13091 * - A hex number of the ActivityRecord object instance. 13092 */ 13093 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13094 int opti, boolean dumpAll) { 13095 ArrayList<ActivityRecord> activities; 13096 13097 synchronized (this) { 13098 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13099 } 13100 13101 if (activities.size() <= 0) { 13102 return false; 13103 } 13104 13105 String[] newArgs = new String[args.length - opti]; 13106 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13107 13108 TaskRecord lastTask = null; 13109 boolean needSep = false; 13110 for (int i=activities.size()-1; i>=0; i--) { 13111 ActivityRecord r = activities.get(i); 13112 if (needSep) { 13113 pw.println(); 13114 } 13115 needSep = true; 13116 synchronized (this) { 13117 if (lastTask != r.task) { 13118 lastTask = r.task; 13119 pw.print("TASK "); pw.print(lastTask.affinity); 13120 pw.print(" id="); pw.println(lastTask.taskId); 13121 if (dumpAll) { 13122 lastTask.dump(pw, " "); 13123 } 13124 } 13125 } 13126 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13127 } 13128 return true; 13129 } 13130 13131 /** 13132 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13133 * there is a thread associated with the activity. 13134 */ 13135 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13136 final ActivityRecord r, String[] args, boolean dumpAll) { 13137 String innerPrefix = prefix + " "; 13138 synchronized (this) { 13139 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13140 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13141 pw.print(" pid="); 13142 if (r.app != null) pw.println(r.app.pid); 13143 else pw.println("(not running)"); 13144 if (dumpAll) { 13145 r.dump(pw, innerPrefix); 13146 } 13147 } 13148 if (r.app != null && r.app.thread != null) { 13149 // flush anything that is already in the PrintWriter since the thread is going 13150 // to write to the file descriptor directly 13151 pw.flush(); 13152 try { 13153 TransferPipe tp = new TransferPipe(); 13154 try { 13155 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13156 r.appToken, innerPrefix, args); 13157 tp.go(fd); 13158 } finally { 13159 tp.kill(); 13160 } 13161 } catch (IOException e) { 13162 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13163 } catch (RemoteException e) { 13164 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13165 } 13166 } 13167 } 13168 13169 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13170 int opti, boolean dumpAll, String dumpPackage) { 13171 boolean needSep = false; 13172 boolean onlyHistory = false; 13173 boolean printedAnything = false; 13174 13175 if ("history".equals(dumpPackage)) { 13176 if (opti < args.length && "-s".equals(args[opti])) { 13177 dumpAll = false; 13178 } 13179 onlyHistory = true; 13180 dumpPackage = null; 13181 } 13182 13183 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13184 if (!onlyHistory && dumpAll) { 13185 if (mRegisteredReceivers.size() > 0) { 13186 boolean printed = false; 13187 Iterator it = mRegisteredReceivers.values().iterator(); 13188 while (it.hasNext()) { 13189 ReceiverList r = (ReceiverList)it.next(); 13190 if (dumpPackage != null && (r.app == null || 13191 !dumpPackage.equals(r.app.info.packageName))) { 13192 continue; 13193 } 13194 if (!printed) { 13195 pw.println(" Registered Receivers:"); 13196 needSep = true; 13197 printed = true; 13198 printedAnything = true; 13199 } 13200 pw.print(" * "); pw.println(r); 13201 r.dump(pw, " "); 13202 } 13203 } 13204 13205 if (mReceiverResolver.dump(pw, needSep ? 13206 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13207 " ", dumpPackage, false)) { 13208 needSep = true; 13209 printedAnything = true; 13210 } 13211 } 13212 13213 for (BroadcastQueue q : mBroadcastQueues) { 13214 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13215 printedAnything |= needSep; 13216 } 13217 13218 needSep = true; 13219 13220 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13221 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13222 if (needSep) { 13223 pw.println(); 13224 } 13225 needSep = true; 13226 printedAnything = true; 13227 pw.print(" Sticky broadcasts for user "); 13228 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13229 StringBuilder sb = new StringBuilder(128); 13230 for (Map.Entry<String, ArrayList<Intent>> ent 13231 : mStickyBroadcasts.valueAt(user).entrySet()) { 13232 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13233 if (dumpAll) { 13234 pw.println(":"); 13235 ArrayList<Intent> intents = ent.getValue(); 13236 final int N = intents.size(); 13237 for (int i=0; i<N; i++) { 13238 sb.setLength(0); 13239 sb.append(" Intent: "); 13240 intents.get(i).toShortString(sb, false, true, false, false); 13241 pw.println(sb.toString()); 13242 Bundle bundle = intents.get(i).getExtras(); 13243 if (bundle != null) { 13244 pw.print(" "); 13245 pw.println(bundle.toString()); 13246 } 13247 } 13248 } else { 13249 pw.println(""); 13250 } 13251 } 13252 } 13253 } 13254 13255 if (!onlyHistory && dumpAll) { 13256 pw.println(); 13257 for (BroadcastQueue queue : mBroadcastQueues) { 13258 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13259 + queue.mBroadcastsScheduled); 13260 } 13261 pw.println(" mHandler:"); 13262 mHandler.dump(new PrintWriterPrinter(pw), " "); 13263 needSep = true; 13264 printedAnything = true; 13265 } 13266 13267 if (!printedAnything) { 13268 pw.println(" (nothing)"); 13269 } 13270 } 13271 13272 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13273 int opti, boolean dumpAll, String dumpPackage) { 13274 boolean needSep; 13275 boolean printedAnything = false; 13276 13277 ItemMatcher matcher = new ItemMatcher(); 13278 matcher.build(args, opti); 13279 13280 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13281 13282 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13283 printedAnything |= needSep; 13284 13285 if (mLaunchingProviders.size() > 0) { 13286 boolean printed = false; 13287 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13288 ContentProviderRecord r = mLaunchingProviders.get(i); 13289 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13290 continue; 13291 } 13292 if (!printed) { 13293 if (needSep) pw.println(); 13294 needSep = true; 13295 pw.println(" Launching content providers:"); 13296 printed = true; 13297 printedAnything = true; 13298 } 13299 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13300 pw.println(r); 13301 } 13302 } 13303 13304 if (mGrantedUriPermissions.size() > 0) { 13305 boolean printed = false; 13306 int dumpUid = -2; 13307 if (dumpPackage != null) { 13308 try { 13309 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13310 } catch (NameNotFoundException e) { 13311 dumpUid = -1; 13312 } 13313 } 13314 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13315 int uid = mGrantedUriPermissions.keyAt(i); 13316 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13317 continue; 13318 } 13319 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13320 if (!printed) { 13321 if (needSep) pw.println(); 13322 needSep = true; 13323 pw.println(" Granted Uri Permissions:"); 13324 printed = true; 13325 printedAnything = true; 13326 } 13327 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13328 for (UriPermission perm : perms.values()) { 13329 pw.print(" "); pw.println(perm); 13330 if (dumpAll) { 13331 perm.dump(pw, " "); 13332 } 13333 } 13334 } 13335 } 13336 13337 if (!printedAnything) { 13338 pw.println(" (nothing)"); 13339 } 13340 } 13341 13342 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13343 int opti, boolean dumpAll, String dumpPackage) { 13344 boolean printed = false; 13345 13346 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13347 13348 if (mIntentSenderRecords.size() > 0) { 13349 Iterator<WeakReference<PendingIntentRecord>> it 13350 = mIntentSenderRecords.values().iterator(); 13351 while (it.hasNext()) { 13352 WeakReference<PendingIntentRecord> ref = it.next(); 13353 PendingIntentRecord rec = ref != null ? ref.get(): null; 13354 if (dumpPackage != null && (rec == null 13355 || !dumpPackage.equals(rec.key.packageName))) { 13356 continue; 13357 } 13358 printed = true; 13359 if (rec != null) { 13360 pw.print(" * "); pw.println(rec); 13361 if (dumpAll) { 13362 rec.dump(pw, " "); 13363 } 13364 } else { 13365 pw.print(" * "); pw.println(ref); 13366 } 13367 } 13368 } 13369 13370 if (!printed) { 13371 pw.println(" (nothing)"); 13372 } 13373 } 13374 13375 private static final int dumpProcessList(PrintWriter pw, 13376 ActivityManagerService service, List list, 13377 String prefix, String normalLabel, String persistentLabel, 13378 String dumpPackage) { 13379 int numPers = 0; 13380 final int N = list.size()-1; 13381 for (int i=N; i>=0; i--) { 13382 ProcessRecord r = (ProcessRecord)list.get(i); 13383 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13384 continue; 13385 } 13386 pw.println(String.format("%s%s #%2d: %s", 13387 prefix, (r.persistent ? persistentLabel : normalLabel), 13388 i, r.toString())); 13389 if (r.persistent) { 13390 numPers++; 13391 } 13392 } 13393 return numPers; 13394 } 13395 13396 private static final boolean dumpProcessOomList(PrintWriter pw, 13397 ActivityManagerService service, List<ProcessRecord> origList, 13398 String prefix, String normalLabel, String persistentLabel, 13399 boolean inclDetails, String dumpPackage) { 13400 13401 ArrayList<Pair<ProcessRecord, Integer>> list 13402 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13403 for (int i=0; i<origList.size(); i++) { 13404 ProcessRecord r = origList.get(i); 13405 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13406 continue; 13407 } 13408 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13409 } 13410 13411 if (list.size() <= 0) { 13412 return false; 13413 } 13414 13415 Comparator<Pair<ProcessRecord, Integer>> comparator 13416 = new Comparator<Pair<ProcessRecord, Integer>>() { 13417 @Override 13418 public int compare(Pair<ProcessRecord, Integer> object1, 13419 Pair<ProcessRecord, Integer> object2) { 13420 if (object1.first.setAdj != object2.first.setAdj) { 13421 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13422 } 13423 if (object1.second.intValue() != object2.second.intValue()) { 13424 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13425 } 13426 return 0; 13427 } 13428 }; 13429 13430 Collections.sort(list, comparator); 13431 13432 final long curRealtime = SystemClock.elapsedRealtime(); 13433 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13434 final long curUptime = SystemClock.uptimeMillis(); 13435 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13436 13437 for (int i=list.size()-1; i>=0; i--) { 13438 ProcessRecord r = list.get(i).first; 13439 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13440 char schedGroup; 13441 switch (r.setSchedGroup) { 13442 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13443 schedGroup = 'B'; 13444 break; 13445 case Process.THREAD_GROUP_DEFAULT: 13446 schedGroup = 'F'; 13447 break; 13448 default: 13449 schedGroup = '?'; 13450 break; 13451 } 13452 char foreground; 13453 if (r.foregroundActivities) { 13454 foreground = 'A'; 13455 } else if (r.foregroundServices) { 13456 foreground = 'S'; 13457 } else { 13458 foreground = ' '; 13459 } 13460 String procState = ProcessList.makeProcStateString(r.curProcState); 13461 pw.print(prefix); 13462 pw.print(r.persistent ? persistentLabel : normalLabel); 13463 pw.print(" #"); 13464 int num = (origList.size()-1)-list.get(i).second; 13465 if (num < 10) pw.print(' '); 13466 pw.print(num); 13467 pw.print(": "); 13468 pw.print(oomAdj); 13469 pw.print(' '); 13470 pw.print(schedGroup); 13471 pw.print('/'); 13472 pw.print(foreground); 13473 pw.print('/'); 13474 pw.print(procState); 13475 pw.print(" trm:"); 13476 if (r.trimMemoryLevel < 10) pw.print(' '); 13477 pw.print(r.trimMemoryLevel); 13478 pw.print(' '); 13479 pw.print(r.toShortString()); 13480 pw.print(" ("); 13481 pw.print(r.adjType); 13482 pw.println(')'); 13483 if (r.adjSource != null || r.adjTarget != null) { 13484 pw.print(prefix); 13485 pw.print(" "); 13486 if (r.adjTarget instanceof ComponentName) { 13487 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13488 } else if (r.adjTarget != null) { 13489 pw.print(r.adjTarget.toString()); 13490 } else { 13491 pw.print("{null}"); 13492 } 13493 pw.print("<="); 13494 if (r.adjSource instanceof ProcessRecord) { 13495 pw.print("Proc{"); 13496 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13497 pw.println("}"); 13498 } else if (r.adjSource != null) { 13499 pw.println(r.adjSource.toString()); 13500 } else { 13501 pw.println("{null}"); 13502 } 13503 } 13504 if (inclDetails) { 13505 pw.print(prefix); 13506 pw.print(" "); 13507 pw.print("oom: max="); pw.print(r.maxAdj); 13508 pw.print(" curRaw="); pw.print(r.curRawAdj); 13509 pw.print(" setRaw="); pw.print(r.setRawAdj); 13510 pw.print(" cur="); pw.print(r.curAdj); 13511 pw.print(" set="); pw.println(r.setAdj); 13512 pw.print(prefix); 13513 pw.print(" "); 13514 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13515 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13516 pw.print(" lastPss="); pw.print(r.lastPss); 13517 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13518 pw.print(prefix); 13519 pw.print(" "); 13520 pw.print("cached="); pw.print(r.cached); 13521 pw.print(" empty="); pw.print(r.empty); 13522 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13523 13524 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13525 if (r.lastWakeTime != 0) { 13526 long wtime; 13527 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13528 synchronized (stats) { 13529 wtime = stats.getProcessWakeTime(r.info.uid, 13530 r.pid, curRealtime); 13531 } 13532 long timeUsed = wtime - r.lastWakeTime; 13533 pw.print(prefix); 13534 pw.print(" "); 13535 pw.print("keep awake over "); 13536 TimeUtils.formatDuration(realtimeSince, pw); 13537 pw.print(" used "); 13538 TimeUtils.formatDuration(timeUsed, pw); 13539 pw.print(" ("); 13540 pw.print((timeUsed*100)/realtimeSince); 13541 pw.println("%)"); 13542 } 13543 if (r.lastCpuTime != 0) { 13544 long timeUsed = r.curCpuTime - r.lastCpuTime; 13545 pw.print(prefix); 13546 pw.print(" "); 13547 pw.print("run cpu over "); 13548 TimeUtils.formatDuration(uptimeSince, pw); 13549 pw.print(" used "); 13550 TimeUtils.formatDuration(timeUsed, pw); 13551 pw.print(" ("); 13552 pw.print((timeUsed*100)/uptimeSince); 13553 pw.println("%)"); 13554 } 13555 } 13556 } 13557 } 13558 return true; 13559 } 13560 13561 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13562 String[] args) { 13563 ArrayList<ProcessRecord> procs; 13564 synchronized (this) { 13565 if (args != null && args.length > start 13566 && args[start].charAt(0) != '-') { 13567 procs = new ArrayList<ProcessRecord>(); 13568 int pid = -1; 13569 try { 13570 pid = Integer.parseInt(args[start]); 13571 } catch (NumberFormatException e) { 13572 } 13573 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13574 ProcessRecord proc = mLruProcesses.get(i); 13575 if (proc.pid == pid) { 13576 procs.add(proc); 13577 } else if (allPkgs && proc.pkgList != null 13578 && proc.pkgList.containsKey(args[start])) { 13579 procs.add(proc); 13580 } else if (proc.processName.equals(args[start])) { 13581 procs.add(proc); 13582 } 13583 } 13584 if (procs.size() <= 0) { 13585 return null; 13586 } 13587 } else { 13588 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13589 } 13590 } 13591 return procs; 13592 } 13593 13594 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13595 PrintWriter pw, String[] args) { 13596 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13597 if (procs == null) { 13598 pw.println("No process found for: " + args[0]); 13599 return; 13600 } 13601 13602 long uptime = SystemClock.uptimeMillis(); 13603 long realtime = SystemClock.elapsedRealtime(); 13604 pw.println("Applications Graphics Acceleration Info:"); 13605 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13606 13607 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13608 ProcessRecord r = procs.get(i); 13609 if (r.thread != null) { 13610 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13611 pw.flush(); 13612 try { 13613 TransferPipe tp = new TransferPipe(); 13614 try { 13615 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13616 tp.go(fd); 13617 } finally { 13618 tp.kill(); 13619 } 13620 } catch (IOException e) { 13621 pw.println("Failure while dumping the app: " + r); 13622 pw.flush(); 13623 } catch (RemoteException e) { 13624 pw.println("Got a RemoteException while dumping the app " + r); 13625 pw.flush(); 13626 } 13627 } 13628 } 13629 } 13630 13631 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13632 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13633 if (procs == null) { 13634 pw.println("No process found for: " + args[0]); 13635 return; 13636 } 13637 13638 pw.println("Applications Database Info:"); 13639 13640 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13641 ProcessRecord r = procs.get(i); 13642 if (r.thread != null) { 13643 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13644 pw.flush(); 13645 try { 13646 TransferPipe tp = new TransferPipe(); 13647 try { 13648 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13649 tp.go(fd); 13650 } finally { 13651 tp.kill(); 13652 } 13653 } catch (IOException e) { 13654 pw.println("Failure while dumping the app: " + r); 13655 pw.flush(); 13656 } catch (RemoteException e) { 13657 pw.println("Got a RemoteException while dumping the app " + r); 13658 pw.flush(); 13659 } 13660 } 13661 } 13662 } 13663 13664 final static class MemItem { 13665 final boolean isProc; 13666 final String label; 13667 final String shortLabel; 13668 final long pss; 13669 final int id; 13670 final boolean hasActivities; 13671 ArrayList<MemItem> subitems; 13672 13673 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13674 boolean _hasActivities) { 13675 isProc = true; 13676 label = _label; 13677 shortLabel = _shortLabel; 13678 pss = _pss; 13679 id = _id; 13680 hasActivities = _hasActivities; 13681 } 13682 13683 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13684 isProc = false; 13685 label = _label; 13686 shortLabel = _shortLabel; 13687 pss = _pss; 13688 id = _id; 13689 hasActivities = false; 13690 } 13691 } 13692 13693 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13694 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13695 if (sort && !isCompact) { 13696 Collections.sort(items, new Comparator<MemItem>() { 13697 @Override 13698 public int compare(MemItem lhs, MemItem rhs) { 13699 if (lhs.pss < rhs.pss) { 13700 return 1; 13701 } else if (lhs.pss > rhs.pss) { 13702 return -1; 13703 } 13704 return 0; 13705 } 13706 }); 13707 } 13708 13709 for (int i=0; i<items.size(); i++) { 13710 MemItem mi = items.get(i); 13711 if (!isCompact) { 13712 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13713 } else if (mi.isProc) { 13714 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13715 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13716 pw.println(mi.hasActivities ? ",a" : ",e"); 13717 } else { 13718 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13719 pw.println(mi.pss); 13720 } 13721 if (mi.subitems != null) { 13722 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13723 true, isCompact); 13724 } 13725 } 13726 } 13727 13728 // These are in KB. 13729 static final long[] DUMP_MEM_BUCKETS = new long[] { 13730 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13731 120*1024, 160*1024, 200*1024, 13732 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13733 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13734 }; 13735 13736 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13737 boolean stackLike) { 13738 int start = label.lastIndexOf('.'); 13739 if (start >= 0) start++; 13740 else start = 0; 13741 int end = label.length(); 13742 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13743 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13744 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13745 out.append(bucket); 13746 out.append(stackLike ? "MB." : "MB "); 13747 out.append(label, start, end); 13748 return; 13749 } 13750 } 13751 out.append(memKB/1024); 13752 out.append(stackLike ? "MB." : "MB "); 13753 out.append(label, start, end); 13754 } 13755 13756 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13757 ProcessList.NATIVE_ADJ, 13758 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13759 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13760 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13761 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13762 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13763 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13764 }; 13765 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13766 "Native", 13767 "System", "Persistent", "Persistent Service", "Foreground", 13768 "Visible", "Perceptible", 13769 "Heavy Weight", "Backup", 13770 "A Services", "Home", 13771 "Previous", "B Services", "Cached" 13772 }; 13773 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13774 "native", 13775 "sys", "pers", "persvc", "fore", 13776 "vis", "percept", 13777 "heavy", "backup", 13778 "servicea", "home", 13779 "prev", "serviceb", "cached" 13780 }; 13781 13782 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13783 long realtime, boolean isCheckinRequest, boolean isCompact) { 13784 if (isCheckinRequest || isCompact) { 13785 // short checkin version 13786 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13787 } else { 13788 pw.println("Applications Memory Usage (kB):"); 13789 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13790 } 13791 } 13792 13793 private static final int KSM_SHARED = 0; 13794 private static final int KSM_SHARING = 1; 13795 private static final int KSM_UNSHARED = 2; 13796 private static final int KSM_VOLATILE = 3; 13797 13798 private final long[] getKsmInfo() { 13799 long[] longOut = new long[4]; 13800 final int[] SINGLE_LONG_FORMAT = new int[] { 13801 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13802 }; 13803 long[] longTmp = new long[1]; 13804 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13805 SINGLE_LONG_FORMAT, null, longTmp, null); 13806 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13807 longTmp[0] = 0; 13808 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13809 SINGLE_LONG_FORMAT, null, longTmp, null); 13810 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13811 longTmp[0] = 0; 13812 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13813 SINGLE_LONG_FORMAT, null, longTmp, null); 13814 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13815 longTmp[0] = 0; 13816 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13817 SINGLE_LONG_FORMAT, null, longTmp, null); 13818 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13819 return longOut; 13820 } 13821 13822 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13823 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13824 boolean dumpDetails = false; 13825 boolean dumpFullDetails = false; 13826 boolean dumpDalvik = false; 13827 boolean oomOnly = false; 13828 boolean isCompact = false; 13829 boolean localOnly = false; 13830 boolean packages = false; 13831 13832 int opti = 0; 13833 while (opti < args.length) { 13834 String opt = args[opti]; 13835 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13836 break; 13837 } 13838 opti++; 13839 if ("-a".equals(opt)) { 13840 dumpDetails = true; 13841 dumpFullDetails = true; 13842 dumpDalvik = true; 13843 } else if ("-d".equals(opt)) { 13844 dumpDalvik = true; 13845 } else if ("-c".equals(opt)) { 13846 isCompact = true; 13847 } else if ("--oom".equals(opt)) { 13848 oomOnly = true; 13849 } else if ("--local".equals(opt)) { 13850 localOnly = true; 13851 } else if ("--package".equals(opt)) { 13852 packages = true; 13853 } else if ("-h".equals(opt)) { 13854 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13855 pw.println(" -a: include all available information for each process."); 13856 pw.println(" -d: include dalvik details when dumping process details."); 13857 pw.println(" -c: dump in a compact machine-parseable representation."); 13858 pw.println(" --oom: only show processes organized by oom adj."); 13859 pw.println(" --local: only collect details locally, don't call process."); 13860 pw.println(" --package: interpret process arg as package, dumping all"); 13861 pw.println(" processes that have loaded that package."); 13862 pw.println("If [process] is specified it can be the name or "); 13863 pw.println("pid of a specific process to dump."); 13864 return; 13865 } else { 13866 pw.println("Unknown argument: " + opt + "; use -h for help"); 13867 } 13868 } 13869 13870 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13871 long uptime = SystemClock.uptimeMillis(); 13872 long realtime = SystemClock.elapsedRealtime(); 13873 final long[] tmpLong = new long[1]; 13874 13875 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13876 if (procs == null) { 13877 // No Java processes. Maybe they want to print a native process. 13878 if (args != null && args.length > opti 13879 && args[opti].charAt(0) != '-') { 13880 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13881 = new ArrayList<ProcessCpuTracker.Stats>(); 13882 updateCpuStatsNow(); 13883 int findPid = -1; 13884 try { 13885 findPid = Integer.parseInt(args[opti]); 13886 } catch (NumberFormatException e) { 13887 } 13888 synchronized (mProcessCpuTracker) { 13889 final int N = mProcessCpuTracker.countStats(); 13890 for (int i=0; i<N; i++) { 13891 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13892 if (st.pid == findPid || (st.baseName != null 13893 && st.baseName.equals(args[opti]))) { 13894 nativeProcs.add(st); 13895 } 13896 } 13897 } 13898 if (nativeProcs.size() > 0) { 13899 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13900 isCompact); 13901 Debug.MemoryInfo mi = null; 13902 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13903 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13904 final int pid = r.pid; 13905 if (!isCheckinRequest && dumpDetails) { 13906 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13907 } 13908 if (mi == null) { 13909 mi = new Debug.MemoryInfo(); 13910 } 13911 if (dumpDetails || (!brief && !oomOnly)) { 13912 Debug.getMemoryInfo(pid, mi); 13913 } else { 13914 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13915 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13916 } 13917 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13918 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13919 if (isCheckinRequest) { 13920 pw.println(); 13921 } 13922 } 13923 return; 13924 } 13925 } 13926 pw.println("No process found for: " + args[opti]); 13927 return; 13928 } 13929 13930 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13931 dumpDetails = true; 13932 } 13933 13934 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13935 13936 String[] innerArgs = new String[args.length-opti]; 13937 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13938 13939 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13940 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13941 long nativePss = 0; 13942 long dalvikPss = 0; 13943 long otherPss = 0; 13944 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13945 13946 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13947 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13948 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13949 13950 long totalPss = 0; 13951 long cachedPss = 0; 13952 13953 Debug.MemoryInfo mi = null; 13954 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13955 final ProcessRecord r = procs.get(i); 13956 final IApplicationThread thread; 13957 final int pid; 13958 final int oomAdj; 13959 final boolean hasActivities; 13960 synchronized (this) { 13961 thread = r.thread; 13962 pid = r.pid; 13963 oomAdj = r.getSetAdjWithServices(); 13964 hasActivities = r.activities.size() > 0; 13965 } 13966 if (thread != null) { 13967 if (!isCheckinRequest && dumpDetails) { 13968 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13969 } 13970 if (mi == null) { 13971 mi = new Debug.MemoryInfo(); 13972 } 13973 if (dumpDetails || (!brief && !oomOnly)) { 13974 Debug.getMemoryInfo(pid, mi); 13975 } else { 13976 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13977 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13978 } 13979 if (dumpDetails) { 13980 if (localOnly) { 13981 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13982 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13983 if (isCheckinRequest) { 13984 pw.println(); 13985 } 13986 } else { 13987 try { 13988 pw.flush(); 13989 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13990 dumpDalvik, innerArgs); 13991 } catch (RemoteException e) { 13992 if (!isCheckinRequest) { 13993 pw.println("Got RemoteException!"); 13994 pw.flush(); 13995 } 13996 } 13997 } 13998 } 13999 14000 final long myTotalPss = mi.getTotalPss(); 14001 final long myTotalUss = mi.getTotalUss(); 14002 14003 synchronized (this) { 14004 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14005 // Record this for posterity if the process has been stable. 14006 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14007 } 14008 } 14009 14010 if (!isCheckinRequest && mi != null) { 14011 totalPss += myTotalPss; 14012 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14013 (hasActivities ? " / activities)" : ")"), 14014 r.processName, myTotalPss, pid, hasActivities); 14015 procMems.add(pssItem); 14016 procMemsMap.put(pid, pssItem); 14017 14018 nativePss += mi.nativePss; 14019 dalvikPss += mi.dalvikPss; 14020 otherPss += mi.otherPss; 14021 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14022 long mem = mi.getOtherPss(j); 14023 miscPss[j] += mem; 14024 otherPss -= mem; 14025 } 14026 14027 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14028 cachedPss += myTotalPss; 14029 } 14030 14031 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14032 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14033 || oomIndex == (oomPss.length-1)) { 14034 oomPss[oomIndex] += myTotalPss; 14035 if (oomProcs[oomIndex] == null) { 14036 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14037 } 14038 oomProcs[oomIndex].add(pssItem); 14039 break; 14040 } 14041 } 14042 } 14043 } 14044 } 14045 14046 long nativeProcTotalPss = 0; 14047 14048 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14049 // If we are showing aggregations, also look for native processes to 14050 // include so that our aggregations are more accurate. 14051 updateCpuStatsNow(); 14052 synchronized (mProcessCpuTracker) { 14053 final int N = mProcessCpuTracker.countStats(); 14054 for (int i=0; i<N; i++) { 14055 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14056 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14057 if (mi == null) { 14058 mi = new Debug.MemoryInfo(); 14059 } 14060 if (!brief && !oomOnly) { 14061 Debug.getMemoryInfo(st.pid, mi); 14062 } else { 14063 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14064 mi.nativePrivateDirty = (int)tmpLong[0]; 14065 } 14066 14067 final long myTotalPss = mi.getTotalPss(); 14068 totalPss += myTotalPss; 14069 nativeProcTotalPss += myTotalPss; 14070 14071 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14072 st.name, myTotalPss, st.pid, false); 14073 procMems.add(pssItem); 14074 14075 nativePss += mi.nativePss; 14076 dalvikPss += mi.dalvikPss; 14077 otherPss += mi.otherPss; 14078 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14079 long mem = mi.getOtherPss(j); 14080 miscPss[j] += mem; 14081 otherPss -= mem; 14082 } 14083 oomPss[0] += myTotalPss; 14084 if (oomProcs[0] == null) { 14085 oomProcs[0] = new ArrayList<MemItem>(); 14086 } 14087 oomProcs[0].add(pssItem); 14088 } 14089 } 14090 } 14091 14092 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14093 14094 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14095 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14096 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14097 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14098 String label = Debug.MemoryInfo.getOtherLabel(j); 14099 catMems.add(new MemItem(label, label, miscPss[j], j)); 14100 } 14101 14102 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14103 for (int j=0; j<oomPss.length; j++) { 14104 if (oomPss[j] != 0) { 14105 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14106 : DUMP_MEM_OOM_LABEL[j]; 14107 MemItem item = new MemItem(label, label, oomPss[j], 14108 DUMP_MEM_OOM_ADJ[j]); 14109 item.subitems = oomProcs[j]; 14110 oomMems.add(item); 14111 } 14112 } 14113 14114 if (!brief && !oomOnly && !isCompact) { 14115 pw.println(); 14116 pw.println("Total PSS by process:"); 14117 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14118 pw.println(); 14119 } 14120 if (!isCompact) { 14121 pw.println("Total PSS by OOM adjustment:"); 14122 } 14123 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14124 if (!brief && !oomOnly) { 14125 PrintWriter out = categoryPw != null ? categoryPw : pw; 14126 if (!isCompact) { 14127 out.println(); 14128 out.println("Total PSS by category:"); 14129 } 14130 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14131 } 14132 if (!isCompact) { 14133 pw.println(); 14134 } 14135 MemInfoReader memInfo = new MemInfoReader(); 14136 memInfo.readMemInfo(); 14137 if (nativeProcTotalPss > 0) { 14138 synchronized (this) { 14139 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14140 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14141 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14142 } 14143 } 14144 if (!brief) { 14145 if (!isCompact) { 14146 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14147 pw.print(" kB (status "); 14148 switch (mLastMemoryLevel) { 14149 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14150 pw.println("normal)"); 14151 break; 14152 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14153 pw.println("moderate)"); 14154 break; 14155 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14156 pw.println("low)"); 14157 break; 14158 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14159 pw.println("critical)"); 14160 break; 14161 default: 14162 pw.print(mLastMemoryLevel); 14163 pw.println(")"); 14164 break; 14165 } 14166 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14167 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14168 pw.print(cachedPss); pw.print(" cached pss + "); 14169 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14170 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14171 } else { 14172 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14173 pw.print(cachedPss + memInfo.getCachedSizeKb() 14174 + memInfo.getFreeSizeKb()); pw.print(","); 14175 pw.println(totalPss - cachedPss); 14176 } 14177 } 14178 if (!isCompact) { 14179 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14180 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14181 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14182 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14183 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14184 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14185 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14186 } 14187 if (!brief) { 14188 if (memInfo.getZramTotalSizeKb() != 0) { 14189 if (!isCompact) { 14190 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14191 pw.print(" kB physical used for "); 14192 pw.print(memInfo.getSwapTotalSizeKb() 14193 - memInfo.getSwapFreeSizeKb()); 14194 pw.print(" kB in swap ("); 14195 pw.print(memInfo.getSwapTotalSizeKb()); 14196 pw.println(" kB total swap)"); 14197 } else { 14198 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14199 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14200 pw.println(memInfo.getSwapFreeSizeKb()); 14201 } 14202 } 14203 final long[] ksm = getKsmInfo(); 14204 if (!isCompact) { 14205 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14206 || ksm[KSM_VOLATILE] != 0) { 14207 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14208 pw.print(" kB saved from shared "); 14209 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14210 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14211 pw.print(" kB unshared; "); 14212 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14213 } 14214 pw.print(" Tuning: "); 14215 pw.print(ActivityManager.staticGetMemoryClass()); 14216 pw.print(" (large "); 14217 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14218 pw.print("), oom "); 14219 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14220 pw.print(" kB"); 14221 pw.print(", restore limit "); 14222 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14223 pw.print(" kB"); 14224 if (ActivityManager.isLowRamDeviceStatic()) { 14225 pw.print(" (low-ram)"); 14226 } 14227 if (ActivityManager.isHighEndGfx()) { 14228 pw.print(" (high-end-gfx)"); 14229 } 14230 pw.println(); 14231 } else { 14232 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14233 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14234 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14235 pw.print("tuning,"); 14236 pw.print(ActivityManager.staticGetMemoryClass()); 14237 pw.print(','); 14238 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14239 pw.print(','); 14240 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14241 if (ActivityManager.isLowRamDeviceStatic()) { 14242 pw.print(",low-ram"); 14243 } 14244 if (ActivityManager.isHighEndGfx()) { 14245 pw.print(",high-end-gfx"); 14246 } 14247 pw.println(); 14248 } 14249 } 14250 } 14251 } 14252 14253 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14254 String name) { 14255 sb.append(" "); 14256 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14257 sb.append(' '); 14258 sb.append(ProcessList.makeProcStateString(procState)); 14259 sb.append(' '); 14260 ProcessList.appendRamKb(sb, pss); 14261 sb.append(" kB: "); 14262 sb.append(name); 14263 } 14264 14265 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14266 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14267 sb.append(" ("); 14268 sb.append(mi.pid); 14269 sb.append(") "); 14270 sb.append(mi.adjType); 14271 sb.append('\n'); 14272 if (mi.adjReason != null) { 14273 sb.append(" "); 14274 sb.append(mi.adjReason); 14275 sb.append('\n'); 14276 } 14277 } 14278 14279 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14280 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14281 for (int i=0, N=memInfos.size(); i<N; i++) { 14282 ProcessMemInfo mi = memInfos.get(i); 14283 infoMap.put(mi.pid, mi); 14284 } 14285 updateCpuStatsNow(); 14286 synchronized (mProcessCpuTracker) { 14287 final int N = mProcessCpuTracker.countStats(); 14288 for (int i=0; i<N; i++) { 14289 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14290 if (st.vsize > 0) { 14291 long pss = Debug.getPss(st.pid, null); 14292 if (pss > 0) { 14293 if (infoMap.indexOfKey(st.pid) < 0) { 14294 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14295 ProcessList.NATIVE_ADJ, -1, "native", null); 14296 mi.pss = pss; 14297 memInfos.add(mi); 14298 } 14299 } 14300 } 14301 } 14302 } 14303 14304 long totalPss = 0; 14305 for (int i=0, N=memInfos.size(); i<N; i++) { 14306 ProcessMemInfo mi = memInfos.get(i); 14307 if (mi.pss == 0) { 14308 mi.pss = Debug.getPss(mi.pid, null); 14309 } 14310 totalPss += mi.pss; 14311 } 14312 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14313 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14314 if (lhs.oomAdj != rhs.oomAdj) { 14315 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14316 } 14317 if (lhs.pss != rhs.pss) { 14318 return lhs.pss < rhs.pss ? 1 : -1; 14319 } 14320 return 0; 14321 } 14322 }); 14323 14324 StringBuilder tag = new StringBuilder(128); 14325 StringBuilder stack = new StringBuilder(128); 14326 tag.append("Low on memory -- "); 14327 appendMemBucket(tag, totalPss, "total", false); 14328 appendMemBucket(stack, totalPss, "total", true); 14329 14330 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14331 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14332 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14333 14334 boolean firstLine = true; 14335 int lastOomAdj = Integer.MIN_VALUE; 14336 long extraNativeRam = 0; 14337 long cachedPss = 0; 14338 for (int i=0, N=memInfos.size(); i<N; i++) { 14339 ProcessMemInfo mi = memInfos.get(i); 14340 14341 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14342 cachedPss += mi.pss; 14343 } 14344 14345 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14346 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14347 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14348 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14349 if (lastOomAdj != mi.oomAdj) { 14350 lastOomAdj = mi.oomAdj; 14351 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14352 tag.append(" / "); 14353 } 14354 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14355 if (firstLine) { 14356 stack.append(":"); 14357 firstLine = false; 14358 } 14359 stack.append("\n\t at "); 14360 } else { 14361 stack.append("$"); 14362 } 14363 } else { 14364 tag.append(" "); 14365 stack.append("$"); 14366 } 14367 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14368 appendMemBucket(tag, mi.pss, mi.name, false); 14369 } 14370 appendMemBucket(stack, mi.pss, mi.name, true); 14371 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14372 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14373 stack.append("("); 14374 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14375 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14376 stack.append(DUMP_MEM_OOM_LABEL[k]); 14377 stack.append(":"); 14378 stack.append(DUMP_MEM_OOM_ADJ[k]); 14379 } 14380 } 14381 stack.append(")"); 14382 } 14383 } 14384 14385 appendMemInfo(fullNativeBuilder, mi); 14386 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14387 // The short form only has native processes that are >= 1MB. 14388 if (mi.pss >= 1000) { 14389 appendMemInfo(shortNativeBuilder, mi); 14390 } else { 14391 extraNativeRam += mi.pss; 14392 } 14393 } else { 14394 // Short form has all other details, but if we have collected RAM 14395 // from smaller native processes let's dump a summary of that. 14396 if (extraNativeRam > 0) { 14397 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14398 -1, extraNativeRam, "(Other native)"); 14399 shortNativeBuilder.append('\n'); 14400 extraNativeRam = 0; 14401 } 14402 appendMemInfo(fullJavaBuilder, mi); 14403 } 14404 } 14405 14406 fullJavaBuilder.append(" "); 14407 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14408 fullJavaBuilder.append(" kB: TOTAL\n"); 14409 14410 MemInfoReader memInfo = new MemInfoReader(); 14411 memInfo.readMemInfo(); 14412 final long[] infos = memInfo.getRawInfo(); 14413 14414 StringBuilder memInfoBuilder = new StringBuilder(1024); 14415 Debug.getMemInfo(infos); 14416 memInfoBuilder.append(" MemInfo: "); 14417 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14418 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14419 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14420 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14421 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14422 memInfoBuilder.append(" "); 14423 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14424 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14425 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14426 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14427 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14428 memInfoBuilder.append(" ZRAM: "); 14429 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14430 memInfoBuilder.append(" kB RAM, "); 14431 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14432 memInfoBuilder.append(" kB swap total, "); 14433 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14434 memInfoBuilder.append(" kB swap free\n"); 14435 } 14436 final long[] ksm = getKsmInfo(); 14437 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14438 || ksm[KSM_VOLATILE] != 0) { 14439 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14440 memInfoBuilder.append(" kB saved from shared "); 14441 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14442 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14443 memInfoBuilder.append(" kB unshared; "); 14444 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14445 } 14446 memInfoBuilder.append(" Free RAM: "); 14447 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14448 + memInfo.getFreeSizeKb()); 14449 memInfoBuilder.append(" kB\n"); 14450 memInfoBuilder.append(" Used RAM: "); 14451 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14452 memInfoBuilder.append(" kB\n"); 14453 memInfoBuilder.append(" Lost RAM: "); 14454 memInfoBuilder.append(memInfo.getTotalSizeKb() 14455 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14456 - memInfo.getKernelUsedSizeKb()); 14457 memInfoBuilder.append(" kB\n"); 14458 Slog.i(TAG, "Low on memory:"); 14459 Slog.i(TAG, shortNativeBuilder.toString()); 14460 Slog.i(TAG, fullJavaBuilder.toString()); 14461 Slog.i(TAG, memInfoBuilder.toString()); 14462 14463 StringBuilder dropBuilder = new StringBuilder(1024); 14464 /* 14465 StringWriter oomSw = new StringWriter(); 14466 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14467 StringWriter catSw = new StringWriter(); 14468 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14469 String[] emptyArgs = new String[] { }; 14470 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14471 oomPw.flush(); 14472 String oomString = oomSw.toString(); 14473 */ 14474 dropBuilder.append("Low on memory:"); 14475 dropBuilder.append(stack); 14476 dropBuilder.append('\n'); 14477 dropBuilder.append(fullNativeBuilder); 14478 dropBuilder.append(fullJavaBuilder); 14479 dropBuilder.append('\n'); 14480 dropBuilder.append(memInfoBuilder); 14481 dropBuilder.append('\n'); 14482 /* 14483 dropBuilder.append(oomString); 14484 dropBuilder.append('\n'); 14485 */ 14486 StringWriter catSw = new StringWriter(); 14487 synchronized (ActivityManagerService.this) { 14488 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14489 String[] emptyArgs = new String[] { }; 14490 catPw.println(); 14491 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14492 catPw.println(); 14493 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14494 false, false, null); 14495 catPw.println(); 14496 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14497 catPw.flush(); 14498 } 14499 dropBuilder.append(catSw.toString()); 14500 addErrorToDropBox("lowmem", null, "system_server", null, 14501 null, tag.toString(), dropBuilder.toString(), null, null); 14502 //Slog.i(TAG, "Sent to dropbox:"); 14503 //Slog.i(TAG, dropBuilder.toString()); 14504 synchronized (ActivityManagerService.this) { 14505 long now = SystemClock.uptimeMillis(); 14506 if (mLastMemUsageReportTime < now) { 14507 mLastMemUsageReportTime = now; 14508 } 14509 } 14510 } 14511 14512 /** 14513 * Searches array of arguments for the specified string 14514 * @param args array of argument strings 14515 * @param value value to search for 14516 * @return true if the value is contained in the array 14517 */ 14518 private static boolean scanArgs(String[] args, String value) { 14519 if (args != null) { 14520 for (String arg : args) { 14521 if (value.equals(arg)) { 14522 return true; 14523 } 14524 } 14525 } 14526 return false; 14527 } 14528 14529 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14530 ContentProviderRecord cpr, boolean always) { 14531 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14532 14533 if (!inLaunching || always) { 14534 synchronized (cpr) { 14535 cpr.launchingApp = null; 14536 cpr.notifyAll(); 14537 } 14538 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14539 String names[] = cpr.info.authority.split(";"); 14540 for (int j = 0; j < names.length; j++) { 14541 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14542 } 14543 } 14544 14545 for (int i=0; i<cpr.connections.size(); i++) { 14546 ContentProviderConnection conn = cpr.connections.get(i); 14547 if (conn.waiting) { 14548 // If this connection is waiting for the provider, then we don't 14549 // need to mess with its process unless we are always removing 14550 // or for some reason the provider is not currently launching. 14551 if (inLaunching && !always) { 14552 continue; 14553 } 14554 } 14555 ProcessRecord capp = conn.client; 14556 conn.dead = true; 14557 if (conn.stableCount > 0) { 14558 if (!capp.persistent && capp.thread != null 14559 && capp.pid != 0 14560 && capp.pid != MY_PID) { 14561 capp.kill("depends on provider " 14562 + cpr.name.flattenToShortString() 14563 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14564 } 14565 } else if (capp.thread != null && conn.provider.provider != null) { 14566 try { 14567 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14568 } catch (RemoteException e) { 14569 } 14570 // In the protocol here, we don't expect the client to correctly 14571 // clean up this connection, we'll just remove it. 14572 cpr.connections.remove(i); 14573 conn.client.conProviders.remove(conn); 14574 } 14575 } 14576 14577 if (inLaunching && always) { 14578 mLaunchingProviders.remove(cpr); 14579 } 14580 return inLaunching; 14581 } 14582 14583 /** 14584 * Main code for cleaning up a process when it has gone away. This is 14585 * called both as a result of the process dying, or directly when stopping 14586 * a process when running in single process mode. 14587 * 14588 * @return Returns true if the given process has been restarted, so the 14589 * app that was passed in must remain on the process lists. 14590 */ 14591 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14592 boolean restarting, boolean allowRestart, int index) { 14593 if (index >= 0) { 14594 removeLruProcessLocked(app); 14595 ProcessList.remove(app.pid); 14596 } 14597 14598 mProcessesToGc.remove(app); 14599 mPendingPssProcesses.remove(app); 14600 14601 // Dismiss any open dialogs. 14602 if (app.crashDialog != null && !app.forceCrashReport) { 14603 app.crashDialog.dismiss(); 14604 app.crashDialog = null; 14605 } 14606 if (app.anrDialog != null) { 14607 app.anrDialog.dismiss(); 14608 app.anrDialog = null; 14609 } 14610 if (app.waitDialog != null) { 14611 app.waitDialog.dismiss(); 14612 app.waitDialog = null; 14613 } 14614 14615 app.crashing = false; 14616 app.notResponding = false; 14617 14618 app.resetPackageList(mProcessStats); 14619 app.unlinkDeathRecipient(); 14620 app.makeInactive(mProcessStats); 14621 app.waitingToKill = null; 14622 app.forcingToForeground = null; 14623 updateProcessForegroundLocked(app, false, false); 14624 app.foregroundActivities = false; 14625 app.hasShownUi = false; 14626 app.treatLikeActivity = false; 14627 app.hasAboveClient = false; 14628 app.hasClientActivities = false; 14629 14630 mServices.killServicesLocked(app, allowRestart); 14631 14632 boolean restart = false; 14633 14634 // Remove published content providers. 14635 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14636 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14637 final boolean always = app.bad || !allowRestart; 14638 if (removeDyingProviderLocked(app, cpr, always) || always) { 14639 // We left the provider in the launching list, need to 14640 // restart it. 14641 restart = true; 14642 } 14643 14644 cpr.provider = null; 14645 cpr.proc = null; 14646 } 14647 app.pubProviders.clear(); 14648 14649 // Take care of any launching providers waiting for this process. 14650 if (checkAppInLaunchingProvidersLocked(app, false)) { 14651 restart = true; 14652 } 14653 14654 // Unregister from connected content providers. 14655 if (!app.conProviders.isEmpty()) { 14656 for (int i=0; i<app.conProviders.size(); i++) { 14657 ContentProviderConnection conn = app.conProviders.get(i); 14658 conn.provider.connections.remove(conn); 14659 } 14660 app.conProviders.clear(); 14661 } 14662 14663 // At this point there may be remaining entries in mLaunchingProviders 14664 // where we were the only one waiting, so they are no longer of use. 14665 // Look for these and clean up if found. 14666 // XXX Commented out for now. Trying to figure out a way to reproduce 14667 // the actual situation to identify what is actually going on. 14668 if (false) { 14669 for (int i=0; i<mLaunchingProviders.size(); i++) { 14670 ContentProviderRecord cpr = (ContentProviderRecord) 14671 mLaunchingProviders.get(i); 14672 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14673 synchronized (cpr) { 14674 cpr.launchingApp = null; 14675 cpr.notifyAll(); 14676 } 14677 } 14678 } 14679 } 14680 14681 skipCurrentReceiverLocked(app); 14682 14683 // Unregister any receivers. 14684 for (int i=app.receivers.size()-1; i>=0; i--) { 14685 removeReceiverLocked(app.receivers.valueAt(i)); 14686 } 14687 app.receivers.clear(); 14688 14689 // If the app is undergoing backup, tell the backup manager about it 14690 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14691 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14692 + mBackupTarget.appInfo + " died during backup"); 14693 try { 14694 IBackupManager bm = IBackupManager.Stub.asInterface( 14695 ServiceManager.getService(Context.BACKUP_SERVICE)); 14696 bm.agentDisconnected(app.info.packageName); 14697 } catch (RemoteException e) { 14698 // can't happen; backup manager is local 14699 } 14700 } 14701 14702 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14703 ProcessChangeItem item = mPendingProcessChanges.get(i); 14704 if (item.pid == app.pid) { 14705 mPendingProcessChanges.remove(i); 14706 mAvailProcessChanges.add(item); 14707 } 14708 } 14709 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14710 14711 // If the caller is restarting this app, then leave it in its 14712 // current lists and let the caller take care of it. 14713 if (restarting) { 14714 return false; 14715 } 14716 14717 if (!app.persistent || app.isolated) { 14718 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14719 "Removing non-persistent process during cleanup: " + app); 14720 mProcessNames.remove(app.processName, app.uid); 14721 mIsolatedProcesses.remove(app.uid); 14722 if (mHeavyWeightProcess == app) { 14723 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14724 mHeavyWeightProcess.userId, 0)); 14725 mHeavyWeightProcess = null; 14726 } 14727 } else if (!app.removed) { 14728 // This app is persistent, so we need to keep its record around. 14729 // If it is not already on the pending app list, add it there 14730 // and start a new process for it. 14731 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14732 mPersistentStartingProcesses.add(app); 14733 restart = true; 14734 } 14735 } 14736 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14737 "Clean-up removing on hold: " + app); 14738 mProcessesOnHold.remove(app); 14739 14740 if (app == mHomeProcess) { 14741 mHomeProcess = null; 14742 } 14743 if (app == mPreviousProcess) { 14744 mPreviousProcess = null; 14745 } 14746 14747 if (restart && !app.isolated) { 14748 // We have components that still need to be running in the 14749 // process, so re-launch it. 14750 if (index < 0) { 14751 ProcessList.remove(app.pid); 14752 } 14753 mProcessNames.put(app.processName, app.uid, app); 14754 startProcessLocked(app, "restart", app.processName); 14755 return true; 14756 } else if (app.pid > 0 && app.pid != MY_PID) { 14757 // Goodbye! 14758 boolean removed; 14759 synchronized (mPidsSelfLocked) { 14760 mPidsSelfLocked.remove(app.pid); 14761 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14762 } 14763 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14764 if (app.isolated) { 14765 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14766 } 14767 app.setPid(0); 14768 } 14769 return false; 14770 } 14771 14772 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14773 // Look through the content providers we are waiting to have launched, 14774 // and if any run in this process then either schedule a restart of 14775 // the process or kill the client waiting for it if this process has 14776 // gone bad. 14777 int NL = mLaunchingProviders.size(); 14778 boolean restart = false; 14779 for (int i=0; i<NL; i++) { 14780 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14781 if (cpr.launchingApp == app) { 14782 if (!alwaysBad && !app.bad) { 14783 restart = true; 14784 } else { 14785 removeDyingProviderLocked(app, cpr, true); 14786 // cpr should have been removed from mLaunchingProviders 14787 NL = mLaunchingProviders.size(); 14788 i--; 14789 } 14790 } 14791 } 14792 return restart; 14793 } 14794 14795 // ========================================================= 14796 // SERVICES 14797 // ========================================================= 14798 14799 @Override 14800 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14801 int flags) { 14802 enforceNotIsolatedCaller("getServices"); 14803 synchronized (this) { 14804 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14805 } 14806 } 14807 14808 @Override 14809 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14810 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14811 synchronized (this) { 14812 return mServices.getRunningServiceControlPanelLocked(name); 14813 } 14814 } 14815 14816 @Override 14817 public ComponentName startService(IApplicationThread caller, Intent service, 14818 String resolvedType, int userId) { 14819 enforceNotIsolatedCaller("startService"); 14820 // Refuse possible leaked file descriptors 14821 if (service != null && service.hasFileDescriptors() == true) { 14822 throw new IllegalArgumentException("File descriptors passed in Intent"); 14823 } 14824 14825 if (DEBUG_SERVICE) 14826 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14827 synchronized(this) { 14828 final int callingPid = Binder.getCallingPid(); 14829 final int callingUid = Binder.getCallingUid(); 14830 final long origId = Binder.clearCallingIdentity(); 14831 ComponentName res = mServices.startServiceLocked(caller, service, 14832 resolvedType, callingPid, callingUid, userId); 14833 Binder.restoreCallingIdentity(origId); 14834 return res; 14835 } 14836 } 14837 14838 ComponentName startServiceInPackage(int uid, 14839 Intent service, String resolvedType, int userId) { 14840 synchronized(this) { 14841 if (DEBUG_SERVICE) 14842 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14843 final long origId = Binder.clearCallingIdentity(); 14844 ComponentName res = mServices.startServiceLocked(null, service, 14845 resolvedType, -1, uid, userId); 14846 Binder.restoreCallingIdentity(origId); 14847 return res; 14848 } 14849 } 14850 14851 @Override 14852 public int stopService(IApplicationThread caller, Intent service, 14853 String resolvedType, int userId) { 14854 enforceNotIsolatedCaller("stopService"); 14855 // Refuse possible leaked file descriptors 14856 if (service != null && service.hasFileDescriptors() == true) { 14857 throw new IllegalArgumentException("File descriptors passed in Intent"); 14858 } 14859 14860 synchronized(this) { 14861 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14862 } 14863 } 14864 14865 @Override 14866 public IBinder peekService(Intent service, String resolvedType) { 14867 enforceNotIsolatedCaller("peekService"); 14868 // Refuse possible leaked file descriptors 14869 if (service != null && service.hasFileDescriptors() == true) { 14870 throw new IllegalArgumentException("File descriptors passed in Intent"); 14871 } 14872 synchronized(this) { 14873 return mServices.peekServiceLocked(service, resolvedType); 14874 } 14875 } 14876 14877 @Override 14878 public boolean stopServiceToken(ComponentName className, IBinder token, 14879 int startId) { 14880 synchronized(this) { 14881 return mServices.stopServiceTokenLocked(className, token, startId); 14882 } 14883 } 14884 14885 @Override 14886 public void setServiceForeground(ComponentName className, IBinder token, 14887 int id, Notification notification, boolean removeNotification) { 14888 synchronized(this) { 14889 mServices.setServiceForegroundLocked(className, token, id, notification, 14890 removeNotification); 14891 } 14892 } 14893 14894 @Override 14895 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14896 boolean requireFull, String name, String callerPackage) { 14897 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14898 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14899 } 14900 14901 int unsafeConvertIncomingUser(int userId) { 14902 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14903 ? mCurrentUserId : userId; 14904 } 14905 14906 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14907 int allowMode, String name, String callerPackage) { 14908 final int callingUserId = UserHandle.getUserId(callingUid); 14909 if (callingUserId == userId) { 14910 return userId; 14911 } 14912 14913 // Note that we may be accessing mCurrentUserId outside of a lock... 14914 // shouldn't be a big deal, if this is being called outside 14915 // of a locked context there is intrinsically a race with 14916 // the value the caller will receive and someone else changing it. 14917 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14918 // we will switch to the calling user if access to the current user fails. 14919 int targetUserId = unsafeConvertIncomingUser(userId); 14920 14921 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14922 final boolean allow; 14923 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14924 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14925 // If the caller has this permission, they always pass go. And collect $200. 14926 allow = true; 14927 } else if (allowMode == ALLOW_FULL_ONLY) { 14928 // We require full access, sucks to be you. 14929 allow = false; 14930 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14931 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14932 // If the caller does not have either permission, they are always doomed. 14933 allow = false; 14934 } else if (allowMode == ALLOW_NON_FULL) { 14935 // We are blanket allowing non-full access, you lucky caller! 14936 allow = true; 14937 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14938 // We may or may not allow this depending on whether the two users are 14939 // in the same profile. 14940 synchronized (mUserProfileGroupIdsSelfLocked) { 14941 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14942 UserInfo.NO_PROFILE_GROUP_ID); 14943 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14944 UserInfo.NO_PROFILE_GROUP_ID); 14945 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14946 && callingProfile == targetProfile; 14947 } 14948 } else { 14949 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14950 } 14951 if (!allow) { 14952 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14953 // In this case, they would like to just execute as their 14954 // owner user instead of failing. 14955 targetUserId = callingUserId; 14956 } else { 14957 StringBuilder builder = new StringBuilder(128); 14958 builder.append("Permission Denial: "); 14959 builder.append(name); 14960 if (callerPackage != null) { 14961 builder.append(" from "); 14962 builder.append(callerPackage); 14963 } 14964 builder.append(" asks to run as user "); 14965 builder.append(userId); 14966 builder.append(" but is calling from user "); 14967 builder.append(UserHandle.getUserId(callingUid)); 14968 builder.append("; this requires "); 14969 builder.append(INTERACT_ACROSS_USERS_FULL); 14970 if (allowMode != ALLOW_FULL_ONLY) { 14971 builder.append(" or "); 14972 builder.append(INTERACT_ACROSS_USERS); 14973 } 14974 String msg = builder.toString(); 14975 Slog.w(TAG, msg); 14976 throw new SecurityException(msg); 14977 } 14978 } 14979 } 14980 if (!allowAll && targetUserId < 0) { 14981 throw new IllegalArgumentException( 14982 "Call does not support special user #" + targetUserId); 14983 } 14984 // Check shell permission 14985 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14986 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14987 targetUserId)) { 14988 throw new SecurityException("Shell does not have permission to access user " 14989 + targetUserId + "\n " + Debug.getCallers(3)); 14990 } 14991 } 14992 return targetUserId; 14993 } 14994 14995 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14996 String className, int flags) { 14997 boolean result = false; 14998 // For apps that don't have pre-defined UIDs, check for permission 14999 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15000 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15001 if (ActivityManager.checkUidPermission( 15002 INTERACT_ACROSS_USERS, 15003 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15004 ComponentName comp = new ComponentName(aInfo.packageName, className); 15005 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15006 + " requests FLAG_SINGLE_USER, but app does not hold " 15007 + INTERACT_ACROSS_USERS; 15008 Slog.w(TAG, msg); 15009 throw new SecurityException(msg); 15010 } 15011 // Permission passed 15012 result = true; 15013 } 15014 } else if ("system".equals(componentProcessName)) { 15015 result = true; 15016 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15017 // Phone app and persistent apps are allowed to export singleuser providers. 15018 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15019 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15020 } 15021 if (DEBUG_MU) { 15022 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15023 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15024 } 15025 return result; 15026 } 15027 15028 /** 15029 * Checks to see if the caller is in the same app as the singleton 15030 * component, or the component is in a special app. It allows special apps 15031 * to export singleton components but prevents exporting singleton 15032 * components for regular apps. 15033 */ 15034 boolean isValidSingletonCall(int callingUid, int componentUid) { 15035 int componentAppId = UserHandle.getAppId(componentUid); 15036 return UserHandle.isSameApp(callingUid, componentUid) 15037 || componentAppId == Process.SYSTEM_UID 15038 || componentAppId == Process.PHONE_UID 15039 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15040 == PackageManager.PERMISSION_GRANTED; 15041 } 15042 15043 public int bindService(IApplicationThread caller, IBinder token, 15044 Intent service, String resolvedType, 15045 IServiceConnection connection, int flags, int userId) { 15046 enforceNotIsolatedCaller("bindService"); 15047 15048 // Refuse possible leaked file descriptors 15049 if (service != null && service.hasFileDescriptors() == true) { 15050 throw new IllegalArgumentException("File descriptors passed in Intent"); 15051 } 15052 15053 synchronized(this) { 15054 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15055 connection, flags, userId); 15056 } 15057 } 15058 15059 public boolean unbindService(IServiceConnection connection) { 15060 synchronized (this) { 15061 return mServices.unbindServiceLocked(connection); 15062 } 15063 } 15064 15065 public void publishService(IBinder token, Intent intent, IBinder service) { 15066 // Refuse possible leaked file descriptors 15067 if (intent != null && intent.hasFileDescriptors() == true) { 15068 throw new IllegalArgumentException("File descriptors passed in Intent"); 15069 } 15070 15071 synchronized(this) { 15072 if (!(token instanceof ServiceRecord)) { 15073 throw new IllegalArgumentException("Invalid service token"); 15074 } 15075 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15076 } 15077 } 15078 15079 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15080 // Refuse possible leaked file descriptors 15081 if (intent != null && intent.hasFileDescriptors() == true) { 15082 throw new IllegalArgumentException("File descriptors passed in Intent"); 15083 } 15084 15085 synchronized(this) { 15086 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15087 } 15088 } 15089 15090 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15091 synchronized(this) { 15092 if (!(token instanceof ServiceRecord)) { 15093 throw new IllegalArgumentException("Invalid service token"); 15094 } 15095 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15096 } 15097 } 15098 15099 // ========================================================= 15100 // BACKUP AND RESTORE 15101 // ========================================================= 15102 15103 // Cause the target app to be launched if necessary and its backup agent 15104 // instantiated. The backup agent will invoke backupAgentCreated() on the 15105 // activity manager to announce its creation. 15106 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15107 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15108 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15109 15110 synchronized(this) { 15111 // !!! TODO: currently no check here that we're already bound 15112 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15113 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15114 synchronized (stats) { 15115 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15116 } 15117 15118 // Backup agent is now in use, its package can't be stopped. 15119 try { 15120 AppGlobals.getPackageManager().setPackageStoppedState( 15121 app.packageName, false, UserHandle.getUserId(app.uid)); 15122 } catch (RemoteException e) { 15123 } catch (IllegalArgumentException e) { 15124 Slog.w(TAG, "Failed trying to unstop package " 15125 + app.packageName + ": " + e); 15126 } 15127 15128 BackupRecord r = new BackupRecord(ss, app, backupMode); 15129 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15130 ? new ComponentName(app.packageName, app.backupAgentName) 15131 : new ComponentName("android", "FullBackupAgent"); 15132 // startProcessLocked() returns existing proc's record if it's already running 15133 ProcessRecord proc = startProcessLocked(app.processName, app, 15134 false, 0, "backup", hostingName, false, false, false); 15135 if (proc == null) { 15136 Slog.e(TAG, "Unable to start backup agent process " + r); 15137 return false; 15138 } 15139 15140 r.app = proc; 15141 mBackupTarget = r; 15142 mBackupAppName = app.packageName; 15143 15144 // Try not to kill the process during backup 15145 updateOomAdjLocked(proc); 15146 15147 // If the process is already attached, schedule the creation of the backup agent now. 15148 // If it is not yet live, this will be done when it attaches to the framework. 15149 if (proc.thread != null) { 15150 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15151 try { 15152 proc.thread.scheduleCreateBackupAgent(app, 15153 compatibilityInfoForPackageLocked(app), backupMode); 15154 } catch (RemoteException e) { 15155 // Will time out on the backup manager side 15156 } 15157 } else { 15158 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15159 } 15160 // Invariants: at this point, the target app process exists and the application 15161 // is either already running or in the process of coming up. mBackupTarget and 15162 // mBackupAppName describe the app, so that when it binds back to the AM we 15163 // know that it's scheduled for a backup-agent operation. 15164 } 15165 15166 return true; 15167 } 15168 15169 @Override 15170 public void clearPendingBackup() { 15171 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15172 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15173 15174 synchronized (this) { 15175 mBackupTarget = null; 15176 mBackupAppName = null; 15177 } 15178 } 15179 15180 // A backup agent has just come up 15181 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15182 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15183 + " = " + agent); 15184 15185 synchronized(this) { 15186 if (!agentPackageName.equals(mBackupAppName)) { 15187 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15188 return; 15189 } 15190 } 15191 15192 long oldIdent = Binder.clearCallingIdentity(); 15193 try { 15194 IBackupManager bm = IBackupManager.Stub.asInterface( 15195 ServiceManager.getService(Context.BACKUP_SERVICE)); 15196 bm.agentConnected(agentPackageName, agent); 15197 } catch (RemoteException e) { 15198 // can't happen; the backup manager service is local 15199 } catch (Exception e) { 15200 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15201 e.printStackTrace(); 15202 } finally { 15203 Binder.restoreCallingIdentity(oldIdent); 15204 } 15205 } 15206 15207 // done with this agent 15208 public void unbindBackupAgent(ApplicationInfo appInfo) { 15209 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15210 if (appInfo == null) { 15211 Slog.w(TAG, "unbind backup agent for null app"); 15212 return; 15213 } 15214 15215 synchronized(this) { 15216 try { 15217 if (mBackupAppName == null) { 15218 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15219 return; 15220 } 15221 15222 if (!mBackupAppName.equals(appInfo.packageName)) { 15223 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15224 return; 15225 } 15226 15227 // Not backing this app up any more; reset its OOM adjustment 15228 final ProcessRecord proc = mBackupTarget.app; 15229 updateOomAdjLocked(proc); 15230 15231 // If the app crashed during backup, 'thread' will be null here 15232 if (proc.thread != null) { 15233 try { 15234 proc.thread.scheduleDestroyBackupAgent(appInfo, 15235 compatibilityInfoForPackageLocked(appInfo)); 15236 } catch (Exception e) { 15237 Slog.e(TAG, "Exception when unbinding backup agent:"); 15238 e.printStackTrace(); 15239 } 15240 } 15241 } finally { 15242 mBackupTarget = null; 15243 mBackupAppName = null; 15244 } 15245 } 15246 } 15247 // ========================================================= 15248 // BROADCASTS 15249 // ========================================================= 15250 15251 private final List getStickiesLocked(String action, IntentFilter filter, 15252 List cur, int userId) { 15253 final ContentResolver resolver = mContext.getContentResolver(); 15254 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15255 if (stickies == null) { 15256 return cur; 15257 } 15258 final ArrayList<Intent> list = stickies.get(action); 15259 if (list == null) { 15260 return cur; 15261 } 15262 int N = list.size(); 15263 for (int i=0; i<N; i++) { 15264 Intent intent = list.get(i); 15265 if (filter.match(resolver, intent, true, TAG) >= 0) { 15266 if (cur == null) { 15267 cur = new ArrayList<Intent>(); 15268 } 15269 cur.add(intent); 15270 } 15271 } 15272 return cur; 15273 } 15274 15275 boolean isPendingBroadcastProcessLocked(int pid) { 15276 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15277 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15278 } 15279 15280 void skipPendingBroadcastLocked(int pid) { 15281 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15282 for (BroadcastQueue queue : mBroadcastQueues) { 15283 queue.skipPendingBroadcastLocked(pid); 15284 } 15285 } 15286 15287 // The app just attached; send any pending broadcasts that it should receive 15288 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15289 boolean didSomething = false; 15290 for (BroadcastQueue queue : mBroadcastQueues) { 15291 didSomething |= queue.sendPendingBroadcastsLocked(app); 15292 } 15293 return didSomething; 15294 } 15295 15296 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15297 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15298 enforceNotIsolatedCaller("registerReceiver"); 15299 int callingUid; 15300 int callingPid; 15301 synchronized(this) { 15302 ProcessRecord callerApp = null; 15303 if (caller != null) { 15304 callerApp = getRecordForAppLocked(caller); 15305 if (callerApp == null) { 15306 throw new SecurityException( 15307 "Unable to find app for caller " + caller 15308 + " (pid=" + Binder.getCallingPid() 15309 + ") when registering receiver " + receiver); 15310 } 15311 if (callerApp.info.uid != Process.SYSTEM_UID && 15312 !callerApp.pkgList.containsKey(callerPackage) && 15313 !"android".equals(callerPackage)) { 15314 throw new SecurityException("Given caller package " + callerPackage 15315 + " is not running in process " + callerApp); 15316 } 15317 callingUid = callerApp.info.uid; 15318 callingPid = callerApp.pid; 15319 } else { 15320 callerPackage = null; 15321 callingUid = Binder.getCallingUid(); 15322 callingPid = Binder.getCallingPid(); 15323 } 15324 15325 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15326 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15327 15328 List allSticky = null; 15329 15330 // Look for any matching sticky broadcasts... 15331 Iterator actions = filter.actionsIterator(); 15332 if (actions != null) { 15333 while (actions.hasNext()) { 15334 String action = (String)actions.next(); 15335 allSticky = getStickiesLocked(action, filter, allSticky, 15336 UserHandle.USER_ALL); 15337 allSticky = getStickiesLocked(action, filter, allSticky, 15338 UserHandle.getUserId(callingUid)); 15339 } 15340 } else { 15341 allSticky = getStickiesLocked(null, filter, allSticky, 15342 UserHandle.USER_ALL); 15343 allSticky = getStickiesLocked(null, filter, allSticky, 15344 UserHandle.getUserId(callingUid)); 15345 } 15346 15347 // The first sticky in the list is returned directly back to 15348 // the client. 15349 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15350 15351 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15352 + ": " + sticky); 15353 15354 if (receiver == null) { 15355 return sticky; 15356 } 15357 15358 ReceiverList rl 15359 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15360 if (rl == null) { 15361 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15362 userId, receiver); 15363 if (rl.app != null) { 15364 rl.app.receivers.add(rl); 15365 } else { 15366 try { 15367 receiver.asBinder().linkToDeath(rl, 0); 15368 } catch (RemoteException e) { 15369 return sticky; 15370 } 15371 rl.linkedToDeath = true; 15372 } 15373 mRegisteredReceivers.put(receiver.asBinder(), rl); 15374 } else if (rl.uid != callingUid) { 15375 throw new IllegalArgumentException( 15376 "Receiver requested to register for uid " + callingUid 15377 + " was previously registered for uid " + rl.uid); 15378 } else if (rl.pid != callingPid) { 15379 throw new IllegalArgumentException( 15380 "Receiver requested to register for pid " + callingPid 15381 + " was previously registered for pid " + rl.pid); 15382 } else if (rl.userId != userId) { 15383 throw new IllegalArgumentException( 15384 "Receiver requested to register for user " + userId 15385 + " was previously registered for user " + rl.userId); 15386 } 15387 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15388 permission, callingUid, userId); 15389 rl.add(bf); 15390 if (!bf.debugCheck()) { 15391 Slog.w(TAG, "==> For Dynamic broadast"); 15392 } 15393 mReceiverResolver.addFilter(bf); 15394 15395 // Enqueue broadcasts for all existing stickies that match 15396 // this filter. 15397 if (allSticky != null) { 15398 ArrayList receivers = new ArrayList(); 15399 receivers.add(bf); 15400 15401 int N = allSticky.size(); 15402 for (int i=0; i<N; i++) { 15403 Intent intent = (Intent)allSticky.get(i); 15404 BroadcastQueue queue = broadcastQueueForIntent(intent); 15405 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15406 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15407 null, null, false, true, true, -1); 15408 queue.enqueueParallelBroadcastLocked(r); 15409 queue.scheduleBroadcastsLocked(); 15410 } 15411 } 15412 15413 return sticky; 15414 } 15415 } 15416 15417 public void unregisterReceiver(IIntentReceiver receiver) { 15418 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15419 15420 final long origId = Binder.clearCallingIdentity(); 15421 try { 15422 boolean doTrim = false; 15423 15424 synchronized(this) { 15425 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15426 if (rl != null) { 15427 if (rl.curBroadcast != null) { 15428 BroadcastRecord r = rl.curBroadcast; 15429 final boolean doNext = finishReceiverLocked( 15430 receiver.asBinder(), r.resultCode, r.resultData, 15431 r.resultExtras, r.resultAbort); 15432 if (doNext) { 15433 doTrim = true; 15434 r.queue.processNextBroadcast(false); 15435 } 15436 } 15437 15438 if (rl.app != null) { 15439 rl.app.receivers.remove(rl); 15440 } 15441 removeReceiverLocked(rl); 15442 if (rl.linkedToDeath) { 15443 rl.linkedToDeath = false; 15444 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15445 } 15446 } 15447 } 15448 15449 // If we actually concluded any broadcasts, we might now be able 15450 // to trim the recipients' apps from our working set 15451 if (doTrim) { 15452 trimApplications(); 15453 return; 15454 } 15455 15456 } finally { 15457 Binder.restoreCallingIdentity(origId); 15458 } 15459 } 15460 15461 void removeReceiverLocked(ReceiverList rl) { 15462 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15463 int N = rl.size(); 15464 for (int i=0; i<N; i++) { 15465 mReceiverResolver.removeFilter(rl.get(i)); 15466 } 15467 } 15468 15469 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15470 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15471 ProcessRecord r = mLruProcesses.get(i); 15472 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15473 try { 15474 r.thread.dispatchPackageBroadcast(cmd, packages); 15475 } catch (RemoteException ex) { 15476 } 15477 } 15478 } 15479 } 15480 15481 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15482 int callingUid, int[] users) { 15483 List<ResolveInfo> receivers = null; 15484 try { 15485 HashSet<ComponentName> singleUserReceivers = null; 15486 boolean scannedFirstReceivers = false; 15487 for (int user : users) { 15488 // Skip users that have Shell restrictions 15489 if (callingUid == Process.SHELL_UID 15490 && getUserManagerLocked().hasUserRestriction( 15491 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15492 continue; 15493 } 15494 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15495 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15496 if (user != 0 && newReceivers != null) { 15497 // If this is not the primary user, we need to check for 15498 // any receivers that should be filtered out. 15499 for (int i=0; i<newReceivers.size(); i++) { 15500 ResolveInfo ri = newReceivers.get(i); 15501 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15502 newReceivers.remove(i); 15503 i--; 15504 } 15505 } 15506 } 15507 if (newReceivers != null && newReceivers.size() == 0) { 15508 newReceivers = null; 15509 } 15510 if (receivers == null) { 15511 receivers = newReceivers; 15512 } else if (newReceivers != null) { 15513 // We need to concatenate the additional receivers 15514 // found with what we have do far. This would be easy, 15515 // but we also need to de-dup any receivers that are 15516 // singleUser. 15517 if (!scannedFirstReceivers) { 15518 // Collect any single user receivers we had already retrieved. 15519 scannedFirstReceivers = true; 15520 for (int i=0; i<receivers.size(); i++) { 15521 ResolveInfo ri = receivers.get(i); 15522 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15523 ComponentName cn = new ComponentName( 15524 ri.activityInfo.packageName, ri.activityInfo.name); 15525 if (singleUserReceivers == null) { 15526 singleUserReceivers = new HashSet<ComponentName>(); 15527 } 15528 singleUserReceivers.add(cn); 15529 } 15530 } 15531 } 15532 // Add the new results to the existing results, tracking 15533 // and de-dupping single user receivers. 15534 for (int i=0; i<newReceivers.size(); i++) { 15535 ResolveInfo ri = newReceivers.get(i); 15536 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15537 ComponentName cn = new ComponentName( 15538 ri.activityInfo.packageName, ri.activityInfo.name); 15539 if (singleUserReceivers == null) { 15540 singleUserReceivers = new HashSet<ComponentName>(); 15541 } 15542 if (!singleUserReceivers.contains(cn)) { 15543 singleUserReceivers.add(cn); 15544 receivers.add(ri); 15545 } 15546 } else { 15547 receivers.add(ri); 15548 } 15549 } 15550 } 15551 } 15552 } catch (RemoteException ex) { 15553 // pm is in same process, this will never happen. 15554 } 15555 return receivers; 15556 } 15557 15558 private final int broadcastIntentLocked(ProcessRecord callerApp, 15559 String callerPackage, Intent intent, String resolvedType, 15560 IIntentReceiver resultTo, int resultCode, String resultData, 15561 Bundle map, String requiredPermission, int appOp, 15562 boolean ordered, boolean sticky, int callingPid, int callingUid, 15563 int userId) { 15564 intent = new Intent(intent); 15565 15566 // By default broadcasts do not go to stopped apps. 15567 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15568 15569 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15570 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15571 + " ordered=" + ordered + " userid=" + userId); 15572 if ((resultTo != null) && !ordered) { 15573 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15574 } 15575 15576 userId = handleIncomingUser(callingPid, callingUid, userId, 15577 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15578 15579 // Make sure that the user who is receiving this broadcast is started. 15580 // If not, we will just skip it. 15581 15582 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15583 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15584 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15585 Slog.w(TAG, "Skipping broadcast of " + intent 15586 + ": user " + userId + " is stopped"); 15587 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15588 } 15589 } 15590 15591 /* 15592 * Prevent non-system code (defined here to be non-persistent 15593 * processes) from sending protected broadcasts. 15594 */ 15595 int callingAppId = UserHandle.getAppId(callingUid); 15596 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15597 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15598 || callingAppId == Process.NFC_UID || callingUid == 0) { 15599 // Always okay. 15600 } else if (callerApp == null || !callerApp.persistent) { 15601 try { 15602 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15603 intent.getAction())) { 15604 String msg = "Permission Denial: not allowed to send broadcast " 15605 + intent.getAction() + " from pid=" 15606 + callingPid + ", uid=" + callingUid; 15607 Slog.w(TAG, msg); 15608 throw new SecurityException(msg); 15609 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15610 // Special case for compatibility: we don't want apps to send this, 15611 // but historically it has not been protected and apps may be using it 15612 // to poke their own app widget. So, instead of making it protected, 15613 // just limit it to the caller. 15614 if (callerApp == null) { 15615 String msg = "Permission Denial: not allowed to send broadcast " 15616 + intent.getAction() + " from unknown caller."; 15617 Slog.w(TAG, msg); 15618 throw new SecurityException(msg); 15619 } else if (intent.getComponent() != null) { 15620 // They are good enough to send to an explicit component... verify 15621 // it is being sent to the calling app. 15622 if (!intent.getComponent().getPackageName().equals( 15623 callerApp.info.packageName)) { 15624 String msg = "Permission Denial: not allowed to send broadcast " 15625 + intent.getAction() + " to " 15626 + intent.getComponent().getPackageName() + " from " 15627 + callerApp.info.packageName; 15628 Slog.w(TAG, msg); 15629 throw new SecurityException(msg); 15630 } 15631 } else { 15632 // Limit broadcast to their own package. 15633 intent.setPackage(callerApp.info.packageName); 15634 } 15635 } 15636 } catch (RemoteException e) { 15637 Slog.w(TAG, "Remote exception", e); 15638 return ActivityManager.BROADCAST_SUCCESS; 15639 } 15640 } 15641 15642 final String action = intent.getAction(); 15643 if (action != null) { 15644 switch (action) { 15645 case Intent.ACTION_UID_REMOVED: 15646 case Intent.ACTION_PACKAGE_REMOVED: 15647 case Intent.ACTION_PACKAGE_CHANGED: 15648 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15649 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15650 // Handle special intents: if this broadcast is from the package 15651 // manager about a package being removed, we need to remove all of 15652 // its activities from the history stack. 15653 if (checkComponentPermission( 15654 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15655 callingPid, callingUid, -1, true) 15656 != PackageManager.PERMISSION_GRANTED) { 15657 String msg = "Permission Denial: " + intent.getAction() 15658 + " broadcast from " + callerPackage + " (pid=" + callingPid 15659 + ", uid=" + callingUid + ")" 15660 + " requires " 15661 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15662 Slog.w(TAG, msg); 15663 throw new SecurityException(msg); 15664 } 15665 switch (action) { 15666 case Intent.ACTION_UID_REMOVED: 15667 final Bundle intentExtras = intent.getExtras(); 15668 final int uid = intentExtras != null 15669 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15670 if (uid >= 0) { 15671 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15672 synchronized (bs) { 15673 bs.removeUidStatsLocked(uid); 15674 } 15675 mAppOpsService.uidRemoved(uid); 15676 } 15677 break; 15678 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15679 // If resources are unavailable just force stop all those packages 15680 // and flush the attribute cache as well. 15681 String list[] = 15682 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15683 if (list != null && list.length > 0) { 15684 for (int i = 0; i < list.length; i++) { 15685 forceStopPackageLocked(list[i], -1, false, true, true, 15686 false, false, userId, "storage unmount"); 15687 } 15688 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15689 sendPackageBroadcastLocked( 15690 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15691 userId); 15692 } 15693 break; 15694 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15695 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15696 break; 15697 case Intent.ACTION_PACKAGE_REMOVED: 15698 case Intent.ACTION_PACKAGE_CHANGED: 15699 Uri data = intent.getData(); 15700 String ssp; 15701 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15702 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15703 boolean fullUninstall = removed && 15704 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15705 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15706 forceStopPackageLocked(ssp, UserHandle.getAppId( 15707 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15708 false, true, true, false, fullUninstall, userId, 15709 removed ? "pkg removed" : "pkg changed"); 15710 } 15711 if (removed) { 15712 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15713 new String[] {ssp}, userId); 15714 if (fullUninstall) { 15715 mAppOpsService.packageRemoved( 15716 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15717 15718 // Remove all permissions granted from/to this package 15719 removeUriPermissionsForPackageLocked(ssp, userId, true); 15720 15721 removeTasksByPackageNameLocked(ssp, userId); 15722 } 15723 } else { 15724 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15725 } 15726 } 15727 break; 15728 } 15729 break; 15730 case Intent.ACTION_PACKAGE_ADDED: 15731 // Special case for adding a package: by default turn on compatibility mode. 15732 Uri data = intent.getData(); 15733 String ssp; 15734 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15735 final boolean replacing = 15736 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15737 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15738 15739 if (replacing) { 15740 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15741 } 15742 } 15743 break; 15744 case Intent.ACTION_TIMEZONE_CHANGED: 15745 // If this is the time zone changed action, queue up a message that will reset 15746 // the timezone of all currently running processes. This message will get 15747 // queued up before the broadcast happens. 15748 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15749 break; 15750 case Intent.ACTION_TIME_CHANGED: 15751 // If the user set the time, let all running processes know. 15752 final int is24Hour = 15753 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15754 : 0; 15755 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15756 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15757 synchronized (stats) { 15758 stats.noteCurrentTimeChangedLocked(); 15759 } 15760 break; 15761 case Intent.ACTION_CLEAR_DNS_CACHE: 15762 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15763 break; 15764 case Proxy.PROXY_CHANGE_ACTION: 15765 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15766 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15767 break; 15768 } 15769 } 15770 15771 // Add to the sticky list if requested. 15772 if (sticky) { 15773 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15774 callingPid, callingUid) 15775 != PackageManager.PERMISSION_GRANTED) { 15776 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15777 + callingPid + ", uid=" + callingUid 15778 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15779 Slog.w(TAG, msg); 15780 throw new SecurityException(msg); 15781 } 15782 if (requiredPermission != null) { 15783 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15784 + " and enforce permission " + requiredPermission); 15785 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15786 } 15787 if (intent.getComponent() != null) { 15788 throw new SecurityException( 15789 "Sticky broadcasts can't target a specific component"); 15790 } 15791 // We use userId directly here, since the "all" target is maintained 15792 // as a separate set of sticky broadcasts. 15793 if (userId != UserHandle.USER_ALL) { 15794 // But first, if this is not a broadcast to all users, then 15795 // make sure it doesn't conflict with an existing broadcast to 15796 // all users. 15797 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15798 UserHandle.USER_ALL); 15799 if (stickies != null) { 15800 ArrayList<Intent> list = stickies.get(intent.getAction()); 15801 if (list != null) { 15802 int N = list.size(); 15803 int i; 15804 for (i=0; i<N; i++) { 15805 if (intent.filterEquals(list.get(i))) { 15806 throw new IllegalArgumentException( 15807 "Sticky broadcast " + intent + " for user " 15808 + userId + " conflicts with existing global broadcast"); 15809 } 15810 } 15811 } 15812 } 15813 } 15814 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15815 if (stickies == null) { 15816 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15817 mStickyBroadcasts.put(userId, stickies); 15818 } 15819 ArrayList<Intent> list = stickies.get(intent.getAction()); 15820 if (list == null) { 15821 list = new ArrayList<Intent>(); 15822 stickies.put(intent.getAction(), list); 15823 } 15824 int N = list.size(); 15825 int i; 15826 for (i=0; i<N; i++) { 15827 if (intent.filterEquals(list.get(i))) { 15828 // This sticky already exists, replace it. 15829 list.set(i, new Intent(intent)); 15830 break; 15831 } 15832 } 15833 if (i >= N) { 15834 list.add(new Intent(intent)); 15835 } 15836 } 15837 15838 int[] users; 15839 if (userId == UserHandle.USER_ALL) { 15840 // Caller wants broadcast to go to all started users. 15841 users = mStartedUserArray; 15842 } else { 15843 // Caller wants broadcast to go to one specific user. 15844 users = new int[] {userId}; 15845 } 15846 15847 // Figure out who all will receive this broadcast. 15848 List receivers = null; 15849 List<BroadcastFilter> registeredReceivers = null; 15850 // Need to resolve the intent to interested receivers... 15851 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15852 == 0) { 15853 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15854 } 15855 if (intent.getComponent() == null) { 15856 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15857 // Query one target user at a time, excluding shell-restricted users 15858 UserManagerService ums = getUserManagerLocked(); 15859 for (int i = 0; i < users.length; i++) { 15860 if (ums.hasUserRestriction( 15861 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15862 continue; 15863 } 15864 List<BroadcastFilter> registeredReceiversForUser = 15865 mReceiverResolver.queryIntent(intent, 15866 resolvedType, false, users[i]); 15867 if (registeredReceivers == null) { 15868 registeredReceivers = registeredReceiversForUser; 15869 } else if (registeredReceiversForUser != null) { 15870 registeredReceivers.addAll(registeredReceiversForUser); 15871 } 15872 } 15873 } else { 15874 registeredReceivers = mReceiverResolver.queryIntent(intent, 15875 resolvedType, false, userId); 15876 } 15877 } 15878 15879 final boolean replacePending = 15880 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15881 15882 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15883 + " replacePending=" + replacePending); 15884 15885 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15886 if (!ordered && NR > 0) { 15887 // If we are not serializing this broadcast, then send the 15888 // registered receivers separately so they don't wait for the 15889 // components to be launched. 15890 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15891 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15892 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15893 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15894 ordered, sticky, false, userId); 15895 if (DEBUG_BROADCAST) Slog.v( 15896 TAG, "Enqueueing parallel broadcast " + r); 15897 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15898 if (!replaced) { 15899 queue.enqueueParallelBroadcastLocked(r); 15900 queue.scheduleBroadcastsLocked(); 15901 } 15902 registeredReceivers = null; 15903 NR = 0; 15904 } 15905 15906 // Merge into one list. 15907 int ir = 0; 15908 if (receivers != null) { 15909 // A special case for PACKAGE_ADDED: do not allow the package 15910 // being added to see this broadcast. This prevents them from 15911 // using this as a back door to get run as soon as they are 15912 // installed. Maybe in the future we want to have a special install 15913 // broadcast or such for apps, but we'd like to deliberately make 15914 // this decision. 15915 String skipPackages[] = null; 15916 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15917 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15918 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15919 Uri data = intent.getData(); 15920 if (data != null) { 15921 String pkgName = data.getSchemeSpecificPart(); 15922 if (pkgName != null) { 15923 skipPackages = new String[] { pkgName }; 15924 } 15925 } 15926 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15927 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15928 } 15929 if (skipPackages != null && (skipPackages.length > 0)) { 15930 for (String skipPackage : skipPackages) { 15931 if (skipPackage != null) { 15932 int NT = receivers.size(); 15933 for (int it=0; it<NT; it++) { 15934 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15935 if (curt.activityInfo.packageName.equals(skipPackage)) { 15936 receivers.remove(it); 15937 it--; 15938 NT--; 15939 } 15940 } 15941 } 15942 } 15943 } 15944 15945 int NT = receivers != null ? receivers.size() : 0; 15946 int it = 0; 15947 ResolveInfo curt = null; 15948 BroadcastFilter curr = null; 15949 while (it < NT && ir < NR) { 15950 if (curt == null) { 15951 curt = (ResolveInfo)receivers.get(it); 15952 } 15953 if (curr == null) { 15954 curr = registeredReceivers.get(ir); 15955 } 15956 if (curr.getPriority() >= curt.priority) { 15957 // Insert this broadcast record into the final list. 15958 receivers.add(it, curr); 15959 ir++; 15960 curr = null; 15961 it++; 15962 NT++; 15963 } else { 15964 // Skip to the next ResolveInfo in the final list. 15965 it++; 15966 curt = null; 15967 } 15968 } 15969 } 15970 while (ir < NR) { 15971 if (receivers == null) { 15972 receivers = new ArrayList(); 15973 } 15974 receivers.add(registeredReceivers.get(ir)); 15975 ir++; 15976 } 15977 15978 if ((receivers != null && receivers.size() > 0) 15979 || resultTo != null) { 15980 BroadcastQueue queue = broadcastQueueForIntent(intent); 15981 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15982 callerPackage, callingPid, callingUid, resolvedType, 15983 requiredPermission, appOp, receivers, resultTo, resultCode, 15984 resultData, map, ordered, sticky, false, userId); 15985 if (DEBUG_BROADCAST) Slog.v( 15986 TAG, "Enqueueing ordered broadcast " + r 15987 + ": prev had " + queue.mOrderedBroadcasts.size()); 15988 if (DEBUG_BROADCAST) { 15989 int seq = r.intent.getIntExtra("seq", -1); 15990 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15991 } 15992 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15993 if (!replaced) { 15994 queue.enqueueOrderedBroadcastLocked(r); 15995 queue.scheduleBroadcastsLocked(); 15996 } 15997 } 15998 15999 return ActivityManager.BROADCAST_SUCCESS; 16000 } 16001 16002 final Intent verifyBroadcastLocked(Intent intent) { 16003 // Refuse possible leaked file descriptors 16004 if (intent != null && intent.hasFileDescriptors() == true) { 16005 throw new IllegalArgumentException("File descriptors passed in Intent"); 16006 } 16007 16008 int flags = intent.getFlags(); 16009 16010 if (!mProcessesReady) { 16011 // if the caller really truly claims to know what they're doing, go 16012 // ahead and allow the broadcast without launching any receivers 16013 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16014 intent = new Intent(intent); 16015 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16016 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16017 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16018 + " before boot completion"); 16019 throw new IllegalStateException("Cannot broadcast before boot completed"); 16020 } 16021 } 16022 16023 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16024 throw new IllegalArgumentException( 16025 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16026 } 16027 16028 return intent; 16029 } 16030 16031 public final int broadcastIntent(IApplicationThread caller, 16032 Intent intent, String resolvedType, IIntentReceiver resultTo, 16033 int resultCode, String resultData, Bundle map, 16034 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16035 enforceNotIsolatedCaller("broadcastIntent"); 16036 synchronized(this) { 16037 intent = verifyBroadcastLocked(intent); 16038 16039 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16040 final int callingPid = Binder.getCallingPid(); 16041 final int callingUid = Binder.getCallingUid(); 16042 final long origId = Binder.clearCallingIdentity(); 16043 int res = broadcastIntentLocked(callerApp, 16044 callerApp != null ? callerApp.info.packageName : null, 16045 intent, resolvedType, resultTo, 16046 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16047 callingPid, callingUid, userId); 16048 Binder.restoreCallingIdentity(origId); 16049 return res; 16050 } 16051 } 16052 16053 int broadcastIntentInPackage(String packageName, int uid, 16054 Intent intent, String resolvedType, IIntentReceiver resultTo, 16055 int resultCode, String resultData, Bundle map, 16056 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16057 synchronized(this) { 16058 intent = verifyBroadcastLocked(intent); 16059 16060 final long origId = Binder.clearCallingIdentity(); 16061 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16062 resultTo, resultCode, resultData, map, requiredPermission, 16063 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16064 Binder.restoreCallingIdentity(origId); 16065 return res; 16066 } 16067 } 16068 16069 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16070 // Refuse possible leaked file descriptors 16071 if (intent != null && intent.hasFileDescriptors() == true) { 16072 throw new IllegalArgumentException("File descriptors passed in Intent"); 16073 } 16074 16075 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16076 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16077 16078 synchronized(this) { 16079 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16080 != PackageManager.PERMISSION_GRANTED) { 16081 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16082 + Binder.getCallingPid() 16083 + ", uid=" + Binder.getCallingUid() 16084 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16085 Slog.w(TAG, msg); 16086 throw new SecurityException(msg); 16087 } 16088 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16089 if (stickies != null) { 16090 ArrayList<Intent> list = stickies.get(intent.getAction()); 16091 if (list != null) { 16092 int N = list.size(); 16093 int i; 16094 for (i=0; i<N; i++) { 16095 if (intent.filterEquals(list.get(i))) { 16096 list.remove(i); 16097 break; 16098 } 16099 } 16100 if (list.size() <= 0) { 16101 stickies.remove(intent.getAction()); 16102 } 16103 } 16104 if (stickies.size() <= 0) { 16105 mStickyBroadcasts.remove(userId); 16106 } 16107 } 16108 } 16109 } 16110 16111 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16112 String resultData, Bundle resultExtras, boolean resultAbort) { 16113 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16114 if (r == null) { 16115 Slog.w(TAG, "finishReceiver called but not found on queue"); 16116 return false; 16117 } 16118 16119 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16120 } 16121 16122 void backgroundServicesFinishedLocked(int userId) { 16123 for (BroadcastQueue queue : mBroadcastQueues) { 16124 queue.backgroundServicesFinishedLocked(userId); 16125 } 16126 } 16127 16128 public void finishReceiver(IBinder who, int resultCode, String resultData, 16129 Bundle resultExtras, boolean resultAbort) { 16130 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16131 16132 // Refuse possible leaked file descriptors 16133 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16134 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16135 } 16136 16137 final long origId = Binder.clearCallingIdentity(); 16138 try { 16139 boolean doNext = false; 16140 BroadcastRecord r; 16141 16142 synchronized(this) { 16143 r = broadcastRecordForReceiverLocked(who); 16144 if (r != null) { 16145 doNext = r.queue.finishReceiverLocked(r, resultCode, 16146 resultData, resultExtras, resultAbort, true); 16147 } 16148 } 16149 16150 if (doNext) { 16151 r.queue.processNextBroadcast(false); 16152 } 16153 trimApplications(); 16154 } finally { 16155 Binder.restoreCallingIdentity(origId); 16156 } 16157 } 16158 16159 // ========================================================= 16160 // INSTRUMENTATION 16161 // ========================================================= 16162 16163 public boolean startInstrumentation(ComponentName className, 16164 String profileFile, int flags, Bundle arguments, 16165 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16166 int userId, String abiOverride) { 16167 enforceNotIsolatedCaller("startInstrumentation"); 16168 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16169 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16170 // Refuse possible leaked file descriptors 16171 if (arguments != null && arguments.hasFileDescriptors()) { 16172 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16173 } 16174 16175 synchronized(this) { 16176 InstrumentationInfo ii = null; 16177 ApplicationInfo ai = null; 16178 try { 16179 ii = mContext.getPackageManager().getInstrumentationInfo( 16180 className, STOCK_PM_FLAGS); 16181 ai = AppGlobals.getPackageManager().getApplicationInfo( 16182 ii.targetPackage, STOCK_PM_FLAGS, userId); 16183 } catch (PackageManager.NameNotFoundException e) { 16184 } catch (RemoteException e) { 16185 } 16186 if (ii == null) { 16187 reportStartInstrumentationFailure(watcher, className, 16188 "Unable to find instrumentation info for: " + className); 16189 return false; 16190 } 16191 if (ai == null) { 16192 reportStartInstrumentationFailure(watcher, className, 16193 "Unable to find instrumentation target package: " + ii.targetPackage); 16194 return false; 16195 } 16196 16197 int match = mContext.getPackageManager().checkSignatures( 16198 ii.targetPackage, ii.packageName); 16199 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16200 String msg = "Permission Denial: starting instrumentation " 16201 + className + " from pid=" 16202 + Binder.getCallingPid() 16203 + ", uid=" + Binder.getCallingPid() 16204 + " not allowed because package " + ii.packageName 16205 + " does not have a signature matching the target " 16206 + ii.targetPackage; 16207 reportStartInstrumentationFailure(watcher, className, msg); 16208 throw new SecurityException(msg); 16209 } 16210 16211 final long origId = Binder.clearCallingIdentity(); 16212 // Instrumentation can kill and relaunch even persistent processes 16213 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16214 "start instr"); 16215 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16216 app.instrumentationClass = className; 16217 app.instrumentationInfo = ai; 16218 app.instrumentationProfileFile = profileFile; 16219 app.instrumentationArguments = arguments; 16220 app.instrumentationWatcher = watcher; 16221 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16222 app.instrumentationResultClass = className; 16223 Binder.restoreCallingIdentity(origId); 16224 } 16225 16226 return true; 16227 } 16228 16229 /** 16230 * Report errors that occur while attempting to start Instrumentation. Always writes the 16231 * error to the logs, but if somebody is watching, send the report there too. This enables 16232 * the "am" command to report errors with more information. 16233 * 16234 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16235 * @param cn The component name of the instrumentation. 16236 * @param report The error report. 16237 */ 16238 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16239 ComponentName cn, String report) { 16240 Slog.w(TAG, report); 16241 try { 16242 if (watcher != null) { 16243 Bundle results = new Bundle(); 16244 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16245 results.putString("Error", report); 16246 watcher.instrumentationStatus(cn, -1, results); 16247 } 16248 } catch (RemoteException e) { 16249 Slog.w(TAG, e); 16250 } 16251 } 16252 16253 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16254 if (app.instrumentationWatcher != null) { 16255 try { 16256 // NOTE: IInstrumentationWatcher *must* be oneway here 16257 app.instrumentationWatcher.instrumentationFinished( 16258 app.instrumentationClass, 16259 resultCode, 16260 results); 16261 } catch (RemoteException e) { 16262 } 16263 } 16264 if (app.instrumentationUiAutomationConnection != null) { 16265 try { 16266 app.instrumentationUiAutomationConnection.shutdown(); 16267 } catch (RemoteException re) { 16268 /* ignore */ 16269 } 16270 // Only a UiAutomation can set this flag and now that 16271 // it is finished we make sure it is reset to its default. 16272 mUserIsMonkey = false; 16273 } 16274 app.instrumentationWatcher = null; 16275 app.instrumentationUiAutomationConnection = null; 16276 app.instrumentationClass = null; 16277 app.instrumentationInfo = null; 16278 app.instrumentationProfileFile = null; 16279 app.instrumentationArguments = null; 16280 16281 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16282 "finished inst"); 16283 } 16284 16285 public void finishInstrumentation(IApplicationThread target, 16286 int resultCode, Bundle results) { 16287 int userId = UserHandle.getCallingUserId(); 16288 // Refuse possible leaked file descriptors 16289 if (results != null && results.hasFileDescriptors()) { 16290 throw new IllegalArgumentException("File descriptors passed in Intent"); 16291 } 16292 16293 synchronized(this) { 16294 ProcessRecord app = getRecordForAppLocked(target); 16295 if (app == null) { 16296 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16297 return; 16298 } 16299 final long origId = Binder.clearCallingIdentity(); 16300 finishInstrumentationLocked(app, resultCode, results); 16301 Binder.restoreCallingIdentity(origId); 16302 } 16303 } 16304 16305 // ========================================================= 16306 // CONFIGURATION 16307 // ========================================================= 16308 16309 public ConfigurationInfo getDeviceConfigurationInfo() { 16310 ConfigurationInfo config = new ConfigurationInfo(); 16311 synchronized (this) { 16312 config.reqTouchScreen = mConfiguration.touchscreen; 16313 config.reqKeyboardType = mConfiguration.keyboard; 16314 config.reqNavigation = mConfiguration.navigation; 16315 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16316 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16317 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16318 } 16319 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16320 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16321 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16322 } 16323 config.reqGlEsVersion = GL_ES_VERSION; 16324 } 16325 return config; 16326 } 16327 16328 ActivityStack getFocusedStack() { 16329 return mStackSupervisor.getFocusedStack(); 16330 } 16331 16332 public Configuration getConfiguration() { 16333 Configuration ci; 16334 synchronized(this) { 16335 ci = new Configuration(mConfiguration); 16336 } 16337 return ci; 16338 } 16339 16340 public void updatePersistentConfiguration(Configuration values) { 16341 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16342 "updateConfiguration()"); 16343 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16344 "updateConfiguration()"); 16345 if (values == null) { 16346 throw new NullPointerException("Configuration must not be null"); 16347 } 16348 16349 synchronized(this) { 16350 final long origId = Binder.clearCallingIdentity(); 16351 updateConfigurationLocked(values, null, true, false); 16352 Binder.restoreCallingIdentity(origId); 16353 } 16354 } 16355 16356 public void updateConfiguration(Configuration values) { 16357 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16358 "updateConfiguration()"); 16359 16360 synchronized(this) { 16361 if (values == null && mWindowManager != null) { 16362 // sentinel: fetch the current configuration from the window manager 16363 values = mWindowManager.computeNewConfiguration(); 16364 } 16365 16366 if (mWindowManager != null) { 16367 mProcessList.applyDisplaySize(mWindowManager); 16368 } 16369 16370 final long origId = Binder.clearCallingIdentity(); 16371 if (values != null) { 16372 Settings.System.clearConfiguration(values); 16373 } 16374 updateConfigurationLocked(values, null, false, false); 16375 Binder.restoreCallingIdentity(origId); 16376 } 16377 } 16378 16379 /** 16380 * Do either or both things: (1) change the current configuration, and (2) 16381 * make sure the given activity is running with the (now) current 16382 * configuration. Returns true if the activity has been left running, or 16383 * false if <var>starting</var> is being destroyed to match the new 16384 * configuration. 16385 * @param persistent TODO 16386 */ 16387 boolean updateConfigurationLocked(Configuration values, 16388 ActivityRecord starting, boolean persistent, boolean initLocale) { 16389 int changes = 0; 16390 16391 if (values != null) { 16392 Configuration newConfig = new Configuration(mConfiguration); 16393 changes = newConfig.updateFrom(values); 16394 if (changes != 0) { 16395 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16396 Slog.i(TAG, "Updating configuration to: " + values); 16397 } 16398 16399 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16400 16401 if (values.locale != null && !initLocale) { 16402 saveLocaleLocked(values.locale, 16403 !values.locale.equals(mConfiguration.locale), 16404 values.userSetLocale); 16405 } 16406 16407 mConfigurationSeq++; 16408 if (mConfigurationSeq <= 0) { 16409 mConfigurationSeq = 1; 16410 } 16411 newConfig.seq = mConfigurationSeq; 16412 mConfiguration = newConfig; 16413 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16414 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16415 //mUsageStatsService.noteStartConfig(newConfig); 16416 16417 final Configuration configCopy = new Configuration(mConfiguration); 16418 16419 // TODO: If our config changes, should we auto dismiss any currently 16420 // showing dialogs? 16421 mShowDialogs = shouldShowDialogs(newConfig); 16422 16423 AttributeCache ac = AttributeCache.instance(); 16424 if (ac != null) { 16425 ac.updateConfiguration(configCopy); 16426 } 16427 16428 // Make sure all resources in our process are updated 16429 // right now, so that anyone who is going to retrieve 16430 // resource values after we return will be sure to get 16431 // the new ones. This is especially important during 16432 // boot, where the first config change needs to guarantee 16433 // all resources have that config before following boot 16434 // code is executed. 16435 mSystemThread.applyConfigurationToResources(configCopy); 16436 16437 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16438 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16439 msg.obj = new Configuration(configCopy); 16440 mHandler.sendMessage(msg); 16441 } 16442 16443 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16444 ProcessRecord app = mLruProcesses.get(i); 16445 try { 16446 if (app.thread != null) { 16447 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16448 + app.processName + " new config " + mConfiguration); 16449 app.thread.scheduleConfigurationChanged(configCopy); 16450 } 16451 } catch (Exception e) { 16452 } 16453 } 16454 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16455 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16456 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16457 | Intent.FLAG_RECEIVER_FOREGROUND); 16458 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16459 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16460 Process.SYSTEM_UID, UserHandle.USER_ALL); 16461 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16462 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16463 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16464 broadcastIntentLocked(null, null, intent, 16465 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16466 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16467 } 16468 } 16469 } 16470 16471 boolean kept = true; 16472 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16473 // mainStack is null during startup. 16474 if (mainStack != null) { 16475 if (changes != 0 && starting == null) { 16476 // If the configuration changed, and the caller is not already 16477 // in the process of starting an activity, then find the top 16478 // activity to check if its configuration needs to change. 16479 starting = mainStack.topRunningActivityLocked(null); 16480 } 16481 16482 if (starting != null) { 16483 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16484 // And we need to make sure at this point that all other activities 16485 // are made visible with the correct configuration. 16486 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16487 } 16488 } 16489 16490 if (values != null && mWindowManager != null) { 16491 mWindowManager.setNewConfiguration(mConfiguration); 16492 } 16493 16494 return kept; 16495 } 16496 16497 /** 16498 * Decide based on the configuration whether we should shouw the ANR, 16499 * crash, etc dialogs. The idea is that if there is no affordnace to 16500 * press the on-screen buttons, we shouldn't show the dialog. 16501 * 16502 * A thought: SystemUI might also want to get told about this, the Power 16503 * dialog / global actions also might want different behaviors. 16504 */ 16505 private static final boolean shouldShowDialogs(Configuration config) { 16506 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16507 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16508 } 16509 16510 /** 16511 * Save the locale. You must be inside a synchronized (this) block. 16512 */ 16513 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16514 if(isDiff) { 16515 SystemProperties.set("user.language", l.getLanguage()); 16516 SystemProperties.set("user.region", l.getCountry()); 16517 } 16518 16519 if(isPersist) { 16520 SystemProperties.set("persist.sys.language", l.getLanguage()); 16521 SystemProperties.set("persist.sys.country", l.getCountry()); 16522 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16523 16524 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16525 } 16526 } 16527 16528 @Override 16529 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16530 synchronized (this) { 16531 ActivityRecord srec = ActivityRecord.forToken(token); 16532 if (srec.task != null && srec.task.stack != null) { 16533 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16534 } 16535 } 16536 return false; 16537 } 16538 16539 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16540 Intent resultData) { 16541 16542 synchronized (this) { 16543 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16544 if (stack != null) { 16545 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16546 } 16547 return false; 16548 } 16549 } 16550 16551 public int getLaunchedFromUid(IBinder activityToken) { 16552 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16553 if (srec == null) { 16554 return -1; 16555 } 16556 return srec.launchedFromUid; 16557 } 16558 16559 public String getLaunchedFromPackage(IBinder activityToken) { 16560 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16561 if (srec == null) { 16562 return null; 16563 } 16564 return srec.launchedFromPackage; 16565 } 16566 16567 // ========================================================= 16568 // LIFETIME MANAGEMENT 16569 // ========================================================= 16570 16571 // Returns which broadcast queue the app is the current [or imminent] receiver 16572 // on, or 'null' if the app is not an active broadcast recipient. 16573 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16574 BroadcastRecord r = app.curReceiver; 16575 if (r != null) { 16576 return r.queue; 16577 } 16578 16579 // It's not the current receiver, but it might be starting up to become one 16580 synchronized (this) { 16581 for (BroadcastQueue queue : mBroadcastQueues) { 16582 r = queue.mPendingBroadcast; 16583 if (r != null && r.curApp == app) { 16584 // found it; report which queue it's in 16585 return queue; 16586 } 16587 } 16588 } 16589 16590 return null; 16591 } 16592 16593 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16594 boolean doingAll, long now) { 16595 if (mAdjSeq == app.adjSeq) { 16596 // This adjustment has already been computed. 16597 return app.curRawAdj; 16598 } 16599 16600 if (app.thread == null) { 16601 app.adjSeq = mAdjSeq; 16602 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16603 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16604 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16605 } 16606 16607 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16608 app.adjSource = null; 16609 app.adjTarget = null; 16610 app.empty = false; 16611 app.cached = false; 16612 16613 final int activitiesSize = app.activities.size(); 16614 16615 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16616 // The max adjustment doesn't allow this app to be anything 16617 // below foreground, so it is not worth doing work for it. 16618 app.adjType = "fixed"; 16619 app.adjSeq = mAdjSeq; 16620 app.curRawAdj = app.maxAdj; 16621 app.foregroundActivities = false; 16622 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16623 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16624 // System processes can do UI, and when they do we want to have 16625 // them trim their memory after the user leaves the UI. To 16626 // facilitate this, here we need to determine whether or not it 16627 // is currently showing UI. 16628 app.systemNoUi = true; 16629 if (app == TOP_APP) { 16630 app.systemNoUi = false; 16631 } else if (activitiesSize > 0) { 16632 for (int j = 0; j < activitiesSize; j++) { 16633 final ActivityRecord r = app.activities.get(j); 16634 if (r.visible) { 16635 app.systemNoUi = false; 16636 } 16637 } 16638 } 16639 if (!app.systemNoUi) { 16640 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16641 } 16642 return (app.curAdj=app.maxAdj); 16643 } 16644 16645 app.systemNoUi = false; 16646 16647 // Determine the importance of the process, starting with most 16648 // important to least, and assign an appropriate OOM adjustment. 16649 int adj; 16650 int schedGroup; 16651 int procState; 16652 boolean foregroundActivities = false; 16653 BroadcastQueue queue; 16654 if (app == TOP_APP) { 16655 // The last app on the list is the foreground app. 16656 adj = ProcessList.FOREGROUND_APP_ADJ; 16657 schedGroup = Process.THREAD_GROUP_DEFAULT; 16658 app.adjType = "top-activity"; 16659 foregroundActivities = true; 16660 procState = ActivityManager.PROCESS_STATE_TOP; 16661 } else if (app.instrumentationClass != null) { 16662 // Don't want to kill running instrumentation. 16663 adj = ProcessList.FOREGROUND_APP_ADJ; 16664 schedGroup = Process.THREAD_GROUP_DEFAULT; 16665 app.adjType = "instrumentation"; 16666 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16667 } else if ((queue = isReceivingBroadcast(app)) != null) { 16668 // An app that is currently receiving a broadcast also 16669 // counts as being in the foreground for OOM killer purposes. 16670 // It's placed in a sched group based on the nature of the 16671 // broadcast as reflected by which queue it's active in. 16672 adj = ProcessList.FOREGROUND_APP_ADJ; 16673 schedGroup = (queue == mFgBroadcastQueue) 16674 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16675 app.adjType = "broadcast"; 16676 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16677 } else if (app.executingServices.size() > 0) { 16678 // An app that is currently executing a service callback also 16679 // counts as being in the foreground. 16680 adj = ProcessList.FOREGROUND_APP_ADJ; 16681 schedGroup = app.execServicesFg ? 16682 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16683 app.adjType = "exec-service"; 16684 procState = ActivityManager.PROCESS_STATE_SERVICE; 16685 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16686 } else { 16687 // As far as we know the process is empty. We may change our mind later. 16688 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16689 // At this point we don't actually know the adjustment. Use the cached adj 16690 // value that the caller wants us to. 16691 adj = cachedAdj; 16692 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16693 app.cached = true; 16694 app.empty = true; 16695 app.adjType = "cch-empty"; 16696 } 16697 16698 // Examine all activities if not already foreground. 16699 if (!foregroundActivities && activitiesSize > 0) { 16700 for (int j = 0; j < activitiesSize; j++) { 16701 final ActivityRecord r = app.activities.get(j); 16702 if (r.app != app) { 16703 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16704 + app + "?!?"); 16705 continue; 16706 } 16707 if (r.visible) { 16708 // App has a visible activity; only upgrade adjustment. 16709 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16710 adj = ProcessList.VISIBLE_APP_ADJ; 16711 app.adjType = "visible"; 16712 } 16713 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16714 procState = ActivityManager.PROCESS_STATE_TOP; 16715 } 16716 schedGroup = Process.THREAD_GROUP_DEFAULT; 16717 app.cached = false; 16718 app.empty = false; 16719 foregroundActivities = true; 16720 break; 16721 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16722 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16723 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16724 app.adjType = "pausing"; 16725 } 16726 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16727 procState = ActivityManager.PROCESS_STATE_TOP; 16728 } 16729 schedGroup = Process.THREAD_GROUP_DEFAULT; 16730 app.cached = false; 16731 app.empty = false; 16732 foregroundActivities = true; 16733 } else if (r.state == ActivityState.STOPPING) { 16734 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16735 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16736 app.adjType = "stopping"; 16737 } 16738 // For the process state, we will at this point consider the 16739 // process to be cached. It will be cached either as an activity 16740 // or empty depending on whether the activity is finishing. We do 16741 // this so that we can treat the process as cached for purposes of 16742 // memory trimming (determing current memory level, trim command to 16743 // send to process) since there can be an arbitrary number of stopping 16744 // processes and they should soon all go into the cached state. 16745 if (!r.finishing) { 16746 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16747 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16748 } 16749 } 16750 app.cached = false; 16751 app.empty = false; 16752 foregroundActivities = true; 16753 } else { 16754 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16755 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16756 app.adjType = "cch-act"; 16757 } 16758 } 16759 } 16760 } 16761 16762 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16763 if (app.foregroundServices) { 16764 // The user is aware of this app, so make it visible. 16765 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16766 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16767 app.cached = false; 16768 app.adjType = "fg-service"; 16769 schedGroup = Process.THREAD_GROUP_DEFAULT; 16770 } else if (app.forcingToForeground != null) { 16771 // The user is aware of this app, so make it visible. 16772 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16773 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16774 app.cached = false; 16775 app.adjType = "force-fg"; 16776 app.adjSource = app.forcingToForeground; 16777 schedGroup = Process.THREAD_GROUP_DEFAULT; 16778 } 16779 } 16780 16781 if (app == mHeavyWeightProcess) { 16782 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16783 // We don't want to kill the current heavy-weight process. 16784 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16785 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16786 app.cached = false; 16787 app.adjType = "heavy"; 16788 } 16789 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16790 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16791 } 16792 } 16793 16794 if (app == mHomeProcess) { 16795 if (adj > ProcessList.HOME_APP_ADJ) { 16796 // This process is hosting what we currently consider to be the 16797 // home app, so we don't want to let it go into the background. 16798 adj = ProcessList.HOME_APP_ADJ; 16799 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16800 app.cached = false; 16801 app.adjType = "home"; 16802 } 16803 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16804 procState = ActivityManager.PROCESS_STATE_HOME; 16805 } 16806 } 16807 16808 if (app == mPreviousProcess && app.activities.size() > 0) { 16809 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16810 // This was the previous process that showed UI to the user. 16811 // We want to try to keep it around more aggressively, to give 16812 // a good experience around switching between two apps. 16813 adj = ProcessList.PREVIOUS_APP_ADJ; 16814 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16815 app.cached = false; 16816 app.adjType = "previous"; 16817 } 16818 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16819 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16820 } 16821 } 16822 16823 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16824 + " reason=" + app.adjType); 16825 16826 // By default, we use the computed adjustment. It may be changed if 16827 // there are applications dependent on our services or providers, but 16828 // this gives us a baseline and makes sure we don't get into an 16829 // infinite recursion. 16830 app.adjSeq = mAdjSeq; 16831 app.curRawAdj = adj; 16832 app.hasStartedServices = false; 16833 16834 if (mBackupTarget != null && app == mBackupTarget.app) { 16835 // If possible we want to avoid killing apps while they're being backed up 16836 if (adj > ProcessList.BACKUP_APP_ADJ) { 16837 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16838 adj = ProcessList.BACKUP_APP_ADJ; 16839 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16840 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16841 } 16842 app.adjType = "backup"; 16843 app.cached = false; 16844 } 16845 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16846 procState = ActivityManager.PROCESS_STATE_BACKUP; 16847 } 16848 } 16849 16850 boolean mayBeTop = false; 16851 16852 for (int is = app.services.size()-1; 16853 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16854 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16855 || procState > ActivityManager.PROCESS_STATE_TOP); 16856 is--) { 16857 ServiceRecord s = app.services.valueAt(is); 16858 if (s.startRequested) { 16859 app.hasStartedServices = true; 16860 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16861 procState = ActivityManager.PROCESS_STATE_SERVICE; 16862 } 16863 if (app.hasShownUi && app != mHomeProcess) { 16864 // If this process has shown some UI, let it immediately 16865 // go to the LRU list because it may be pretty heavy with 16866 // UI stuff. We'll tag it with a label just to help 16867 // debug and understand what is going on. 16868 if (adj > ProcessList.SERVICE_ADJ) { 16869 app.adjType = "cch-started-ui-services"; 16870 } 16871 } else { 16872 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16873 // This service has seen some activity within 16874 // recent memory, so we will keep its process ahead 16875 // of the background processes. 16876 if (adj > ProcessList.SERVICE_ADJ) { 16877 adj = ProcessList.SERVICE_ADJ; 16878 app.adjType = "started-services"; 16879 app.cached = false; 16880 } 16881 } 16882 // If we have let the service slide into the background 16883 // state, still have some text describing what it is doing 16884 // even though the service no longer has an impact. 16885 if (adj > ProcessList.SERVICE_ADJ) { 16886 app.adjType = "cch-started-services"; 16887 } 16888 } 16889 } 16890 for (int conni = s.connections.size()-1; 16891 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16892 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16893 || procState > ActivityManager.PROCESS_STATE_TOP); 16894 conni--) { 16895 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16896 for (int i = 0; 16897 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16898 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16899 || procState > ActivityManager.PROCESS_STATE_TOP); 16900 i++) { 16901 // XXX should compute this based on the max of 16902 // all connected clients. 16903 ConnectionRecord cr = clist.get(i); 16904 if (cr.binding.client == app) { 16905 // Binding to ourself is not interesting. 16906 continue; 16907 } 16908 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16909 ProcessRecord client = cr.binding.client; 16910 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16911 TOP_APP, doingAll, now); 16912 int clientProcState = client.curProcState; 16913 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16914 // If the other app is cached for any reason, for purposes here 16915 // we are going to consider it empty. The specific cached state 16916 // doesn't propagate except under certain conditions. 16917 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16918 } 16919 String adjType = null; 16920 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16921 // Not doing bind OOM management, so treat 16922 // this guy more like a started service. 16923 if (app.hasShownUi && app != mHomeProcess) { 16924 // If this process has shown some UI, let it immediately 16925 // go to the LRU list because it may be pretty heavy with 16926 // UI stuff. We'll tag it with a label just to help 16927 // debug and understand what is going on. 16928 if (adj > clientAdj) { 16929 adjType = "cch-bound-ui-services"; 16930 } 16931 app.cached = false; 16932 clientAdj = adj; 16933 clientProcState = procState; 16934 } else { 16935 if (now >= (s.lastActivity 16936 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16937 // This service has not seen activity within 16938 // recent memory, so allow it to drop to the 16939 // LRU list if there is no other reason to keep 16940 // it around. We'll also tag it with a label just 16941 // to help debug and undertand what is going on. 16942 if (adj > clientAdj) { 16943 adjType = "cch-bound-services"; 16944 } 16945 clientAdj = adj; 16946 } 16947 } 16948 } 16949 if (adj > clientAdj) { 16950 // If this process has recently shown UI, and 16951 // the process that is binding to it is less 16952 // important than being visible, then we don't 16953 // care about the binding as much as we care 16954 // about letting this process get into the LRU 16955 // list to be killed and restarted if needed for 16956 // memory. 16957 if (app.hasShownUi && app != mHomeProcess 16958 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16959 adjType = "cch-bound-ui-services"; 16960 } else { 16961 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16962 |Context.BIND_IMPORTANT)) != 0) { 16963 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16964 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16965 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16966 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16967 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16968 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16969 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16970 adj = clientAdj; 16971 } else { 16972 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16973 adj = ProcessList.VISIBLE_APP_ADJ; 16974 } 16975 } 16976 if (!client.cached) { 16977 app.cached = false; 16978 } 16979 adjType = "service"; 16980 } 16981 } 16982 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16983 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16984 schedGroup = Process.THREAD_GROUP_DEFAULT; 16985 } 16986 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16987 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16988 // Special handling of clients who are in the top state. 16989 // We *may* want to consider this process to be in the 16990 // top state as well, but only if there is not another 16991 // reason for it to be running. Being on the top is a 16992 // special state, meaning you are specifically running 16993 // for the current top app. If the process is already 16994 // running in the background for some other reason, it 16995 // is more important to continue considering it to be 16996 // in the background state. 16997 mayBeTop = true; 16998 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16999 } else { 17000 // Special handling for above-top states (persistent 17001 // processes). These should not bring the current process 17002 // into the top state, since they are not on top. Instead 17003 // give them the best state after that. 17004 clientProcState = 17005 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17006 } 17007 } 17008 } else { 17009 if (clientProcState < 17010 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17011 clientProcState = 17012 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17013 } 17014 } 17015 if (procState > clientProcState) { 17016 procState = clientProcState; 17017 } 17018 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17019 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17020 app.pendingUiClean = true; 17021 } 17022 if (adjType != null) { 17023 app.adjType = adjType; 17024 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17025 .REASON_SERVICE_IN_USE; 17026 app.adjSource = cr.binding.client; 17027 app.adjSourceProcState = clientProcState; 17028 app.adjTarget = s.name; 17029 } 17030 } 17031 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17032 app.treatLikeActivity = true; 17033 } 17034 final ActivityRecord a = cr.activity; 17035 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17036 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17037 (a.visible || a.state == ActivityState.RESUMED 17038 || a.state == ActivityState.PAUSING)) { 17039 adj = ProcessList.FOREGROUND_APP_ADJ; 17040 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17041 schedGroup = Process.THREAD_GROUP_DEFAULT; 17042 } 17043 app.cached = false; 17044 app.adjType = "service"; 17045 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17046 .REASON_SERVICE_IN_USE; 17047 app.adjSource = a; 17048 app.adjSourceProcState = procState; 17049 app.adjTarget = s.name; 17050 } 17051 } 17052 } 17053 } 17054 } 17055 17056 for (int provi = app.pubProviders.size()-1; 17057 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17058 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17059 || procState > ActivityManager.PROCESS_STATE_TOP); 17060 provi--) { 17061 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17062 for (int i = cpr.connections.size()-1; 17063 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17064 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17065 || procState > ActivityManager.PROCESS_STATE_TOP); 17066 i--) { 17067 ContentProviderConnection conn = cpr.connections.get(i); 17068 ProcessRecord client = conn.client; 17069 if (client == app) { 17070 // Being our own client is not interesting. 17071 continue; 17072 } 17073 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17074 int clientProcState = client.curProcState; 17075 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17076 // If the other app is cached for any reason, for purposes here 17077 // we are going to consider it empty. 17078 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17079 } 17080 if (adj > clientAdj) { 17081 if (app.hasShownUi && app != mHomeProcess 17082 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17083 app.adjType = "cch-ui-provider"; 17084 } else { 17085 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17086 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17087 app.adjType = "provider"; 17088 } 17089 app.cached &= client.cached; 17090 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17091 .REASON_PROVIDER_IN_USE; 17092 app.adjSource = client; 17093 app.adjSourceProcState = clientProcState; 17094 app.adjTarget = cpr.name; 17095 } 17096 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17097 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17098 // Special handling of clients who are in the top state. 17099 // We *may* want to consider this process to be in the 17100 // top state as well, but only if there is not another 17101 // reason for it to be running. Being on the top is a 17102 // special state, meaning you are specifically running 17103 // for the current top app. If the process is already 17104 // running in the background for some other reason, it 17105 // is more important to continue considering it to be 17106 // in the background state. 17107 mayBeTop = true; 17108 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17109 } else { 17110 // Special handling for above-top states (persistent 17111 // processes). These should not bring the current process 17112 // into the top state, since they are not on top. Instead 17113 // give them the best state after that. 17114 clientProcState = 17115 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17116 } 17117 } 17118 if (procState > clientProcState) { 17119 procState = clientProcState; 17120 } 17121 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17122 schedGroup = Process.THREAD_GROUP_DEFAULT; 17123 } 17124 } 17125 // If the provider has external (non-framework) process 17126 // dependencies, ensure that its adjustment is at least 17127 // FOREGROUND_APP_ADJ. 17128 if (cpr.hasExternalProcessHandles()) { 17129 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17130 adj = ProcessList.FOREGROUND_APP_ADJ; 17131 schedGroup = Process.THREAD_GROUP_DEFAULT; 17132 app.cached = false; 17133 app.adjType = "provider"; 17134 app.adjTarget = cpr.name; 17135 } 17136 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17137 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17138 } 17139 } 17140 } 17141 17142 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17143 // A client of one of our services or providers is in the top state. We 17144 // *may* want to be in the top state, but not if we are already running in 17145 // the background for some other reason. For the decision here, we are going 17146 // to pick out a few specific states that we want to remain in when a client 17147 // is top (states that tend to be longer-term) and otherwise allow it to go 17148 // to the top state. 17149 switch (procState) { 17150 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17151 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17152 case ActivityManager.PROCESS_STATE_SERVICE: 17153 // These all are longer-term states, so pull them up to the top 17154 // of the background states, but not all the way to the top state. 17155 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17156 break; 17157 default: 17158 // Otherwise, top is a better choice, so take it. 17159 procState = ActivityManager.PROCESS_STATE_TOP; 17160 break; 17161 } 17162 } 17163 17164 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17165 if (app.hasClientActivities) { 17166 // This is a cached process, but with client activities. Mark it so. 17167 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17168 app.adjType = "cch-client-act"; 17169 } else if (app.treatLikeActivity) { 17170 // This is a cached process, but somebody wants us to treat it like it has 17171 // an activity, okay! 17172 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17173 app.adjType = "cch-as-act"; 17174 } 17175 } 17176 17177 if (adj == ProcessList.SERVICE_ADJ) { 17178 if (doingAll) { 17179 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17180 mNewNumServiceProcs++; 17181 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17182 if (!app.serviceb) { 17183 // This service isn't far enough down on the LRU list to 17184 // normally be a B service, but if we are low on RAM and it 17185 // is large we want to force it down since we would prefer to 17186 // keep launcher over it. 17187 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17188 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17189 app.serviceHighRam = true; 17190 app.serviceb = true; 17191 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17192 } else { 17193 mNewNumAServiceProcs++; 17194 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17195 } 17196 } else { 17197 app.serviceHighRam = false; 17198 } 17199 } 17200 if (app.serviceb) { 17201 adj = ProcessList.SERVICE_B_ADJ; 17202 } 17203 } 17204 17205 app.curRawAdj = adj; 17206 17207 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17208 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17209 if (adj > app.maxAdj) { 17210 adj = app.maxAdj; 17211 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17212 schedGroup = Process.THREAD_GROUP_DEFAULT; 17213 } 17214 } 17215 17216 // Do final modification to adj. Everything we do between here and applying 17217 // the final setAdj must be done in this function, because we will also use 17218 // it when computing the final cached adj later. Note that we don't need to 17219 // worry about this for max adj above, since max adj will always be used to 17220 // keep it out of the cached vaues. 17221 app.curAdj = app.modifyRawOomAdj(adj); 17222 app.curSchedGroup = schedGroup; 17223 app.curProcState = procState; 17224 app.foregroundActivities = foregroundActivities; 17225 17226 return app.curRawAdj; 17227 } 17228 17229 /** 17230 * Schedule PSS collection of a process. 17231 */ 17232 void requestPssLocked(ProcessRecord proc, int procState) { 17233 if (mPendingPssProcesses.contains(proc)) { 17234 return; 17235 } 17236 if (mPendingPssProcesses.size() == 0) { 17237 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17238 } 17239 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17240 proc.pssProcState = procState; 17241 mPendingPssProcesses.add(proc); 17242 } 17243 17244 /** 17245 * Schedule PSS collection of all processes. 17246 */ 17247 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17248 if (!always) { 17249 if (now < (mLastFullPssTime + 17250 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17251 return; 17252 } 17253 } 17254 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17255 mLastFullPssTime = now; 17256 mFullPssPending = true; 17257 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17258 mPendingPssProcesses.clear(); 17259 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17260 ProcessRecord app = mLruProcesses.get(i); 17261 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17262 app.pssProcState = app.setProcState; 17263 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17264 isSleeping(), now); 17265 mPendingPssProcesses.add(app); 17266 } 17267 } 17268 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17269 } 17270 17271 /** 17272 * Ask a given process to GC right now. 17273 */ 17274 final void performAppGcLocked(ProcessRecord app) { 17275 try { 17276 app.lastRequestedGc = SystemClock.uptimeMillis(); 17277 if (app.thread != null) { 17278 if (app.reportLowMemory) { 17279 app.reportLowMemory = false; 17280 app.thread.scheduleLowMemory(); 17281 } else { 17282 app.thread.processInBackground(); 17283 } 17284 } 17285 } catch (Exception e) { 17286 // whatever. 17287 } 17288 } 17289 17290 /** 17291 * Returns true if things are idle enough to perform GCs. 17292 */ 17293 private final boolean canGcNowLocked() { 17294 boolean processingBroadcasts = false; 17295 for (BroadcastQueue q : mBroadcastQueues) { 17296 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17297 processingBroadcasts = true; 17298 } 17299 } 17300 return !processingBroadcasts 17301 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17302 } 17303 17304 /** 17305 * Perform GCs on all processes that are waiting for it, but only 17306 * if things are idle. 17307 */ 17308 final void performAppGcsLocked() { 17309 final int N = mProcessesToGc.size(); 17310 if (N <= 0) { 17311 return; 17312 } 17313 if (canGcNowLocked()) { 17314 while (mProcessesToGc.size() > 0) { 17315 ProcessRecord proc = mProcessesToGc.remove(0); 17316 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17317 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17318 <= SystemClock.uptimeMillis()) { 17319 // To avoid spamming the system, we will GC processes one 17320 // at a time, waiting a few seconds between each. 17321 performAppGcLocked(proc); 17322 scheduleAppGcsLocked(); 17323 return; 17324 } else { 17325 // It hasn't been long enough since we last GCed this 17326 // process... put it in the list to wait for its time. 17327 addProcessToGcListLocked(proc); 17328 break; 17329 } 17330 } 17331 } 17332 17333 scheduleAppGcsLocked(); 17334 } 17335 } 17336 17337 /** 17338 * If all looks good, perform GCs on all processes waiting for them. 17339 */ 17340 final void performAppGcsIfAppropriateLocked() { 17341 if (canGcNowLocked()) { 17342 performAppGcsLocked(); 17343 return; 17344 } 17345 // Still not idle, wait some more. 17346 scheduleAppGcsLocked(); 17347 } 17348 17349 /** 17350 * Schedule the execution of all pending app GCs. 17351 */ 17352 final void scheduleAppGcsLocked() { 17353 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17354 17355 if (mProcessesToGc.size() > 0) { 17356 // Schedule a GC for the time to the next process. 17357 ProcessRecord proc = mProcessesToGc.get(0); 17358 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17359 17360 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17361 long now = SystemClock.uptimeMillis(); 17362 if (when < (now+GC_TIMEOUT)) { 17363 when = now + GC_TIMEOUT; 17364 } 17365 mHandler.sendMessageAtTime(msg, when); 17366 } 17367 } 17368 17369 /** 17370 * Add a process to the array of processes waiting to be GCed. Keeps the 17371 * list in sorted order by the last GC time. The process can't already be 17372 * on the list. 17373 */ 17374 final void addProcessToGcListLocked(ProcessRecord proc) { 17375 boolean added = false; 17376 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17377 if (mProcessesToGc.get(i).lastRequestedGc < 17378 proc.lastRequestedGc) { 17379 added = true; 17380 mProcessesToGc.add(i+1, proc); 17381 break; 17382 } 17383 } 17384 if (!added) { 17385 mProcessesToGc.add(0, proc); 17386 } 17387 } 17388 17389 /** 17390 * Set up to ask a process to GC itself. This will either do it 17391 * immediately, or put it on the list of processes to gc the next 17392 * time things are idle. 17393 */ 17394 final void scheduleAppGcLocked(ProcessRecord app) { 17395 long now = SystemClock.uptimeMillis(); 17396 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17397 return; 17398 } 17399 if (!mProcessesToGc.contains(app)) { 17400 addProcessToGcListLocked(app); 17401 scheduleAppGcsLocked(); 17402 } 17403 } 17404 17405 final void checkExcessivePowerUsageLocked(boolean doKills) { 17406 updateCpuStatsNow(); 17407 17408 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17409 boolean doWakeKills = doKills; 17410 boolean doCpuKills = doKills; 17411 if (mLastPowerCheckRealtime == 0) { 17412 doWakeKills = false; 17413 } 17414 if (mLastPowerCheckUptime == 0) { 17415 doCpuKills = false; 17416 } 17417 if (stats.isScreenOn()) { 17418 doWakeKills = false; 17419 } 17420 final long curRealtime = SystemClock.elapsedRealtime(); 17421 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17422 final long curUptime = SystemClock.uptimeMillis(); 17423 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17424 mLastPowerCheckRealtime = curRealtime; 17425 mLastPowerCheckUptime = curUptime; 17426 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17427 doWakeKills = false; 17428 } 17429 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17430 doCpuKills = false; 17431 } 17432 int i = mLruProcesses.size(); 17433 while (i > 0) { 17434 i--; 17435 ProcessRecord app = mLruProcesses.get(i); 17436 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17437 long wtime; 17438 synchronized (stats) { 17439 wtime = stats.getProcessWakeTime(app.info.uid, 17440 app.pid, curRealtime); 17441 } 17442 long wtimeUsed = wtime - app.lastWakeTime; 17443 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17444 if (DEBUG_POWER) { 17445 StringBuilder sb = new StringBuilder(128); 17446 sb.append("Wake for "); 17447 app.toShortString(sb); 17448 sb.append(": over "); 17449 TimeUtils.formatDuration(realtimeSince, sb); 17450 sb.append(" used "); 17451 TimeUtils.formatDuration(wtimeUsed, sb); 17452 sb.append(" ("); 17453 sb.append((wtimeUsed*100)/realtimeSince); 17454 sb.append("%)"); 17455 Slog.i(TAG, sb.toString()); 17456 sb.setLength(0); 17457 sb.append("CPU for "); 17458 app.toShortString(sb); 17459 sb.append(": over "); 17460 TimeUtils.formatDuration(uptimeSince, sb); 17461 sb.append(" used "); 17462 TimeUtils.formatDuration(cputimeUsed, sb); 17463 sb.append(" ("); 17464 sb.append((cputimeUsed*100)/uptimeSince); 17465 sb.append("%)"); 17466 Slog.i(TAG, sb.toString()); 17467 } 17468 // If a process has held a wake lock for more 17469 // than 50% of the time during this period, 17470 // that sounds bad. Kill! 17471 if (doWakeKills && realtimeSince > 0 17472 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17473 synchronized (stats) { 17474 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17475 realtimeSince, wtimeUsed); 17476 } 17477 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17478 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17479 } else if (doCpuKills && uptimeSince > 0 17480 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17481 synchronized (stats) { 17482 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17483 uptimeSince, cputimeUsed); 17484 } 17485 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17486 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17487 } else { 17488 app.lastWakeTime = wtime; 17489 app.lastCpuTime = app.curCpuTime; 17490 } 17491 } 17492 } 17493 } 17494 17495 private final boolean applyOomAdjLocked(ProcessRecord app, 17496 ProcessRecord TOP_APP, boolean doingAll, long now) { 17497 boolean success = true; 17498 17499 if (app.curRawAdj != app.setRawAdj) { 17500 app.setRawAdj = app.curRawAdj; 17501 } 17502 17503 int changes = 0; 17504 17505 if (app.curAdj != app.setAdj) { 17506 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17507 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17508 TAG, "Set " + app.pid + " " + app.processName + 17509 " adj " + app.curAdj + ": " + app.adjType); 17510 app.setAdj = app.curAdj; 17511 } 17512 17513 if (app.setSchedGroup != app.curSchedGroup) { 17514 app.setSchedGroup = app.curSchedGroup; 17515 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17516 "Setting process group of " + app.processName 17517 + " to " + app.curSchedGroup); 17518 if (app.waitingToKill != null && 17519 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17520 app.kill(app.waitingToKill, true); 17521 success = false; 17522 } else { 17523 if (true) { 17524 long oldId = Binder.clearCallingIdentity(); 17525 try { 17526 Process.setProcessGroup(app.pid, app.curSchedGroup); 17527 } catch (Exception e) { 17528 Slog.w(TAG, "Failed setting process group of " + app.pid 17529 + " to " + app.curSchedGroup); 17530 e.printStackTrace(); 17531 } finally { 17532 Binder.restoreCallingIdentity(oldId); 17533 } 17534 } else { 17535 if (app.thread != null) { 17536 try { 17537 app.thread.setSchedulingGroup(app.curSchedGroup); 17538 } catch (RemoteException e) { 17539 } 17540 } 17541 } 17542 Process.setSwappiness(app.pid, 17543 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17544 } 17545 } 17546 if (app.repForegroundActivities != app.foregroundActivities) { 17547 app.repForegroundActivities = app.foregroundActivities; 17548 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17549 } 17550 if (app.repProcState != app.curProcState) { 17551 app.repProcState = app.curProcState; 17552 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17553 if (app.thread != null) { 17554 try { 17555 if (false) { 17556 //RuntimeException h = new RuntimeException("here"); 17557 Slog.i(TAG, "Sending new process state " + app.repProcState 17558 + " to " + app /*, h*/); 17559 } 17560 app.thread.setProcessState(app.repProcState); 17561 } catch (RemoteException e) { 17562 } 17563 } 17564 } 17565 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17566 app.setProcState)) { 17567 app.lastStateTime = now; 17568 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17569 isSleeping(), now); 17570 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17571 + ProcessList.makeProcStateString(app.setProcState) + " to " 17572 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17573 + (app.nextPssTime-now) + ": " + app); 17574 } else { 17575 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17576 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17577 requestPssLocked(app, app.setProcState); 17578 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17579 isSleeping(), now); 17580 } else if (false && DEBUG_PSS) { 17581 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17582 } 17583 } 17584 if (app.setProcState != app.curProcState) { 17585 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17586 "Proc state change of " + app.processName 17587 + " to " + app.curProcState); 17588 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17589 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17590 if (setImportant && !curImportant) { 17591 // This app is no longer something we consider important enough to allow to 17592 // use arbitrary amounts of battery power. Note 17593 // its current wake lock time to later know to kill it if 17594 // it is not behaving well. 17595 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17596 synchronized (stats) { 17597 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17598 app.pid, SystemClock.elapsedRealtime()); 17599 } 17600 app.lastCpuTime = app.curCpuTime; 17601 17602 } 17603 app.setProcState = app.curProcState; 17604 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17605 app.notCachedSinceIdle = false; 17606 } 17607 if (!doingAll) { 17608 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17609 } else { 17610 app.procStateChanged = true; 17611 } 17612 } 17613 17614 if (changes != 0) { 17615 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17616 int i = mPendingProcessChanges.size()-1; 17617 ProcessChangeItem item = null; 17618 while (i >= 0) { 17619 item = mPendingProcessChanges.get(i); 17620 if (item.pid == app.pid) { 17621 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17622 break; 17623 } 17624 i--; 17625 } 17626 if (i < 0) { 17627 // No existing item in pending changes; need a new one. 17628 final int NA = mAvailProcessChanges.size(); 17629 if (NA > 0) { 17630 item = mAvailProcessChanges.remove(NA-1); 17631 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17632 } else { 17633 item = new ProcessChangeItem(); 17634 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17635 } 17636 item.changes = 0; 17637 item.pid = app.pid; 17638 item.uid = app.info.uid; 17639 if (mPendingProcessChanges.size() == 0) { 17640 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17641 "*** Enqueueing dispatch processes changed!"); 17642 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17643 } 17644 mPendingProcessChanges.add(item); 17645 } 17646 item.changes |= changes; 17647 item.processState = app.repProcState; 17648 item.foregroundActivities = app.repForegroundActivities; 17649 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17650 + Integer.toHexString(System.identityHashCode(item)) 17651 + " " + app.toShortString() + ": changes=" + item.changes 17652 + " procState=" + item.processState 17653 + " foreground=" + item.foregroundActivities 17654 + " type=" + app.adjType + " source=" + app.adjSource 17655 + " target=" + app.adjTarget); 17656 } 17657 17658 return success; 17659 } 17660 17661 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17662 if (proc.thread != null) { 17663 if (proc.baseProcessTracker != null) { 17664 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17665 } 17666 if (proc.repProcState >= 0) { 17667 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17668 proc.repProcState); 17669 } 17670 } 17671 } 17672 17673 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17674 ProcessRecord TOP_APP, boolean doingAll, long now) { 17675 if (app.thread == null) { 17676 return false; 17677 } 17678 17679 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17680 17681 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17682 } 17683 17684 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17685 boolean oomAdj) { 17686 if (isForeground != proc.foregroundServices) { 17687 proc.foregroundServices = isForeground; 17688 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17689 proc.info.uid); 17690 if (isForeground) { 17691 if (curProcs == null) { 17692 curProcs = new ArrayList<ProcessRecord>(); 17693 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17694 } 17695 if (!curProcs.contains(proc)) { 17696 curProcs.add(proc); 17697 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17698 proc.info.packageName, proc.info.uid); 17699 } 17700 } else { 17701 if (curProcs != null) { 17702 if (curProcs.remove(proc)) { 17703 mBatteryStatsService.noteEvent( 17704 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17705 proc.info.packageName, proc.info.uid); 17706 if (curProcs.size() <= 0) { 17707 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17708 } 17709 } 17710 } 17711 } 17712 if (oomAdj) { 17713 updateOomAdjLocked(); 17714 } 17715 } 17716 } 17717 17718 private final ActivityRecord resumedAppLocked() { 17719 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17720 String pkg; 17721 int uid; 17722 if (act != null) { 17723 pkg = act.packageName; 17724 uid = act.info.applicationInfo.uid; 17725 } else { 17726 pkg = null; 17727 uid = -1; 17728 } 17729 // Has the UID or resumed package name changed? 17730 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17731 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17732 if (mCurResumedPackage != null) { 17733 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17734 mCurResumedPackage, mCurResumedUid); 17735 } 17736 mCurResumedPackage = pkg; 17737 mCurResumedUid = uid; 17738 if (mCurResumedPackage != null) { 17739 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17740 mCurResumedPackage, mCurResumedUid); 17741 } 17742 } 17743 return act; 17744 } 17745 17746 final boolean updateOomAdjLocked(ProcessRecord app) { 17747 final ActivityRecord TOP_ACT = resumedAppLocked(); 17748 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17749 final boolean wasCached = app.cached; 17750 17751 mAdjSeq++; 17752 17753 // This is the desired cached adjusment we want to tell it to use. 17754 // If our app is currently cached, we know it, and that is it. Otherwise, 17755 // we don't know it yet, and it needs to now be cached we will then 17756 // need to do a complete oom adj. 17757 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17758 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17759 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17760 SystemClock.uptimeMillis()); 17761 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17762 // Changed to/from cached state, so apps after it in the LRU 17763 // list may also be changed. 17764 updateOomAdjLocked(); 17765 } 17766 return success; 17767 } 17768 17769 final void updateOomAdjLocked() { 17770 final ActivityRecord TOP_ACT = resumedAppLocked(); 17771 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17772 final long now = SystemClock.uptimeMillis(); 17773 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17774 final int N = mLruProcesses.size(); 17775 17776 if (false) { 17777 RuntimeException e = new RuntimeException(); 17778 e.fillInStackTrace(); 17779 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17780 } 17781 17782 mAdjSeq++; 17783 mNewNumServiceProcs = 0; 17784 mNewNumAServiceProcs = 0; 17785 17786 final int emptyProcessLimit; 17787 final int cachedProcessLimit; 17788 if (mProcessLimit <= 0) { 17789 emptyProcessLimit = cachedProcessLimit = 0; 17790 } else if (mProcessLimit == 1) { 17791 emptyProcessLimit = 1; 17792 cachedProcessLimit = 0; 17793 } else { 17794 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17795 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17796 } 17797 17798 // Let's determine how many processes we have running vs. 17799 // how many slots we have for background processes; we may want 17800 // to put multiple processes in a slot of there are enough of 17801 // them. 17802 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17803 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17804 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17805 if (numEmptyProcs > cachedProcessLimit) { 17806 // If there are more empty processes than our limit on cached 17807 // processes, then use the cached process limit for the factor. 17808 // This ensures that the really old empty processes get pushed 17809 // down to the bottom, so if we are running low on memory we will 17810 // have a better chance at keeping around more cached processes 17811 // instead of a gazillion empty processes. 17812 numEmptyProcs = cachedProcessLimit; 17813 } 17814 int emptyFactor = numEmptyProcs/numSlots; 17815 if (emptyFactor < 1) emptyFactor = 1; 17816 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17817 if (cachedFactor < 1) cachedFactor = 1; 17818 int stepCached = 0; 17819 int stepEmpty = 0; 17820 int numCached = 0; 17821 int numEmpty = 0; 17822 int numTrimming = 0; 17823 17824 mNumNonCachedProcs = 0; 17825 mNumCachedHiddenProcs = 0; 17826 17827 // First update the OOM adjustment for each of the 17828 // application processes based on their current state. 17829 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17830 int nextCachedAdj = curCachedAdj+1; 17831 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17832 int nextEmptyAdj = curEmptyAdj+2; 17833 for (int i=N-1; i>=0; i--) { 17834 ProcessRecord app = mLruProcesses.get(i); 17835 if (!app.killedByAm && app.thread != null) { 17836 app.procStateChanged = false; 17837 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17838 17839 // If we haven't yet assigned the final cached adj 17840 // to the process, do that now. 17841 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17842 switch (app.curProcState) { 17843 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17844 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17845 // This process is a cached process holding activities... 17846 // assign it the next cached value for that type, and then 17847 // step that cached level. 17848 app.curRawAdj = curCachedAdj; 17849 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17850 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17851 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17852 + ")"); 17853 if (curCachedAdj != nextCachedAdj) { 17854 stepCached++; 17855 if (stepCached >= cachedFactor) { 17856 stepCached = 0; 17857 curCachedAdj = nextCachedAdj; 17858 nextCachedAdj += 2; 17859 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17860 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17861 } 17862 } 17863 } 17864 break; 17865 default: 17866 // For everything else, assign next empty cached process 17867 // level and bump that up. Note that this means that 17868 // long-running services that have dropped down to the 17869 // cached level will be treated as empty (since their process 17870 // state is still as a service), which is what we want. 17871 app.curRawAdj = curEmptyAdj; 17872 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17873 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17874 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17875 + ")"); 17876 if (curEmptyAdj != nextEmptyAdj) { 17877 stepEmpty++; 17878 if (stepEmpty >= emptyFactor) { 17879 stepEmpty = 0; 17880 curEmptyAdj = nextEmptyAdj; 17881 nextEmptyAdj += 2; 17882 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17883 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17884 } 17885 } 17886 } 17887 break; 17888 } 17889 } 17890 17891 applyOomAdjLocked(app, TOP_APP, true, now); 17892 17893 // Count the number of process types. 17894 switch (app.curProcState) { 17895 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17896 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17897 mNumCachedHiddenProcs++; 17898 numCached++; 17899 if (numCached > cachedProcessLimit) { 17900 app.kill("cached #" + numCached, true); 17901 } 17902 break; 17903 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17904 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17905 && app.lastActivityTime < oldTime) { 17906 app.kill("empty for " 17907 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17908 / 1000) + "s", true); 17909 } else { 17910 numEmpty++; 17911 if (numEmpty > emptyProcessLimit) { 17912 app.kill("empty #" + numEmpty, true); 17913 } 17914 } 17915 break; 17916 default: 17917 mNumNonCachedProcs++; 17918 break; 17919 } 17920 17921 if (app.isolated && app.services.size() <= 0) { 17922 // If this is an isolated process, and there are no 17923 // services running in it, then the process is no longer 17924 // needed. We agressively kill these because we can by 17925 // definition not re-use the same process again, and it is 17926 // good to avoid having whatever code was running in them 17927 // left sitting around after no longer needed. 17928 app.kill("isolated not needed", true); 17929 } 17930 17931 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17932 && !app.killedByAm) { 17933 numTrimming++; 17934 } 17935 } 17936 } 17937 17938 mNumServiceProcs = mNewNumServiceProcs; 17939 17940 // Now determine the memory trimming level of background processes. 17941 // Unfortunately we need to start at the back of the list to do this 17942 // properly. We only do this if the number of background apps we 17943 // are managing to keep around is less than half the maximum we desire; 17944 // if we are keeping a good number around, we'll let them use whatever 17945 // memory they want. 17946 final int numCachedAndEmpty = numCached + numEmpty; 17947 int memFactor; 17948 if (numCached <= ProcessList.TRIM_CACHED_APPS 17949 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17950 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17951 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17952 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17953 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17954 } else { 17955 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17956 } 17957 } else { 17958 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17959 } 17960 // We always allow the memory level to go up (better). We only allow it to go 17961 // down if we are in a state where that is allowed, *and* the total number of processes 17962 // has gone down since last time. 17963 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17964 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17965 + " last=" + mLastNumProcesses); 17966 if (memFactor > mLastMemoryLevel) { 17967 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17968 memFactor = mLastMemoryLevel; 17969 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17970 } 17971 } 17972 mLastMemoryLevel = memFactor; 17973 mLastNumProcesses = mLruProcesses.size(); 17974 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17975 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17976 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17977 if (mLowRamStartTime == 0) { 17978 mLowRamStartTime = now; 17979 } 17980 int step = 0; 17981 int fgTrimLevel; 17982 switch (memFactor) { 17983 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17984 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17985 break; 17986 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17987 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17988 break; 17989 default: 17990 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17991 break; 17992 } 17993 int factor = numTrimming/3; 17994 int minFactor = 2; 17995 if (mHomeProcess != null) minFactor++; 17996 if (mPreviousProcess != null) minFactor++; 17997 if (factor < minFactor) factor = minFactor; 17998 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17999 for (int i=N-1; i>=0; i--) { 18000 ProcessRecord app = mLruProcesses.get(i); 18001 if (allChanged || app.procStateChanged) { 18002 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18003 app.procStateChanged = false; 18004 } 18005 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18006 && !app.killedByAm) { 18007 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18008 try { 18009 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18010 "Trimming memory of " + app.processName 18011 + " to " + curLevel); 18012 app.thread.scheduleTrimMemory(curLevel); 18013 } catch (RemoteException e) { 18014 } 18015 if (false) { 18016 // For now we won't do this; our memory trimming seems 18017 // to be good enough at this point that destroying 18018 // activities causes more harm than good. 18019 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18020 && app != mHomeProcess && app != mPreviousProcess) { 18021 // Need to do this on its own message because the stack may not 18022 // be in a consistent state at this point. 18023 // For these apps we will also finish their activities 18024 // to help them free memory. 18025 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18026 } 18027 } 18028 } 18029 app.trimMemoryLevel = curLevel; 18030 step++; 18031 if (step >= factor) { 18032 step = 0; 18033 switch (curLevel) { 18034 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18035 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18036 break; 18037 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18038 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18039 break; 18040 } 18041 } 18042 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18043 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18044 && app.thread != null) { 18045 try { 18046 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18047 "Trimming memory of heavy-weight " + app.processName 18048 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18049 app.thread.scheduleTrimMemory( 18050 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18051 } catch (RemoteException e) { 18052 } 18053 } 18054 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18055 } else { 18056 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18057 || app.systemNoUi) && app.pendingUiClean) { 18058 // If this application is now in the background and it 18059 // had done UI, then give it the special trim level to 18060 // have it free UI resources. 18061 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18062 if (app.trimMemoryLevel < level && app.thread != null) { 18063 try { 18064 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18065 "Trimming memory of bg-ui " + app.processName 18066 + " to " + level); 18067 app.thread.scheduleTrimMemory(level); 18068 } catch (RemoteException e) { 18069 } 18070 } 18071 app.pendingUiClean = false; 18072 } 18073 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18074 try { 18075 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18076 "Trimming memory of fg " + app.processName 18077 + " to " + fgTrimLevel); 18078 app.thread.scheduleTrimMemory(fgTrimLevel); 18079 } catch (RemoteException e) { 18080 } 18081 } 18082 app.trimMemoryLevel = fgTrimLevel; 18083 } 18084 } 18085 } else { 18086 if (mLowRamStartTime != 0) { 18087 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18088 mLowRamStartTime = 0; 18089 } 18090 for (int i=N-1; i>=0; i--) { 18091 ProcessRecord app = mLruProcesses.get(i); 18092 if (allChanged || app.procStateChanged) { 18093 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18094 app.procStateChanged = false; 18095 } 18096 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18097 || app.systemNoUi) && app.pendingUiClean) { 18098 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18099 && app.thread != null) { 18100 try { 18101 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18102 "Trimming memory of ui hidden " + app.processName 18103 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18104 app.thread.scheduleTrimMemory( 18105 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18106 } catch (RemoteException e) { 18107 } 18108 } 18109 app.pendingUiClean = false; 18110 } 18111 app.trimMemoryLevel = 0; 18112 } 18113 } 18114 18115 if (mAlwaysFinishActivities) { 18116 // Need to do this on its own message because the stack may not 18117 // be in a consistent state at this point. 18118 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18119 } 18120 18121 if (allChanged) { 18122 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18123 } 18124 18125 if (mProcessStats.shouldWriteNowLocked(now)) { 18126 mHandler.post(new Runnable() { 18127 @Override public void run() { 18128 synchronized (ActivityManagerService.this) { 18129 mProcessStats.writeStateAsyncLocked(); 18130 } 18131 } 18132 }); 18133 } 18134 18135 if (DEBUG_OOM_ADJ) { 18136 if (false) { 18137 RuntimeException here = new RuntimeException("here"); 18138 here.fillInStackTrace(); 18139 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18140 } else { 18141 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18142 } 18143 } 18144 } 18145 18146 final void trimApplications() { 18147 synchronized (this) { 18148 int i; 18149 18150 // First remove any unused application processes whose package 18151 // has been removed. 18152 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18153 final ProcessRecord app = mRemovedProcesses.get(i); 18154 if (app.activities.size() == 0 18155 && app.curReceiver == null && app.services.size() == 0) { 18156 Slog.i( 18157 TAG, "Exiting empty application process " 18158 + app.processName + " (" 18159 + (app.thread != null ? app.thread.asBinder() : null) 18160 + ")\n"); 18161 if (app.pid > 0 && app.pid != MY_PID) { 18162 app.kill("empty", false); 18163 } else { 18164 try { 18165 app.thread.scheduleExit(); 18166 } catch (Exception e) { 18167 // Ignore exceptions. 18168 } 18169 } 18170 cleanUpApplicationRecordLocked(app, false, true, -1); 18171 mRemovedProcesses.remove(i); 18172 18173 if (app.persistent) { 18174 addAppLocked(app.info, false, null /* ABI override */); 18175 } 18176 } 18177 } 18178 18179 // Now update the oom adj for all processes. 18180 updateOomAdjLocked(); 18181 } 18182 } 18183 18184 /** This method sends the specified signal to each of the persistent apps */ 18185 public void signalPersistentProcesses(int sig) throws RemoteException { 18186 if (sig != Process.SIGNAL_USR1) { 18187 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18188 } 18189 18190 synchronized (this) { 18191 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18192 != PackageManager.PERMISSION_GRANTED) { 18193 throw new SecurityException("Requires permission " 18194 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18195 } 18196 18197 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18198 ProcessRecord r = mLruProcesses.get(i); 18199 if (r.thread != null && r.persistent) { 18200 Process.sendSignal(r.pid, sig); 18201 } 18202 } 18203 } 18204 } 18205 18206 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18207 if (proc == null || proc == mProfileProc) { 18208 proc = mProfileProc; 18209 profileType = mProfileType; 18210 clearProfilerLocked(); 18211 } 18212 if (proc == null) { 18213 return; 18214 } 18215 try { 18216 proc.thread.profilerControl(false, null, profileType); 18217 } catch (RemoteException e) { 18218 throw new IllegalStateException("Process disappeared"); 18219 } 18220 } 18221 18222 private void clearProfilerLocked() { 18223 if (mProfileFd != null) { 18224 try { 18225 mProfileFd.close(); 18226 } catch (IOException e) { 18227 } 18228 } 18229 mProfileApp = null; 18230 mProfileProc = null; 18231 mProfileFile = null; 18232 mProfileType = 0; 18233 mAutoStopProfiler = false; 18234 mSamplingInterval = 0; 18235 } 18236 18237 public boolean profileControl(String process, int userId, boolean start, 18238 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18239 18240 try { 18241 synchronized (this) { 18242 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18243 // its own permission. 18244 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18245 != PackageManager.PERMISSION_GRANTED) { 18246 throw new SecurityException("Requires permission " 18247 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18248 } 18249 18250 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18251 throw new IllegalArgumentException("null profile info or fd"); 18252 } 18253 18254 ProcessRecord proc = null; 18255 if (process != null) { 18256 proc = findProcessLocked(process, userId, "profileControl"); 18257 } 18258 18259 if (start && (proc == null || proc.thread == null)) { 18260 throw new IllegalArgumentException("Unknown process: " + process); 18261 } 18262 18263 if (start) { 18264 stopProfilerLocked(null, 0); 18265 setProfileApp(proc.info, proc.processName, profilerInfo); 18266 mProfileProc = proc; 18267 mProfileType = profileType; 18268 ParcelFileDescriptor fd = profilerInfo.profileFd; 18269 try { 18270 fd = fd.dup(); 18271 } catch (IOException e) { 18272 fd = null; 18273 } 18274 profilerInfo.profileFd = fd; 18275 proc.thread.profilerControl(start, profilerInfo, profileType); 18276 fd = null; 18277 mProfileFd = null; 18278 } else { 18279 stopProfilerLocked(proc, profileType); 18280 if (profilerInfo != null && profilerInfo.profileFd != null) { 18281 try { 18282 profilerInfo.profileFd.close(); 18283 } catch (IOException e) { 18284 } 18285 } 18286 } 18287 18288 return true; 18289 } 18290 } catch (RemoteException e) { 18291 throw new IllegalStateException("Process disappeared"); 18292 } finally { 18293 if (profilerInfo != null && profilerInfo.profileFd != null) { 18294 try { 18295 profilerInfo.profileFd.close(); 18296 } catch (IOException e) { 18297 } 18298 } 18299 } 18300 } 18301 18302 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18303 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18304 userId, true, ALLOW_FULL_ONLY, callName, null); 18305 ProcessRecord proc = null; 18306 try { 18307 int pid = Integer.parseInt(process); 18308 synchronized (mPidsSelfLocked) { 18309 proc = mPidsSelfLocked.get(pid); 18310 } 18311 } catch (NumberFormatException e) { 18312 } 18313 18314 if (proc == null) { 18315 ArrayMap<String, SparseArray<ProcessRecord>> all 18316 = mProcessNames.getMap(); 18317 SparseArray<ProcessRecord> procs = all.get(process); 18318 if (procs != null && procs.size() > 0) { 18319 proc = procs.valueAt(0); 18320 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18321 for (int i=1; i<procs.size(); i++) { 18322 ProcessRecord thisProc = procs.valueAt(i); 18323 if (thisProc.userId == userId) { 18324 proc = thisProc; 18325 break; 18326 } 18327 } 18328 } 18329 } 18330 } 18331 18332 return proc; 18333 } 18334 18335 public boolean dumpHeap(String process, int userId, boolean managed, 18336 String path, ParcelFileDescriptor fd) throws RemoteException { 18337 18338 try { 18339 synchronized (this) { 18340 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18341 // its own permission (same as profileControl). 18342 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18343 != PackageManager.PERMISSION_GRANTED) { 18344 throw new SecurityException("Requires permission " 18345 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18346 } 18347 18348 if (fd == null) { 18349 throw new IllegalArgumentException("null fd"); 18350 } 18351 18352 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18353 if (proc == null || proc.thread == null) { 18354 throw new IllegalArgumentException("Unknown process: " + process); 18355 } 18356 18357 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18358 if (!isDebuggable) { 18359 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18360 throw new SecurityException("Process not debuggable: " + proc); 18361 } 18362 } 18363 18364 proc.thread.dumpHeap(managed, path, fd); 18365 fd = null; 18366 return true; 18367 } 18368 } catch (RemoteException e) { 18369 throw new IllegalStateException("Process disappeared"); 18370 } finally { 18371 if (fd != null) { 18372 try { 18373 fd.close(); 18374 } catch (IOException e) { 18375 } 18376 } 18377 } 18378 } 18379 18380 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18381 public void monitor() { 18382 synchronized (this) { } 18383 } 18384 18385 void onCoreSettingsChange(Bundle settings) { 18386 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18387 ProcessRecord processRecord = mLruProcesses.get(i); 18388 try { 18389 if (processRecord.thread != null) { 18390 processRecord.thread.setCoreSettings(settings); 18391 } 18392 } catch (RemoteException re) { 18393 /* ignore */ 18394 } 18395 } 18396 } 18397 18398 // Multi-user methods 18399 18400 /** 18401 * Start user, if its not already running, but don't bring it to foreground. 18402 */ 18403 @Override 18404 public boolean startUserInBackground(final int userId) { 18405 return startUser(userId, /* foreground */ false); 18406 } 18407 18408 /** 18409 * Start user, if its not already running, and bring it to foreground. 18410 */ 18411 boolean startUserInForeground(final int userId, Dialog dlg) { 18412 boolean result = startUser(userId, /* foreground */ true); 18413 dlg.dismiss(); 18414 return result; 18415 } 18416 18417 /** 18418 * Refreshes the list of users related to the current user when either a 18419 * user switch happens or when a new related user is started in the 18420 * background. 18421 */ 18422 private void updateCurrentProfileIdsLocked() { 18423 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18424 mCurrentUserId, false /* enabledOnly */); 18425 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18426 for (int i = 0; i < currentProfileIds.length; i++) { 18427 currentProfileIds[i] = profiles.get(i).id; 18428 } 18429 mCurrentProfileIds = currentProfileIds; 18430 18431 synchronized (mUserProfileGroupIdsSelfLocked) { 18432 mUserProfileGroupIdsSelfLocked.clear(); 18433 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18434 for (int i = 0; i < users.size(); i++) { 18435 UserInfo user = users.get(i); 18436 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18437 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18438 } 18439 } 18440 } 18441 } 18442 18443 private Set getProfileIdsLocked(int userId) { 18444 Set userIds = new HashSet<Integer>(); 18445 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18446 userId, false /* enabledOnly */); 18447 for (UserInfo user : profiles) { 18448 userIds.add(Integer.valueOf(user.id)); 18449 } 18450 return userIds; 18451 } 18452 18453 @Override 18454 public boolean switchUser(final int userId) { 18455 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18456 String userName; 18457 synchronized (this) { 18458 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18459 if (userInfo == null) { 18460 Slog.w(TAG, "No user info for user #" + userId); 18461 return false; 18462 } 18463 if (userInfo.isManagedProfile()) { 18464 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18465 return false; 18466 } 18467 userName = userInfo.name; 18468 mTargetUserId = userId; 18469 } 18470 mHandler.removeMessages(START_USER_SWITCH_MSG); 18471 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18472 return true; 18473 } 18474 18475 private void showUserSwitchDialog(int userId, String userName) { 18476 // The dialog will show and then initiate the user switch by calling startUserInForeground 18477 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18478 true /* above system */); 18479 d.show(); 18480 } 18481 18482 private boolean startUser(final int userId, final boolean foreground) { 18483 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18484 != PackageManager.PERMISSION_GRANTED) { 18485 String msg = "Permission Denial: switchUser() from pid=" 18486 + Binder.getCallingPid() 18487 + ", uid=" + Binder.getCallingUid() 18488 + " requires " + INTERACT_ACROSS_USERS_FULL; 18489 Slog.w(TAG, msg); 18490 throw new SecurityException(msg); 18491 } 18492 18493 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18494 18495 final long ident = Binder.clearCallingIdentity(); 18496 try { 18497 synchronized (this) { 18498 final int oldUserId = mCurrentUserId; 18499 if (oldUserId == userId) { 18500 return true; 18501 } 18502 18503 mStackSupervisor.setLockTaskModeLocked(null, false); 18504 18505 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18506 if (userInfo == null) { 18507 Slog.w(TAG, "No user info for user #" + userId); 18508 return false; 18509 } 18510 if (foreground && userInfo.isManagedProfile()) { 18511 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18512 return false; 18513 } 18514 18515 if (foreground) { 18516 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18517 R.anim.screen_user_enter); 18518 } 18519 18520 boolean needStart = false; 18521 18522 // If the user we are switching to is not currently started, then 18523 // we need to start it now. 18524 if (mStartedUsers.get(userId) == null) { 18525 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18526 updateStartedUserArrayLocked(); 18527 needStart = true; 18528 } 18529 18530 final Integer userIdInt = Integer.valueOf(userId); 18531 mUserLru.remove(userIdInt); 18532 mUserLru.add(userIdInt); 18533 18534 if (foreground) { 18535 mCurrentUserId = userId; 18536 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18537 updateCurrentProfileIdsLocked(); 18538 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18539 // Once the internal notion of the active user has switched, we lock the device 18540 // with the option to show the user switcher on the keyguard. 18541 mWindowManager.lockNow(null); 18542 } else { 18543 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18544 updateCurrentProfileIdsLocked(); 18545 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18546 mUserLru.remove(currentUserIdInt); 18547 mUserLru.add(currentUserIdInt); 18548 } 18549 18550 final UserStartedState uss = mStartedUsers.get(userId); 18551 18552 // Make sure user is in the started state. If it is currently 18553 // stopping, we need to knock that off. 18554 if (uss.mState == UserStartedState.STATE_STOPPING) { 18555 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18556 // so we can just fairly silently bring the user back from 18557 // the almost-dead. 18558 uss.mState = UserStartedState.STATE_RUNNING; 18559 updateStartedUserArrayLocked(); 18560 needStart = true; 18561 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18562 // This means ACTION_SHUTDOWN has been sent, so we will 18563 // need to treat this as a new boot of the user. 18564 uss.mState = UserStartedState.STATE_BOOTING; 18565 updateStartedUserArrayLocked(); 18566 needStart = true; 18567 } 18568 18569 if (uss.mState == UserStartedState.STATE_BOOTING) { 18570 // Booting up a new user, need to tell system services about it. 18571 // Note that this is on the same handler as scheduling of broadcasts, 18572 // which is important because it needs to go first. 18573 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18574 } 18575 18576 if (foreground) { 18577 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18578 oldUserId)); 18579 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18580 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18581 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18582 oldUserId, userId, uss)); 18583 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18584 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18585 } 18586 18587 if (needStart) { 18588 // Send USER_STARTED broadcast 18589 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18590 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18591 | Intent.FLAG_RECEIVER_FOREGROUND); 18592 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18593 broadcastIntentLocked(null, null, intent, 18594 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18595 false, false, MY_PID, Process.SYSTEM_UID, userId); 18596 } 18597 18598 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18599 if (userId != UserHandle.USER_OWNER) { 18600 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18601 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18602 broadcastIntentLocked(null, null, intent, null, 18603 new IIntentReceiver.Stub() { 18604 public void performReceive(Intent intent, int resultCode, 18605 String data, Bundle extras, boolean ordered, 18606 boolean sticky, int sendingUser) { 18607 onUserInitialized(uss, foreground, oldUserId, userId); 18608 } 18609 }, 0, null, null, null, AppOpsManager.OP_NONE, 18610 true, false, MY_PID, Process.SYSTEM_UID, 18611 userId); 18612 uss.initializing = true; 18613 } else { 18614 getUserManagerLocked().makeInitialized(userInfo.id); 18615 } 18616 } 18617 18618 if (foreground) { 18619 if (!uss.initializing) { 18620 moveUserToForeground(uss, oldUserId, userId); 18621 } 18622 } else { 18623 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18624 } 18625 18626 if (needStart) { 18627 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18628 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18629 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18630 broadcastIntentLocked(null, null, intent, 18631 null, new IIntentReceiver.Stub() { 18632 @Override 18633 public void performReceive(Intent intent, int resultCode, String data, 18634 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18635 throws RemoteException { 18636 } 18637 }, 0, null, null, 18638 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18639 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18640 } 18641 } 18642 } finally { 18643 Binder.restoreCallingIdentity(ident); 18644 } 18645 18646 return true; 18647 } 18648 18649 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18650 long ident = Binder.clearCallingIdentity(); 18651 try { 18652 Intent intent; 18653 if (oldUserId >= 0) { 18654 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18655 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18656 int count = profiles.size(); 18657 for (int i = 0; i < count; i++) { 18658 int profileUserId = profiles.get(i).id; 18659 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18660 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18661 | Intent.FLAG_RECEIVER_FOREGROUND); 18662 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18663 broadcastIntentLocked(null, null, intent, 18664 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18665 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18666 } 18667 } 18668 if (newUserId >= 0) { 18669 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18670 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18671 int count = profiles.size(); 18672 for (int i = 0; i < count; i++) { 18673 int profileUserId = profiles.get(i).id; 18674 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18675 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18676 | Intent.FLAG_RECEIVER_FOREGROUND); 18677 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18678 broadcastIntentLocked(null, null, intent, 18679 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18680 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18681 } 18682 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18683 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18684 | Intent.FLAG_RECEIVER_FOREGROUND); 18685 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18686 broadcastIntentLocked(null, null, intent, 18687 null, null, 0, null, null, 18688 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18689 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18690 } 18691 } finally { 18692 Binder.restoreCallingIdentity(ident); 18693 } 18694 } 18695 18696 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18697 final int newUserId) { 18698 final int N = mUserSwitchObservers.beginBroadcast(); 18699 if (N > 0) { 18700 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18701 int mCount = 0; 18702 @Override 18703 public void sendResult(Bundle data) throws RemoteException { 18704 synchronized (ActivityManagerService.this) { 18705 if (mCurUserSwitchCallback == this) { 18706 mCount++; 18707 if (mCount == N) { 18708 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18709 } 18710 } 18711 } 18712 } 18713 }; 18714 synchronized (this) { 18715 uss.switching = true; 18716 mCurUserSwitchCallback = callback; 18717 } 18718 for (int i=0; i<N; i++) { 18719 try { 18720 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18721 newUserId, callback); 18722 } catch (RemoteException e) { 18723 } 18724 } 18725 } else { 18726 synchronized (this) { 18727 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18728 } 18729 } 18730 mUserSwitchObservers.finishBroadcast(); 18731 } 18732 18733 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18734 synchronized (this) { 18735 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18736 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18737 } 18738 } 18739 18740 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18741 mCurUserSwitchCallback = null; 18742 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18743 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18744 oldUserId, newUserId, uss)); 18745 } 18746 18747 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18748 synchronized (this) { 18749 if (foreground) { 18750 moveUserToForeground(uss, oldUserId, newUserId); 18751 } 18752 } 18753 18754 completeSwitchAndInitalize(uss, newUserId, true, false); 18755 } 18756 18757 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18758 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18759 if (homeInFront) { 18760 startHomeActivityLocked(newUserId); 18761 } else { 18762 mStackSupervisor.resumeTopActivitiesLocked(); 18763 } 18764 EventLogTags.writeAmSwitchUser(newUserId); 18765 getUserManagerLocked().userForeground(newUserId); 18766 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18767 } 18768 18769 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18770 completeSwitchAndInitalize(uss, newUserId, false, true); 18771 } 18772 18773 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18774 boolean clearInitializing, boolean clearSwitching) { 18775 boolean unfrozen = false; 18776 synchronized (this) { 18777 if (clearInitializing) { 18778 uss.initializing = false; 18779 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18780 } 18781 if (clearSwitching) { 18782 uss.switching = false; 18783 } 18784 if (!uss.switching && !uss.initializing) { 18785 mWindowManager.stopFreezingScreen(); 18786 unfrozen = true; 18787 } 18788 } 18789 if (unfrozen) { 18790 final int N = mUserSwitchObservers.beginBroadcast(); 18791 for (int i=0; i<N; i++) { 18792 try { 18793 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18794 } catch (RemoteException e) { 18795 } 18796 } 18797 mUserSwitchObservers.finishBroadcast(); 18798 } 18799 } 18800 18801 void scheduleStartProfilesLocked() { 18802 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18803 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18804 DateUtils.SECOND_IN_MILLIS); 18805 } 18806 } 18807 18808 void startProfilesLocked() { 18809 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18810 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18811 mCurrentUserId, false /* enabledOnly */); 18812 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18813 for (UserInfo user : profiles) { 18814 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18815 && user.id != mCurrentUserId) { 18816 toStart.add(user); 18817 } 18818 } 18819 final int n = toStart.size(); 18820 int i = 0; 18821 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18822 startUserInBackground(toStart.get(i).id); 18823 } 18824 if (i < n) { 18825 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18826 } 18827 } 18828 18829 void finishUserBoot(UserStartedState uss) { 18830 synchronized (this) { 18831 if (uss.mState == UserStartedState.STATE_BOOTING 18832 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18833 uss.mState = UserStartedState.STATE_RUNNING; 18834 final int userId = uss.mHandle.getIdentifier(); 18835 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18836 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18837 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18838 broadcastIntentLocked(null, null, intent, 18839 null, null, 0, null, null, 18840 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18841 true, false, MY_PID, Process.SYSTEM_UID, userId); 18842 } 18843 } 18844 } 18845 18846 void finishUserSwitch(UserStartedState uss) { 18847 synchronized (this) { 18848 finishUserBoot(uss); 18849 18850 startProfilesLocked(); 18851 18852 int num = mUserLru.size(); 18853 int i = 0; 18854 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18855 Integer oldUserId = mUserLru.get(i); 18856 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18857 if (oldUss == null) { 18858 // Shouldn't happen, but be sane if it does. 18859 mUserLru.remove(i); 18860 num--; 18861 continue; 18862 } 18863 if (oldUss.mState == UserStartedState.STATE_STOPPING 18864 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18865 // This user is already stopping, doesn't count. 18866 num--; 18867 i++; 18868 continue; 18869 } 18870 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18871 // Owner and current can't be stopped, but count as running. 18872 i++; 18873 continue; 18874 } 18875 // This is a user to be stopped. 18876 stopUserLocked(oldUserId, null); 18877 num--; 18878 i++; 18879 } 18880 } 18881 } 18882 18883 @Override 18884 public int stopUser(final int userId, final IStopUserCallback callback) { 18885 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18886 != PackageManager.PERMISSION_GRANTED) { 18887 String msg = "Permission Denial: switchUser() from pid=" 18888 + Binder.getCallingPid() 18889 + ", uid=" + Binder.getCallingUid() 18890 + " requires " + INTERACT_ACROSS_USERS_FULL; 18891 Slog.w(TAG, msg); 18892 throw new SecurityException(msg); 18893 } 18894 if (userId <= 0) { 18895 throw new IllegalArgumentException("Can't stop primary user " + userId); 18896 } 18897 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18898 synchronized (this) { 18899 return stopUserLocked(userId, callback); 18900 } 18901 } 18902 18903 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18904 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18905 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18906 return ActivityManager.USER_OP_IS_CURRENT; 18907 } 18908 18909 final UserStartedState uss = mStartedUsers.get(userId); 18910 if (uss == null) { 18911 // User is not started, nothing to do... but we do need to 18912 // callback if requested. 18913 if (callback != null) { 18914 mHandler.post(new Runnable() { 18915 @Override 18916 public void run() { 18917 try { 18918 callback.userStopped(userId); 18919 } catch (RemoteException e) { 18920 } 18921 } 18922 }); 18923 } 18924 return ActivityManager.USER_OP_SUCCESS; 18925 } 18926 18927 if (callback != null) { 18928 uss.mStopCallbacks.add(callback); 18929 } 18930 18931 if (uss.mState != UserStartedState.STATE_STOPPING 18932 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18933 uss.mState = UserStartedState.STATE_STOPPING; 18934 updateStartedUserArrayLocked(); 18935 18936 long ident = Binder.clearCallingIdentity(); 18937 try { 18938 // We are going to broadcast ACTION_USER_STOPPING and then 18939 // once that is done send a final ACTION_SHUTDOWN and then 18940 // stop the user. 18941 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18942 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18943 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18944 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18945 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18946 // This is the result receiver for the final shutdown broadcast. 18947 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18948 @Override 18949 public void performReceive(Intent intent, int resultCode, String data, 18950 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18951 finishUserStop(uss); 18952 } 18953 }; 18954 // This is the result receiver for the initial stopping broadcast. 18955 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18956 @Override 18957 public void performReceive(Intent intent, int resultCode, String data, 18958 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18959 // On to the next. 18960 synchronized (ActivityManagerService.this) { 18961 if (uss.mState != UserStartedState.STATE_STOPPING) { 18962 // Whoops, we are being started back up. Abort, abort! 18963 return; 18964 } 18965 uss.mState = UserStartedState.STATE_SHUTDOWN; 18966 } 18967 mBatteryStatsService.noteEvent( 18968 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18969 Integer.toString(userId), userId); 18970 mSystemServiceManager.stopUser(userId); 18971 broadcastIntentLocked(null, null, shutdownIntent, 18972 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18973 true, false, MY_PID, Process.SYSTEM_UID, userId); 18974 } 18975 }; 18976 // Kick things off. 18977 broadcastIntentLocked(null, null, stoppingIntent, 18978 null, stoppingReceiver, 0, null, null, 18979 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18980 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18981 } finally { 18982 Binder.restoreCallingIdentity(ident); 18983 } 18984 } 18985 18986 return ActivityManager.USER_OP_SUCCESS; 18987 } 18988 18989 void finishUserStop(UserStartedState uss) { 18990 final int userId = uss.mHandle.getIdentifier(); 18991 boolean stopped; 18992 ArrayList<IStopUserCallback> callbacks; 18993 synchronized (this) { 18994 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18995 if (mStartedUsers.get(userId) != uss) { 18996 stopped = false; 18997 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18998 stopped = false; 18999 } else { 19000 stopped = true; 19001 // User can no longer run. 19002 mStartedUsers.remove(userId); 19003 mUserLru.remove(Integer.valueOf(userId)); 19004 updateStartedUserArrayLocked(); 19005 19006 // Clean up all state and processes associated with the user. 19007 // Kill all the processes for the user. 19008 forceStopUserLocked(userId, "finish user"); 19009 } 19010 19011 // Explicitly remove the old information in mRecentTasks. 19012 removeRecentTasksForUserLocked(userId); 19013 } 19014 19015 for (int i=0; i<callbacks.size(); i++) { 19016 try { 19017 if (stopped) callbacks.get(i).userStopped(userId); 19018 else callbacks.get(i).userStopAborted(userId); 19019 } catch (RemoteException e) { 19020 } 19021 } 19022 19023 if (stopped) { 19024 mSystemServiceManager.cleanupUser(userId); 19025 synchronized (this) { 19026 mStackSupervisor.removeUserLocked(userId); 19027 } 19028 } 19029 } 19030 19031 @Override 19032 public UserInfo getCurrentUser() { 19033 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19034 != PackageManager.PERMISSION_GRANTED) && ( 19035 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19036 != PackageManager.PERMISSION_GRANTED)) { 19037 String msg = "Permission Denial: getCurrentUser() from pid=" 19038 + Binder.getCallingPid() 19039 + ", uid=" + Binder.getCallingUid() 19040 + " requires " + INTERACT_ACROSS_USERS; 19041 Slog.w(TAG, msg); 19042 throw new SecurityException(msg); 19043 } 19044 synchronized (this) { 19045 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19046 return getUserManagerLocked().getUserInfo(userId); 19047 } 19048 } 19049 19050 int getCurrentUserIdLocked() { 19051 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19052 } 19053 19054 @Override 19055 public boolean isUserRunning(int userId, boolean orStopped) { 19056 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19057 != PackageManager.PERMISSION_GRANTED) { 19058 String msg = "Permission Denial: isUserRunning() from pid=" 19059 + Binder.getCallingPid() 19060 + ", uid=" + Binder.getCallingUid() 19061 + " requires " + INTERACT_ACROSS_USERS; 19062 Slog.w(TAG, msg); 19063 throw new SecurityException(msg); 19064 } 19065 synchronized (this) { 19066 return isUserRunningLocked(userId, orStopped); 19067 } 19068 } 19069 19070 boolean isUserRunningLocked(int userId, boolean orStopped) { 19071 UserStartedState state = mStartedUsers.get(userId); 19072 if (state == null) { 19073 return false; 19074 } 19075 if (orStopped) { 19076 return true; 19077 } 19078 return state.mState != UserStartedState.STATE_STOPPING 19079 && state.mState != UserStartedState.STATE_SHUTDOWN; 19080 } 19081 19082 @Override 19083 public int[] getRunningUserIds() { 19084 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19085 != PackageManager.PERMISSION_GRANTED) { 19086 String msg = "Permission Denial: isUserRunning() from pid=" 19087 + Binder.getCallingPid() 19088 + ", uid=" + Binder.getCallingUid() 19089 + " requires " + INTERACT_ACROSS_USERS; 19090 Slog.w(TAG, msg); 19091 throw new SecurityException(msg); 19092 } 19093 synchronized (this) { 19094 return mStartedUserArray; 19095 } 19096 } 19097 19098 private void updateStartedUserArrayLocked() { 19099 int num = 0; 19100 for (int i=0; i<mStartedUsers.size(); i++) { 19101 UserStartedState uss = mStartedUsers.valueAt(i); 19102 // This list does not include stopping users. 19103 if (uss.mState != UserStartedState.STATE_STOPPING 19104 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19105 num++; 19106 } 19107 } 19108 mStartedUserArray = new int[num]; 19109 num = 0; 19110 for (int i=0; i<mStartedUsers.size(); i++) { 19111 UserStartedState uss = mStartedUsers.valueAt(i); 19112 if (uss.mState != UserStartedState.STATE_STOPPING 19113 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19114 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19115 num++; 19116 } 19117 } 19118 } 19119 19120 @Override 19121 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19122 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19123 != PackageManager.PERMISSION_GRANTED) { 19124 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19125 + Binder.getCallingPid() 19126 + ", uid=" + Binder.getCallingUid() 19127 + " requires " + INTERACT_ACROSS_USERS_FULL; 19128 Slog.w(TAG, msg); 19129 throw new SecurityException(msg); 19130 } 19131 19132 mUserSwitchObservers.register(observer); 19133 } 19134 19135 @Override 19136 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19137 mUserSwitchObservers.unregister(observer); 19138 } 19139 19140 private boolean userExists(int userId) { 19141 if (userId == 0) { 19142 return true; 19143 } 19144 UserManagerService ums = getUserManagerLocked(); 19145 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19146 } 19147 19148 int[] getUsersLocked() { 19149 UserManagerService ums = getUserManagerLocked(); 19150 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19151 } 19152 19153 UserManagerService getUserManagerLocked() { 19154 if (mUserManager == null) { 19155 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19156 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19157 } 19158 return mUserManager; 19159 } 19160 19161 private int applyUserId(int uid, int userId) { 19162 return UserHandle.getUid(userId, uid); 19163 } 19164 19165 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19166 if (info == null) return null; 19167 ApplicationInfo newInfo = new ApplicationInfo(info); 19168 newInfo.uid = applyUserId(info.uid, userId); 19169 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19170 + info.packageName; 19171 return newInfo; 19172 } 19173 19174 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19175 if (aInfo == null 19176 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19177 return aInfo; 19178 } 19179 19180 ActivityInfo info = new ActivityInfo(aInfo); 19181 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19182 return info; 19183 } 19184 19185 private final class LocalService extends ActivityManagerInternal { 19186 @Override 19187 public void goingToSleep() { 19188 ActivityManagerService.this.goingToSleep(); 19189 } 19190 19191 @Override 19192 public void wakingUp() { 19193 ActivityManagerService.this.wakingUp(); 19194 } 19195 19196 @Override 19197 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19198 String processName, String abiOverride, int uid, Runnable crashHandler) { 19199 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19200 processName, abiOverride, uid, crashHandler); 19201 } 19202 } 19203 19204 /** 19205 * An implementation of IAppTask, that allows an app to manage its own tasks via 19206 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19207 * only the process that calls getAppTasks() can call the AppTask methods. 19208 */ 19209 class AppTaskImpl extends IAppTask.Stub { 19210 private int mTaskId; 19211 private int mCallingUid; 19212 19213 public AppTaskImpl(int taskId, int callingUid) { 19214 mTaskId = taskId; 19215 mCallingUid = callingUid; 19216 } 19217 19218 private void checkCaller() { 19219 if (mCallingUid != Binder.getCallingUid()) { 19220 throw new SecurityException("Caller " + mCallingUid 19221 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19222 } 19223 } 19224 19225 @Override 19226 public void finishAndRemoveTask() { 19227 checkCaller(); 19228 19229 synchronized (ActivityManagerService.this) { 19230 long origId = Binder.clearCallingIdentity(); 19231 try { 19232 if (!removeTaskByIdLocked(mTaskId, false)) { 19233 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19234 } 19235 } finally { 19236 Binder.restoreCallingIdentity(origId); 19237 } 19238 } 19239 } 19240 19241 @Override 19242 public ActivityManager.RecentTaskInfo getTaskInfo() { 19243 checkCaller(); 19244 19245 synchronized (ActivityManagerService.this) { 19246 long origId = Binder.clearCallingIdentity(); 19247 try { 19248 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19249 if (tr == null) { 19250 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19251 } 19252 return createRecentTaskInfoFromTaskRecord(tr); 19253 } finally { 19254 Binder.restoreCallingIdentity(origId); 19255 } 19256 } 19257 } 19258 19259 @Override 19260 public void moveToFront() { 19261 checkCaller(); 19262 19263 final TaskRecord tr; 19264 synchronized (ActivityManagerService.this) { 19265 tr = recentTaskForIdLocked(mTaskId); 19266 if (tr == null) { 19267 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19268 } 19269 if (tr.getRootActivity() != null) { 19270 moveTaskToFrontLocked(tr.taskId, 0, null); 19271 return; 19272 } 19273 } 19274 19275 startActivityFromRecentsInner(tr.taskId, null); 19276 } 19277 19278 @Override 19279 public int startActivity(IBinder whoThread, String callingPackage, 19280 Intent intent, String resolvedType, Bundle options) { 19281 checkCaller(); 19282 19283 int callingUser = UserHandle.getCallingUserId(); 19284 TaskRecord tr; 19285 IApplicationThread appThread; 19286 synchronized (ActivityManagerService.this) { 19287 tr = recentTaskForIdLocked(mTaskId); 19288 if (tr == null) { 19289 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19290 } 19291 appThread = ApplicationThreadNative.asInterface(whoThread); 19292 if (appThread == null) { 19293 throw new IllegalArgumentException("Bad app thread " + appThread); 19294 } 19295 } 19296 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19297 resolvedType, null, null, null, null, 0, 0, null, null, 19298 null, options, callingUser, null, tr); 19299 } 19300 19301 @Override 19302 public void setExcludeFromRecents(boolean exclude) { 19303 checkCaller(); 19304 19305 synchronized (ActivityManagerService.this) { 19306 long origId = Binder.clearCallingIdentity(); 19307 try { 19308 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19309 if (tr == null) { 19310 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19311 } 19312 Intent intent = tr.getBaseIntent(); 19313 if (exclude) { 19314 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19315 } else { 19316 intent.setFlags(intent.getFlags() 19317 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19318 } 19319 } finally { 19320 Binder.restoreCallingIdentity(origId); 19321 } 19322 } 19323 } 19324 } 19325} 19326