ActivityManagerService.java revision 57a873fcaa4dd95fc844887b0c255f650b9159e5
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.ITaskStackListener; 41import android.app.ProfilerInfo; 42import android.app.admin.DevicePolicyManager; 43import android.app.usage.UsageEvents; 44import android.app.usage.UsageStatsManagerInternal; 45import android.appwidget.AppWidgetManager; 46import android.content.res.Resources; 47import android.graphics.Bitmap; 48import android.graphics.Point; 49import android.graphics.Rect; 50import android.os.BatteryStats; 51import android.os.PersistableBundle; 52import android.os.storage.IMountService; 53import android.os.storage.StorageManager; 54import android.service.voice.IVoiceInteractionSession; 55import android.util.ArrayMap; 56import android.util.ArraySet; 57import android.util.SparseIntArray; 58 59import com.android.internal.R; 60import com.android.internal.annotations.GuardedBy; 61import com.android.internal.app.IAppOpsService; 62import com.android.internal.app.IVoiceInteractor; 63import com.android.internal.app.ProcessMap; 64import com.android.internal.app.ProcessStats; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.Installer; 85import com.android.server.pm.UserManagerService; 86import com.android.server.statusbar.StatusBarManagerInternal; 87import com.android.server.wm.AppTransition; 88import com.android.server.wm.WindowManagerService; 89import com.google.android.collect.Lists; 90import com.google.android.collect.Maps; 91 92import libcore.io.IoUtils; 93 94import org.xmlpull.v1.XmlPullParser; 95import org.xmlpull.v1.XmlPullParserException; 96import org.xmlpull.v1.XmlSerializer; 97 98import android.app.Activity; 99import android.app.ActivityManager; 100import android.app.ActivityManager.RunningTaskInfo; 101import android.app.ActivityManager.StackInfo; 102import android.app.ActivityManagerInternal; 103import android.app.ActivityManagerNative; 104import android.app.ActivityOptions; 105import android.app.ActivityThread; 106import android.app.AlertDialog; 107import android.app.AppGlobals; 108import android.app.ApplicationErrorReport; 109import android.app.Dialog; 110import android.app.IActivityController; 111import android.app.IApplicationThread; 112import android.app.IInstrumentationWatcher; 113import android.app.INotificationManager; 114import android.app.IProcessObserver; 115import android.app.IServiceConnection; 116import android.app.IStopUserCallback; 117import android.app.IUiAutomationConnection; 118import android.app.IUserSwitchObserver; 119import android.app.Instrumentation; 120import android.app.Notification; 121import android.app.NotificationManager; 122import android.app.PendingIntent; 123import android.app.backup.IBackupManager; 124import android.content.ActivityNotFoundException; 125import android.content.BroadcastReceiver; 126import android.content.ClipData; 127import android.content.ComponentCallbacks2; 128import android.content.ComponentName; 129import android.content.ContentProvider; 130import android.content.ContentResolver; 131import android.content.Context; 132import android.content.DialogInterface; 133import android.content.IContentProvider; 134import android.content.IIntentReceiver; 135import android.content.IIntentSender; 136import android.content.Intent; 137import android.content.IntentFilter; 138import android.content.IntentSender; 139import android.content.pm.ActivityInfo; 140import android.content.pm.ApplicationInfo; 141import android.content.pm.ConfigurationInfo; 142import android.content.pm.IPackageDataObserver; 143import android.content.pm.IPackageManager; 144import android.content.pm.InstrumentationInfo; 145import android.content.pm.PackageInfo; 146import android.content.pm.PackageManager; 147import android.content.pm.ParceledListSlice; 148import android.content.pm.UserInfo; 149import android.content.pm.PackageManager.NameNotFoundException; 150import android.content.pm.PathPermission; 151import android.content.pm.ProviderInfo; 152import android.content.pm.ResolveInfo; 153import android.content.pm.ServiceInfo; 154import android.content.res.CompatibilityInfo; 155import android.content.res.Configuration; 156import android.net.Proxy; 157import android.net.ProxyInfo; 158import android.net.Uri; 159import android.os.Binder; 160import android.os.Build; 161import android.os.Bundle; 162import android.os.Debug; 163import android.os.DropBoxManager; 164import android.os.Environment; 165import android.os.FactoryTest; 166import android.os.FileObserver; 167import android.os.FileUtils; 168import android.os.Handler; 169import android.os.IBinder; 170import android.os.IPermissionController; 171import android.os.IRemoteCallback; 172import android.os.IUserManager; 173import android.os.Looper; 174import android.os.Message; 175import android.os.Parcel; 176import android.os.ParcelFileDescriptor; 177import android.os.PowerManagerInternal; 178import android.os.Process; 179import android.os.RemoteCallbackList; 180import android.os.RemoteException; 181import android.os.SELinux; 182import android.os.ServiceManager; 183import android.os.StrictMode; 184import android.os.SystemClock; 185import android.os.SystemProperties; 186import android.os.UpdateLock; 187import android.os.UserHandle; 188import android.os.UserManager; 189import android.provider.Settings; 190import android.text.format.DateUtils; 191import android.text.format.Time; 192import android.util.AtomicFile; 193import android.util.EventLog; 194import android.util.Log; 195import android.util.Pair; 196import android.util.PrintWriterPrinter; 197import android.util.Slog; 198import android.util.SparseArray; 199import android.util.TimeUtils; 200import android.util.Xml; 201import android.view.Gravity; 202import android.view.LayoutInflater; 203import android.view.View; 204import android.view.WindowManager; 205 206import dalvik.system.VMRuntime; 207 208import java.io.BufferedInputStream; 209import java.io.BufferedOutputStream; 210import java.io.DataInputStream; 211import java.io.DataOutputStream; 212import java.io.File; 213import java.io.FileDescriptor; 214import java.io.FileInputStream; 215import java.io.FileNotFoundException; 216import java.io.FileOutputStream; 217import java.io.IOException; 218import java.io.InputStreamReader; 219import java.io.PrintWriter; 220import java.io.StringWriter; 221import java.lang.ref.WeakReference; 222import java.util.ArrayList; 223import java.util.Arrays; 224import java.util.Collections; 225import java.util.Comparator; 226import java.util.HashMap; 227import java.util.HashSet; 228import java.util.Iterator; 229import java.util.List; 230import java.util.Locale; 231import java.util.Map; 232import java.util.Set; 233import java.util.concurrent.atomic.AtomicBoolean; 234import java.util.concurrent.atomic.AtomicLong; 235 236public final class ActivityManagerService extends ActivityManagerNative 237 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 238 239 private static final String USER_DATA_DIR = "/data/user/"; 240 // File that stores last updated system version and called preboot receivers 241 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 242 243 static final String TAG = "ActivityManager"; 244 static final String TAG_MU = "ActivityManagerServiceMU"; 245 static final boolean DEBUG = false; 246 static final boolean localLOGV = DEBUG; 247 static final boolean DEBUG_BACKUP = localLOGV || false; 248 static final boolean DEBUG_BROADCAST = localLOGV || false; 249 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 250 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_CLEANUP = localLOGV || false; 252 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 253 static final boolean DEBUG_FOCUS = false; 254 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 255 static final boolean DEBUG_MU = localLOGV || false; 256 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 257 static final boolean DEBUG_LRU = localLOGV || false; 258 static final boolean DEBUG_PAUSE = localLOGV || false; 259 static final boolean DEBUG_POWER = localLOGV || false; 260 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 261 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 262 static final boolean DEBUG_PROCESSES = localLOGV || false; 263 static final boolean DEBUG_PROVIDER = localLOGV || false; 264 static final boolean DEBUG_RESULTS = localLOGV || false; 265 static final boolean DEBUG_SERVICE = localLOGV || false; 266 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 267 static final boolean DEBUG_STACK = localLOGV || false; 268 static final boolean DEBUG_SWITCH = localLOGV || false; 269 static final boolean DEBUG_TASKS = localLOGV || false; 270 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 271 static final boolean DEBUG_TRANSITION = localLOGV || false; 272 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 273 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 274 static final boolean DEBUG_VISBILITY = localLOGV || false; 275 static final boolean DEBUG_PSS = localLOGV || false; 276 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 277 static final boolean DEBUG_RECENTS = localLOGV || false; 278 static final boolean VALIDATE_TOKENS = false; 279 static final boolean SHOW_ACTIVITY_START_TIME = true; 280 281 // Control over CPU and battery monitoring. 282 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 283 static final boolean MONITOR_CPU_USAGE = true; 284 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 285 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 286 static final boolean MONITOR_THREAD_CPU_USAGE = false; 287 288 // The flags that are set for all calls we make to the package manager. 289 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 290 291 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 292 293 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 294 295 // Maximum number recent bitmaps to keep in memory. 296 static final int MAX_RECENT_BITMAPS = 3; 297 298 // Amount of time after a call to stopAppSwitches() during which we will 299 // prevent further untrusted switches from happening. 300 static final long APP_SWITCH_DELAY_TIME = 5*1000; 301 302 // How long we wait for a launched process to attach to the activity manager 303 // before we decide it's never going to come up for real. 304 static final int PROC_START_TIMEOUT = 10*1000; 305 306 // How long we wait for a launched process to attach to the activity manager 307 // before we decide it's never going to come up for real, when the process was 308 // started with a wrapper for instrumentation (such as Valgrind) because it 309 // could take much longer than usual. 310 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 311 312 // How long to wait after going idle before forcing apps to GC. 313 static final int GC_TIMEOUT = 5*1000; 314 315 // The minimum amount of time between successive GC requests for a process. 316 static final int GC_MIN_INTERVAL = 60*1000; 317 318 // The minimum amount of time between successive PSS requests for a process. 319 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 320 321 // The minimum amount of time between successive PSS requests for a process 322 // when the request is due to the memory state being lowered. 323 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 324 325 // The rate at which we check for apps using excessive power -- 15 mins. 326 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on wake locks to start killing things. 330 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // The minimum sample duration we will allow before deciding we have 333 // enough data on CPU usage to start killing things. 334 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 335 336 // How long we allow a receiver to run before giving up on it. 337 static final int BROADCAST_FG_TIMEOUT = 10*1000; 338 static final int BROADCAST_BG_TIMEOUT = 60*1000; 339 340 // How long we wait until we timeout on key dispatching. 341 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 342 343 // How long we wait until we timeout on key dispatching during instrumentation. 344 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 345 346 // Amount of time we wait for observers to handle a user switch before 347 // giving up on them and unfreezing the screen. 348 static final int USER_SWITCH_TIMEOUT = 2*1000; 349 350 // Maximum number of users we allow to be running at a time. 351 static final int MAX_RUNNING_USERS = 3; 352 353 // How long to wait in getAssistContextExtras for the activity and foreground services 354 // to respond with the result. 355 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 356 357 // Maximum number of persisted Uri grants a package is allowed 358 static final int MAX_PERSISTED_URI_GRANTS = 128; 359 360 static final int MY_PID = Process.myPid(); 361 362 static final String[] EMPTY_STRING_ARRAY = new String[0]; 363 364 // How many bytes to write into the dropbox log before truncating 365 static final int DROPBOX_MAX_SIZE = 256 * 1024; 366 367 // Access modes for handleIncomingUser. 368 static final int ALLOW_NON_FULL = 0; 369 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 370 static final int ALLOW_FULL_ONLY = 2; 371 372 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 373 374 // Delay in notifying task stack change listeners (in millis) 375 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 376 377 /** All system services */ 378 SystemServiceManager mSystemServiceManager; 379 380 private Installer mInstaller; 381 382 /** Run all ActivityStacks through this */ 383 ActivityStackSupervisor mStackSupervisor; 384 385 /** Task stack change listeners. */ 386 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 387 new RemoteCallbackList<ITaskStackListener>(); 388 389 public IntentFirewall mIntentFirewall; 390 391 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 392 // default actuion automatically. Important for devices without direct input 393 // devices. 394 private boolean mShowDialogs = true; 395 396 BroadcastQueue mFgBroadcastQueue; 397 BroadcastQueue mBgBroadcastQueue; 398 // Convenient for easy iteration over the queues. Foreground is first 399 // so that dispatch of foreground broadcasts gets precedence. 400 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 401 402 BroadcastQueue broadcastQueueForIntent(Intent intent) { 403 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 404 if (DEBUG_BACKGROUND_BROADCAST) { 405 Slog.i(TAG, "Broadcast intent " + intent + " on " 406 + (isFg ? "foreground" : "background") 407 + " queue"); 408 } 409 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 410 } 411 412 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 413 for (BroadcastQueue queue : mBroadcastQueues) { 414 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 415 if (r != null) { 416 return r; 417 } 418 } 419 return null; 420 } 421 422 /** 423 * Activity we have told the window manager to have key focus. 424 */ 425 ActivityRecord mFocusedActivity = null; 426 427 /** 428 * List of intents that were used to start the most recent tasks. 429 */ 430 ArrayList<TaskRecord> mRecentTasks; 431 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 432 433 /** 434 * For addAppTask: cached of the last activity component that was added. 435 */ 436 ComponentName mLastAddedTaskComponent; 437 438 /** 439 * For addAppTask: cached of the last activity uid that was added. 440 */ 441 int mLastAddedTaskUid; 442 443 /** 444 * For addAppTask: cached of the last ActivityInfo that was added. 445 */ 446 ActivityInfo mLastAddedTaskActivity; 447 448 public class PendingAssistExtras extends Binder implements Runnable { 449 public final ActivityRecord activity; 450 public final Bundle extras; 451 public final Intent intent; 452 public final String hint; 453 public final int userHandle; 454 public boolean haveResult = false; 455 public Bundle result = null; 456 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 457 String _hint, int _userHandle) { 458 activity = _activity; 459 extras = _extras; 460 intent = _intent; 461 hint = _hint; 462 userHandle = _userHandle; 463 } 464 @Override 465 public void run() { 466 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 467 synchronized (this) { 468 haveResult = true; 469 notifyAll(); 470 } 471 } 472 } 473 474 final ArrayList<PendingAssistExtras> mPendingAssistExtras 475 = new ArrayList<PendingAssistExtras>(); 476 477 /** 478 * Process management. 479 */ 480 final ProcessList mProcessList = new ProcessList(); 481 482 /** 483 * All of the applications we currently have running organized by name. 484 * The keys are strings of the application package name (as 485 * returned by the package manager), and the keys are ApplicationRecord 486 * objects. 487 */ 488 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 489 490 /** 491 * Tracking long-term execution of processes to look for abuse and other 492 * bad app behavior. 493 */ 494 final ProcessStatsService mProcessStats; 495 496 /** 497 * The currently running isolated processes. 498 */ 499 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 500 501 /** 502 * Counter for assigning isolated process uids, to avoid frequently reusing the 503 * same ones. 504 */ 505 int mNextIsolatedProcessUid = 0; 506 507 /** 508 * The currently running heavy-weight process, if any. 509 */ 510 ProcessRecord mHeavyWeightProcess = null; 511 512 /** 513 * The last time that various processes have crashed. 514 */ 515 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 516 517 /** 518 * Information about a process that is currently marked as bad. 519 */ 520 static final class BadProcessInfo { 521 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 522 this.time = time; 523 this.shortMsg = shortMsg; 524 this.longMsg = longMsg; 525 this.stack = stack; 526 } 527 528 final long time; 529 final String shortMsg; 530 final String longMsg; 531 final String stack; 532 } 533 534 /** 535 * Set of applications that we consider to be bad, and will reject 536 * incoming broadcasts from (which the user has no control over). 537 * Processes are added to this set when they have crashed twice within 538 * a minimum amount of time; they are removed from it when they are 539 * later restarted (hopefully due to some user action). The value is the 540 * time it was added to the list. 541 */ 542 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 543 544 /** 545 * All of the processes we currently have running organized by pid. 546 * The keys are the pid running the application. 547 * 548 * <p>NOTE: This object is protected by its own lock, NOT the global 549 * activity manager lock! 550 */ 551 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 552 553 /** 554 * All of the processes that have been forced to be foreground. The key 555 * is the pid of the caller who requested it (we hold a death 556 * link on it). 557 */ 558 abstract class ForegroundToken implements IBinder.DeathRecipient { 559 int pid; 560 IBinder token; 561 } 562 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 563 564 /** 565 * List of records for processes that someone had tried to start before the 566 * system was ready. We don't start them at that point, but ensure they 567 * are started by the time booting is complete. 568 */ 569 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 570 571 /** 572 * List of persistent applications that are in the process 573 * of being started. 574 */ 575 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 576 577 /** 578 * Processes that are being forcibly torn down. 579 */ 580 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 581 582 /** 583 * List of running applications, sorted by recent usage. 584 * The first entry in the list is the least recently used. 585 */ 586 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 587 588 /** 589 * Where in mLruProcesses that the processes hosting activities start. 590 */ 591 int mLruProcessActivityStart = 0; 592 593 /** 594 * Where in mLruProcesses that the processes hosting services start. 595 * This is after (lower index) than mLruProcessesActivityStart. 596 */ 597 int mLruProcessServiceStart = 0; 598 599 /** 600 * List of processes that should gc as soon as things are idle. 601 */ 602 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 603 604 /** 605 * Processes we want to collect PSS data from. 606 */ 607 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 608 609 /** 610 * Last time we requested PSS data of all processes. 611 */ 612 long mLastFullPssTime = SystemClock.uptimeMillis(); 613 614 /** 615 * If set, the next time we collect PSS data we should do a full collection 616 * with data from native processes and the kernel. 617 */ 618 boolean mFullPssPending = false; 619 620 /** 621 * This is the process holding what we currently consider to be 622 * the "home" activity. 623 */ 624 ProcessRecord mHomeProcess; 625 626 /** 627 * This is the process holding the activity the user last visited that 628 * is in a different process from the one they are currently in. 629 */ 630 ProcessRecord mPreviousProcess; 631 632 /** 633 * The time at which the previous process was last visible. 634 */ 635 long mPreviousProcessVisibleTime; 636 637 /** 638 * Which uses have been started, so are allowed to run code. 639 */ 640 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 641 642 /** 643 * LRU list of history of current users. Most recently current is at the end. 644 */ 645 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 646 647 /** 648 * Constant array of the users that are currently started. 649 */ 650 int[] mStartedUserArray = new int[] { 0 }; 651 652 /** 653 * Registered observers of the user switching mechanics. 654 */ 655 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 656 = new RemoteCallbackList<IUserSwitchObserver>(); 657 658 /** 659 * Currently active user switch. 660 */ 661 Object mCurUserSwitchCallback; 662 663 /** 664 * Packages that the user has asked to have run in screen size 665 * compatibility mode instead of filling the screen. 666 */ 667 final CompatModePackages mCompatModePackages; 668 669 /** 670 * Set of IntentSenderRecord objects that are currently active. 671 */ 672 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 673 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 674 675 /** 676 * Fingerprints (hashCode()) of stack traces that we've 677 * already logged DropBox entries for. Guarded by itself. If 678 * something (rogue user app) forces this over 679 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 680 */ 681 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 682 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 683 684 /** 685 * Strict Mode background batched logging state. 686 * 687 * The string buffer is guarded by itself, and its lock is also 688 * used to determine if another batched write is already 689 * in-flight. 690 */ 691 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 692 693 /** 694 * Keeps track of all IIntentReceivers that have been registered for 695 * broadcasts. Hash keys are the receiver IBinder, hash value is 696 * a ReceiverList. 697 */ 698 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 699 new HashMap<IBinder, ReceiverList>(); 700 701 /** 702 * Resolver for broadcast intents to registered receivers. 703 * Holds BroadcastFilter (subclass of IntentFilter). 704 */ 705 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 706 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 707 @Override 708 protected boolean allowFilterResult( 709 BroadcastFilter filter, List<BroadcastFilter> dest) { 710 IBinder target = filter.receiverList.receiver.asBinder(); 711 for (int i=dest.size()-1; i>=0; i--) { 712 if (dest.get(i).receiverList.receiver.asBinder() == target) { 713 return false; 714 } 715 } 716 return true; 717 } 718 719 @Override 720 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 721 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 722 || userId == filter.owningUserId) { 723 return super.newResult(filter, match, userId); 724 } 725 return null; 726 } 727 728 @Override 729 protected BroadcastFilter[] newArray(int size) { 730 return new BroadcastFilter[size]; 731 } 732 733 @Override 734 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 735 return packageName.equals(filter.packageName); 736 } 737 }; 738 739 /** 740 * State of all active sticky broadcasts per user. Keys are the action of the 741 * sticky Intent, values are an ArrayList of all broadcasted intents with 742 * that action (which should usually be one). The SparseArray is keyed 743 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 744 * for stickies that are sent to all users. 745 */ 746 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 747 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 748 749 final ActiveServices mServices; 750 751 /** 752 * Backup/restore process management 753 */ 754 String mBackupAppName = null; 755 BackupRecord mBackupTarget = null; 756 757 final ProviderMap mProviderMap; 758 759 /** 760 * List of content providers who have clients waiting for them. The 761 * application is currently being launched and the provider will be 762 * removed from this list once it is published. 763 */ 764 final ArrayList<ContentProviderRecord> mLaunchingProviders 765 = new ArrayList<ContentProviderRecord>(); 766 767 /** 768 * File storing persisted {@link #mGrantedUriPermissions}. 769 */ 770 private final AtomicFile mGrantFile; 771 772 /** XML constants used in {@link #mGrantFile} */ 773 private static final String TAG_URI_GRANTS = "uri-grants"; 774 private static final String TAG_URI_GRANT = "uri-grant"; 775 private static final String ATTR_USER_HANDLE = "userHandle"; 776 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 777 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 778 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 779 private static final String ATTR_TARGET_PKG = "targetPkg"; 780 private static final String ATTR_URI = "uri"; 781 private static final String ATTR_MODE_FLAGS = "modeFlags"; 782 private static final String ATTR_CREATED_TIME = "createdTime"; 783 private static final String ATTR_PREFIX = "prefix"; 784 785 /** 786 * Global set of specific {@link Uri} permissions that have been granted. 787 * This optimized lookup structure maps from {@link UriPermission#targetUid} 788 * to {@link UriPermission#uri} to {@link UriPermission}. 789 */ 790 @GuardedBy("this") 791 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 792 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 793 794 public static class GrantUri { 795 public final int sourceUserId; 796 public final Uri uri; 797 public boolean prefix; 798 799 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 800 this.sourceUserId = sourceUserId; 801 this.uri = uri; 802 this.prefix = prefix; 803 } 804 805 @Override 806 public int hashCode() { 807 int hashCode = 1; 808 hashCode = 31 * hashCode + sourceUserId; 809 hashCode = 31 * hashCode + uri.hashCode(); 810 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 811 return hashCode; 812 } 813 814 @Override 815 public boolean equals(Object o) { 816 if (o instanceof GrantUri) { 817 GrantUri other = (GrantUri) o; 818 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 819 && prefix == other.prefix; 820 } 821 return false; 822 } 823 824 @Override 825 public String toString() { 826 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 827 if (prefix) result += " [prefix]"; 828 return result; 829 } 830 831 public String toSafeString() { 832 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 833 if (prefix) result += " [prefix]"; 834 return result; 835 } 836 837 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 838 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 839 ContentProvider.getUriWithoutUserId(uri), false); 840 } 841 } 842 843 CoreSettingsObserver mCoreSettingsObserver; 844 845 /** 846 * Thread-local storage used to carry caller permissions over through 847 * indirect content-provider access. 848 */ 849 private class Identity { 850 public final IBinder token; 851 public final int pid; 852 public final int uid; 853 854 Identity(IBinder _token, int _pid, int _uid) { 855 token = _token; 856 pid = _pid; 857 uid = _uid; 858 } 859 } 860 861 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 862 863 /** 864 * All information we have collected about the runtime performance of 865 * any user id that can impact battery performance. 866 */ 867 final BatteryStatsService mBatteryStatsService; 868 869 /** 870 * Information about component usage 871 */ 872 UsageStatsManagerInternal mUsageStatsService; 873 874 /** 875 * Information about and control over application operations 876 */ 877 final AppOpsService mAppOpsService; 878 879 /** 880 * Save recent tasks information across reboots. 881 */ 882 final TaskPersister mTaskPersister; 883 884 /** 885 * Current configuration information. HistoryRecord objects are given 886 * a reference to this object to indicate which configuration they are 887 * currently running in, so this object must be kept immutable. 888 */ 889 Configuration mConfiguration = new Configuration(); 890 891 /** 892 * Current sequencing integer of the configuration, for skipping old 893 * configurations. 894 */ 895 int mConfigurationSeq = 0; 896 897 /** 898 * Hardware-reported OpenGLES version. 899 */ 900 final int GL_ES_VERSION; 901 902 /** 903 * List of initialization arguments to pass to all processes when binding applications to them. 904 * For example, references to the commonly used services. 905 */ 906 HashMap<String, IBinder> mAppBindArgs; 907 908 /** 909 * Temporary to avoid allocations. Protected by main lock. 910 */ 911 final StringBuilder mStringBuilder = new StringBuilder(256); 912 913 /** 914 * Used to control how we initialize the service. 915 */ 916 ComponentName mTopComponent; 917 String mTopAction = Intent.ACTION_MAIN; 918 String mTopData; 919 boolean mProcessesReady = false; 920 boolean mSystemReady = false; 921 boolean mBooting = false; 922 boolean mCallFinishBooting = false; 923 boolean mBootAnimationComplete = false; 924 boolean mWaitingUpdate = false; 925 boolean mDidUpdate = false; 926 boolean mOnBattery = false; 927 boolean mLaunchWarningShown = false; 928 929 Context mContext; 930 931 int mFactoryTest; 932 933 boolean mCheckedForSetup; 934 935 /** 936 * The time at which we will allow normal application switches again, 937 * after a call to {@link #stopAppSwitches()}. 938 */ 939 long mAppSwitchesAllowedTime; 940 941 /** 942 * This is set to true after the first switch after mAppSwitchesAllowedTime 943 * is set; any switches after that will clear the time. 944 */ 945 boolean mDidAppSwitch; 946 947 /** 948 * Last time (in realtime) at which we checked for power usage. 949 */ 950 long mLastPowerCheckRealtime; 951 952 /** 953 * Last time (in uptime) at which we checked for power usage. 954 */ 955 long mLastPowerCheckUptime; 956 957 /** 958 * Set while we are wanting to sleep, to prevent any 959 * activities from being started/resumed. 960 */ 961 private boolean mSleeping = false; 962 963 /** 964 * Set while we are running a voice interaction. This overrides 965 * sleeping while it is active. 966 */ 967 private boolean mRunningVoice = false; 968 969 /** 970 * State of external calls telling us if the device is awake or asleep. 971 */ 972 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 973 974 static final int LOCK_SCREEN_HIDDEN = 0; 975 static final int LOCK_SCREEN_LEAVING = 1; 976 static final int LOCK_SCREEN_SHOWN = 2; 977 /** 978 * State of external call telling us if the lock screen is shown. 979 */ 980 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 981 982 /** 983 * Set if we are shutting down the system, similar to sleeping. 984 */ 985 boolean mShuttingDown = false; 986 987 /** 988 * Current sequence id for oom_adj computation traversal. 989 */ 990 int mAdjSeq = 0; 991 992 /** 993 * Current sequence id for process LRU updating. 994 */ 995 int mLruSeq = 0; 996 997 /** 998 * Keep track of the non-cached/empty process we last found, to help 999 * determine how to distribute cached/empty processes next time. 1000 */ 1001 int mNumNonCachedProcs = 0; 1002 1003 /** 1004 * Keep track of the number of cached hidden procs, to balance oom adj 1005 * distribution between those and empty procs. 1006 */ 1007 int mNumCachedHiddenProcs = 0; 1008 1009 /** 1010 * Keep track of the number of service processes we last found, to 1011 * determine on the next iteration which should be B services. 1012 */ 1013 int mNumServiceProcs = 0; 1014 int mNewNumAServiceProcs = 0; 1015 int mNewNumServiceProcs = 0; 1016 1017 /** 1018 * Allow the current computed overall memory level of the system to go down? 1019 * This is set to false when we are killing processes for reasons other than 1020 * memory management, so that the now smaller process list will not be taken as 1021 * an indication that memory is tighter. 1022 */ 1023 boolean mAllowLowerMemLevel = false; 1024 1025 /** 1026 * The last computed memory level, for holding when we are in a state that 1027 * processes are going away for other reasons. 1028 */ 1029 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1030 1031 /** 1032 * The last total number of process we have, to determine if changes actually look 1033 * like a shrinking number of process due to lower RAM. 1034 */ 1035 int mLastNumProcesses; 1036 1037 /** 1038 * The uptime of the last time we performed idle maintenance. 1039 */ 1040 long mLastIdleTime = SystemClock.uptimeMillis(); 1041 1042 /** 1043 * Total time spent with RAM that has been added in the past since the last idle time. 1044 */ 1045 long mLowRamTimeSinceLastIdle = 0; 1046 1047 /** 1048 * If RAM is currently low, when that horrible situation started. 1049 */ 1050 long mLowRamStartTime = 0; 1051 1052 /** 1053 * For reporting to battery stats the current top application. 1054 */ 1055 private String mCurResumedPackage = null; 1056 private int mCurResumedUid = -1; 1057 1058 /** 1059 * For reporting to battery stats the apps currently running foreground 1060 * service. The ProcessMap is package/uid tuples; each of these contain 1061 * an array of the currently foreground processes. 1062 */ 1063 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1064 = new ProcessMap<ArrayList<ProcessRecord>>(); 1065 1066 /** 1067 * This is set if we had to do a delayed dexopt of an app before launching 1068 * it, to increase the ANR timeouts in that case. 1069 */ 1070 boolean mDidDexOpt; 1071 1072 /** 1073 * Set if the systemServer made a call to enterSafeMode. 1074 */ 1075 boolean mSafeMode; 1076 1077 String mDebugApp = null; 1078 boolean mWaitForDebugger = false; 1079 boolean mDebugTransient = false; 1080 String mOrigDebugApp = null; 1081 boolean mOrigWaitForDebugger = false; 1082 boolean mAlwaysFinishActivities = false; 1083 IActivityController mController = null; 1084 String mProfileApp = null; 1085 ProcessRecord mProfileProc = null; 1086 String mProfileFile; 1087 ParcelFileDescriptor mProfileFd; 1088 int mSamplingInterval = 0; 1089 boolean mAutoStopProfiler = false; 1090 int mProfileType = 0; 1091 String mOpenGlTraceApp = null; 1092 1093 static class ProcessChangeItem { 1094 static final int CHANGE_ACTIVITIES = 1<<0; 1095 static final int CHANGE_PROCESS_STATE = 1<<1; 1096 int changes; 1097 int uid; 1098 int pid; 1099 int processState; 1100 boolean foregroundActivities; 1101 } 1102 1103 final RemoteCallbackList<IProcessObserver> mProcessObservers 1104 = new RemoteCallbackList<IProcessObserver>(); 1105 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1106 1107 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1108 = new ArrayList<ProcessChangeItem>(); 1109 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1110 = new ArrayList<ProcessChangeItem>(); 1111 1112 /** 1113 * Runtime CPU use collection thread. This object's lock is used to 1114 * perform synchronization with the thread (notifying it to run). 1115 */ 1116 final Thread mProcessCpuThread; 1117 1118 /** 1119 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1120 * Must acquire this object's lock when accessing it. 1121 * NOTE: this lock will be held while doing long operations (trawling 1122 * through all processes in /proc), so it should never be acquired by 1123 * any critical paths such as when holding the main activity manager lock. 1124 */ 1125 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1126 MONITOR_THREAD_CPU_USAGE); 1127 final AtomicLong mLastCpuTime = new AtomicLong(0); 1128 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1129 1130 long mLastWriteTime = 0; 1131 1132 /** 1133 * Used to retain an update lock when the foreground activity is in 1134 * immersive mode. 1135 */ 1136 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1137 1138 /** 1139 * Set to true after the system has finished booting. 1140 */ 1141 boolean mBooted = false; 1142 1143 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1144 int mProcessLimitOverride = -1; 1145 1146 WindowManagerService mWindowManager; 1147 1148 final ActivityThread mSystemThread; 1149 1150 // Holds the current foreground user's id 1151 int mCurrentUserId = 0; 1152 // Holds the target user's id during a user switch 1153 int mTargetUserId = UserHandle.USER_NULL; 1154 // If there are multiple profiles for the current user, their ids are here 1155 // Currently only the primary user can have managed profiles 1156 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1157 1158 /** 1159 * Mapping from each known user ID to the profile group ID it is associated with. 1160 */ 1161 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1162 1163 private UserManagerService mUserManager; 1164 1165 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1166 final ProcessRecord mApp; 1167 final int mPid; 1168 final IApplicationThread mAppThread; 1169 1170 AppDeathRecipient(ProcessRecord app, int pid, 1171 IApplicationThread thread) { 1172 if (localLOGV) Slog.v( 1173 TAG, "New death recipient " + this 1174 + " for thread " + thread.asBinder()); 1175 mApp = app; 1176 mPid = pid; 1177 mAppThread = thread; 1178 } 1179 1180 @Override 1181 public void binderDied() { 1182 if (localLOGV) Slog.v( 1183 TAG, "Death received in " + this 1184 + " for thread " + mAppThread.asBinder()); 1185 synchronized(ActivityManagerService.this) { 1186 appDiedLocked(mApp, mPid, mAppThread); 1187 } 1188 } 1189 } 1190 1191 static final int SHOW_ERROR_MSG = 1; 1192 static final int SHOW_NOT_RESPONDING_MSG = 2; 1193 static final int SHOW_FACTORY_ERROR_MSG = 3; 1194 static final int UPDATE_CONFIGURATION_MSG = 4; 1195 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1196 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1197 static final int SERVICE_TIMEOUT_MSG = 12; 1198 static final int UPDATE_TIME_ZONE = 13; 1199 static final int SHOW_UID_ERROR_MSG = 14; 1200 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1201 static final int PROC_START_TIMEOUT_MSG = 20; 1202 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1203 static final int KILL_APPLICATION_MSG = 22; 1204 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1205 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1206 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1207 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1208 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1209 static final int CLEAR_DNS_CACHE_MSG = 28; 1210 static final int UPDATE_HTTP_PROXY_MSG = 29; 1211 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1212 static final int DISPATCH_PROCESSES_CHANGED = 31; 1213 static final int DISPATCH_PROCESS_DIED = 32; 1214 static final int REPORT_MEM_USAGE_MSG = 33; 1215 static final int REPORT_USER_SWITCH_MSG = 34; 1216 static final int CONTINUE_USER_SWITCH_MSG = 35; 1217 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1218 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1219 static final int PERSIST_URI_GRANTS_MSG = 38; 1220 static final int REQUEST_ALL_PSS_MSG = 39; 1221 static final int START_PROFILES_MSG = 40; 1222 static final int UPDATE_TIME = 41; 1223 static final int SYSTEM_USER_START_MSG = 42; 1224 static final int SYSTEM_USER_CURRENT_MSG = 43; 1225 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1226 static final int FINISH_BOOTING_MSG = 45; 1227 static final int START_USER_SWITCH_MSG = 46; 1228 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1229 static final int DISMISS_DIALOG_MSG = 48; 1230 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1231 1232 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1233 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1234 static final int FIRST_COMPAT_MODE_MSG = 300; 1235 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1236 1237 CompatModeDialog mCompatModeDialog; 1238 long mLastMemUsageReportTime = 0; 1239 1240 /** 1241 * Flag whether the current user is a "monkey", i.e. whether 1242 * the UI is driven by a UI automation tool. 1243 */ 1244 private boolean mUserIsMonkey; 1245 1246 /** Flag whether the device has a Recents UI */ 1247 boolean mHasRecents; 1248 1249 /** The dimensions of the thumbnails in the Recents UI. */ 1250 int mThumbnailWidth; 1251 int mThumbnailHeight; 1252 1253 final ServiceThread mHandlerThread; 1254 final MainHandler mHandler; 1255 1256 final class MainHandler extends Handler { 1257 public MainHandler(Looper looper) { 1258 super(looper, null, true); 1259 } 1260 1261 @Override 1262 public void handleMessage(Message msg) { 1263 switch (msg.what) { 1264 case SHOW_ERROR_MSG: { 1265 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1266 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1267 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1268 synchronized (ActivityManagerService.this) { 1269 ProcessRecord proc = (ProcessRecord)data.get("app"); 1270 AppErrorResult res = (AppErrorResult) data.get("result"); 1271 if (proc != null && proc.crashDialog != null) { 1272 Slog.e(TAG, "App already has crash dialog: " + proc); 1273 if (res != null) { 1274 res.set(0); 1275 } 1276 return; 1277 } 1278 boolean isBackground = (UserHandle.getAppId(proc.uid) 1279 >= Process.FIRST_APPLICATION_UID 1280 && proc.pid != MY_PID); 1281 for (int userId : mCurrentProfileIds) { 1282 isBackground &= (proc.userId != userId); 1283 } 1284 if (isBackground && !showBackground) { 1285 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1286 if (res != null) { 1287 res.set(0); 1288 } 1289 return; 1290 } 1291 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1292 Dialog d = new AppErrorDialog(mContext, 1293 ActivityManagerService.this, res, proc); 1294 d.show(); 1295 proc.crashDialog = d; 1296 } else { 1297 // The device is asleep, so just pretend that the user 1298 // saw a crash dialog and hit "force quit". 1299 if (res != null) { 1300 res.set(0); 1301 } 1302 } 1303 } 1304 1305 ensureBootCompleted(); 1306 } break; 1307 case SHOW_NOT_RESPONDING_MSG: { 1308 synchronized (ActivityManagerService.this) { 1309 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1310 ProcessRecord proc = (ProcessRecord)data.get("app"); 1311 if (proc != null && proc.anrDialog != null) { 1312 Slog.e(TAG, "App already has anr dialog: " + proc); 1313 return; 1314 } 1315 1316 Intent intent = new Intent("android.intent.action.ANR"); 1317 if (!mProcessesReady) { 1318 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1319 | Intent.FLAG_RECEIVER_FOREGROUND); 1320 } 1321 broadcastIntentLocked(null, null, intent, 1322 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1323 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1324 1325 if (mShowDialogs) { 1326 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1327 mContext, proc, (ActivityRecord)data.get("activity"), 1328 msg.arg1 != 0); 1329 d.show(); 1330 proc.anrDialog = d; 1331 } else { 1332 // Just kill the app if there is no dialog to be shown. 1333 killAppAtUsersRequest(proc, null); 1334 } 1335 } 1336 1337 ensureBootCompleted(); 1338 } break; 1339 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1340 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1341 synchronized (ActivityManagerService.this) { 1342 ProcessRecord proc = (ProcessRecord) data.get("app"); 1343 if (proc == null) { 1344 Slog.e(TAG, "App not found when showing strict mode dialog."); 1345 break; 1346 } 1347 if (proc.crashDialog != null) { 1348 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1349 return; 1350 } 1351 AppErrorResult res = (AppErrorResult) data.get("result"); 1352 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1353 Dialog d = new StrictModeViolationDialog(mContext, 1354 ActivityManagerService.this, res, proc); 1355 d.show(); 1356 proc.crashDialog = d; 1357 } else { 1358 // The device is asleep, so just pretend that the user 1359 // saw a crash dialog and hit "force quit". 1360 res.set(0); 1361 } 1362 } 1363 ensureBootCompleted(); 1364 } break; 1365 case SHOW_FACTORY_ERROR_MSG: { 1366 Dialog d = new FactoryErrorDialog( 1367 mContext, msg.getData().getCharSequence("msg")); 1368 d.show(); 1369 ensureBootCompleted(); 1370 } break; 1371 case UPDATE_CONFIGURATION_MSG: { 1372 final ContentResolver resolver = mContext.getContentResolver(); 1373 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1374 } break; 1375 case GC_BACKGROUND_PROCESSES_MSG: { 1376 synchronized (ActivityManagerService.this) { 1377 performAppGcsIfAppropriateLocked(); 1378 } 1379 } break; 1380 case WAIT_FOR_DEBUGGER_MSG: { 1381 synchronized (ActivityManagerService.this) { 1382 ProcessRecord app = (ProcessRecord)msg.obj; 1383 if (msg.arg1 != 0) { 1384 if (!app.waitedForDebugger) { 1385 Dialog d = new AppWaitingForDebuggerDialog( 1386 ActivityManagerService.this, 1387 mContext, app); 1388 app.waitDialog = d; 1389 app.waitedForDebugger = true; 1390 d.show(); 1391 } 1392 } else { 1393 if (app.waitDialog != null) { 1394 app.waitDialog.dismiss(); 1395 app.waitDialog = null; 1396 } 1397 } 1398 } 1399 } break; 1400 case SERVICE_TIMEOUT_MSG: { 1401 if (mDidDexOpt) { 1402 mDidDexOpt = false; 1403 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1404 nmsg.obj = msg.obj; 1405 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1406 return; 1407 } 1408 mServices.serviceTimeout((ProcessRecord)msg.obj); 1409 } break; 1410 case UPDATE_TIME_ZONE: { 1411 synchronized (ActivityManagerService.this) { 1412 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1413 ProcessRecord r = mLruProcesses.get(i); 1414 if (r.thread != null) { 1415 try { 1416 r.thread.updateTimeZone(); 1417 } catch (RemoteException ex) { 1418 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1419 } 1420 } 1421 } 1422 } 1423 } break; 1424 case CLEAR_DNS_CACHE_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1427 ProcessRecord r = mLruProcesses.get(i); 1428 if (r.thread != null) { 1429 try { 1430 r.thread.clearDnsCache(); 1431 } catch (RemoteException ex) { 1432 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1433 } 1434 } 1435 } 1436 } 1437 } break; 1438 case UPDATE_HTTP_PROXY_MSG: { 1439 ProxyInfo proxy = (ProxyInfo)msg.obj; 1440 String host = ""; 1441 String port = ""; 1442 String exclList = ""; 1443 Uri pacFileUrl = Uri.EMPTY; 1444 if (proxy != null) { 1445 host = proxy.getHost(); 1446 port = Integer.toString(proxy.getPort()); 1447 exclList = proxy.getExclusionListAsString(); 1448 pacFileUrl = proxy.getPacFileUrl(); 1449 } 1450 synchronized (ActivityManagerService.this) { 1451 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1452 ProcessRecord r = mLruProcesses.get(i); 1453 if (r.thread != null) { 1454 try { 1455 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1456 } catch (RemoteException ex) { 1457 Slog.w(TAG, "Failed to update http proxy for: " + 1458 r.info.processName); 1459 } 1460 } 1461 } 1462 } 1463 } break; 1464 case SHOW_UID_ERROR_MSG: { 1465 if (mShowDialogs) { 1466 AlertDialog d = new BaseErrorDialog(mContext); 1467 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1468 d.setCancelable(false); 1469 d.setTitle(mContext.getText(R.string.android_system_label)); 1470 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1471 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1472 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1473 d.show(); 1474 } 1475 } break; 1476 case SHOW_FINGERPRINT_ERROR_MSG: { 1477 if (mShowDialogs) { 1478 AlertDialog d = new BaseErrorDialog(mContext); 1479 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1480 d.setCancelable(false); 1481 d.setTitle(mContext.getText(R.string.android_system_label)); 1482 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1483 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1484 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1485 d.show(); 1486 } 1487 } break; 1488 case PROC_START_TIMEOUT_MSG: { 1489 if (mDidDexOpt) { 1490 mDidDexOpt = false; 1491 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1492 nmsg.obj = msg.obj; 1493 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1494 return; 1495 } 1496 ProcessRecord app = (ProcessRecord)msg.obj; 1497 synchronized (ActivityManagerService.this) { 1498 processStartTimedOutLocked(app); 1499 } 1500 } break; 1501 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1502 synchronized (ActivityManagerService.this) { 1503 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1504 } 1505 } break; 1506 case KILL_APPLICATION_MSG: { 1507 synchronized (ActivityManagerService.this) { 1508 int appid = msg.arg1; 1509 boolean restart = (msg.arg2 == 1); 1510 Bundle bundle = (Bundle)msg.obj; 1511 String pkg = bundle.getString("pkg"); 1512 String reason = bundle.getString("reason"); 1513 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1514 false, UserHandle.USER_ALL, reason); 1515 } 1516 } break; 1517 case FINALIZE_PENDING_INTENT_MSG: { 1518 ((PendingIntentRecord)msg.obj).completeFinalize(); 1519 } break; 1520 case POST_HEAVY_NOTIFICATION_MSG: { 1521 INotificationManager inm = NotificationManager.getService(); 1522 if (inm == null) { 1523 return; 1524 } 1525 1526 ActivityRecord root = (ActivityRecord)msg.obj; 1527 ProcessRecord process = root.app; 1528 if (process == null) { 1529 return; 1530 } 1531 1532 try { 1533 Context context = mContext.createPackageContext(process.info.packageName, 0); 1534 String text = mContext.getString(R.string.heavy_weight_notification, 1535 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1536 Notification notification = new Notification(); 1537 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1538 notification.when = 0; 1539 notification.flags = Notification.FLAG_ONGOING_EVENT; 1540 notification.tickerText = text; 1541 notification.defaults = 0; // please be quiet 1542 notification.sound = null; 1543 notification.vibrate = null; 1544 notification.color = mContext.getResources().getColor( 1545 com.android.internal.R.color.system_notification_accent_color); 1546 notification.setLatestEventInfo(context, text, 1547 mContext.getText(R.string.heavy_weight_notification_detail), 1548 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1549 PendingIntent.FLAG_CANCEL_CURRENT, null, 1550 new UserHandle(root.userId))); 1551 1552 try { 1553 int[] outId = new int[1]; 1554 inm.enqueueNotificationWithTag("android", "android", null, 1555 R.string.heavy_weight_notification, 1556 notification, outId, root.userId); 1557 } catch (RuntimeException e) { 1558 Slog.w(ActivityManagerService.TAG, 1559 "Error showing notification for heavy-weight app", e); 1560 } catch (RemoteException e) { 1561 } 1562 } catch (NameNotFoundException e) { 1563 Slog.w(TAG, "Unable to create context for heavy notification", e); 1564 } 1565 } break; 1566 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1567 INotificationManager inm = NotificationManager.getService(); 1568 if (inm == null) { 1569 return; 1570 } 1571 try { 1572 inm.cancelNotificationWithTag("android", null, 1573 R.string.heavy_weight_notification, msg.arg1); 1574 } catch (RuntimeException e) { 1575 Slog.w(ActivityManagerService.TAG, 1576 "Error canceling notification for service", e); 1577 } catch (RemoteException e) { 1578 } 1579 } break; 1580 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1581 synchronized (ActivityManagerService.this) { 1582 checkExcessivePowerUsageLocked(true); 1583 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1584 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1585 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1586 } 1587 } break; 1588 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1589 synchronized (ActivityManagerService.this) { 1590 ActivityRecord ar = (ActivityRecord)msg.obj; 1591 if (mCompatModeDialog != null) { 1592 if (mCompatModeDialog.mAppInfo.packageName.equals( 1593 ar.info.applicationInfo.packageName)) { 1594 return; 1595 } 1596 mCompatModeDialog.dismiss(); 1597 mCompatModeDialog = null; 1598 } 1599 if (ar != null && false) { 1600 if (mCompatModePackages.getPackageAskCompatModeLocked( 1601 ar.packageName)) { 1602 int mode = mCompatModePackages.computeCompatModeLocked( 1603 ar.info.applicationInfo); 1604 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1605 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1606 mCompatModeDialog = new CompatModeDialog( 1607 ActivityManagerService.this, mContext, 1608 ar.info.applicationInfo); 1609 mCompatModeDialog.show(); 1610 } 1611 } 1612 } 1613 } 1614 break; 1615 } 1616 case DISPATCH_PROCESSES_CHANGED: { 1617 dispatchProcessesChanged(); 1618 break; 1619 } 1620 case DISPATCH_PROCESS_DIED: { 1621 final int pid = msg.arg1; 1622 final int uid = msg.arg2; 1623 dispatchProcessDied(pid, uid); 1624 break; 1625 } 1626 case REPORT_MEM_USAGE_MSG: { 1627 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1628 Thread thread = new Thread() { 1629 @Override public void run() { 1630 reportMemUsage(memInfos); 1631 } 1632 }; 1633 thread.start(); 1634 break; 1635 } 1636 case START_USER_SWITCH_MSG: { 1637 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1638 break; 1639 } 1640 case REPORT_USER_SWITCH_MSG: { 1641 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1642 break; 1643 } 1644 case CONTINUE_USER_SWITCH_MSG: { 1645 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1646 break; 1647 } 1648 case USER_SWITCH_TIMEOUT_MSG: { 1649 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1650 break; 1651 } 1652 case IMMERSIVE_MODE_LOCK_MSG: { 1653 final boolean nextState = (msg.arg1 != 0); 1654 if (mUpdateLock.isHeld() != nextState) { 1655 if (DEBUG_IMMERSIVE) { 1656 final ActivityRecord r = (ActivityRecord) msg.obj; 1657 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1658 } 1659 if (nextState) { 1660 mUpdateLock.acquire(); 1661 } else { 1662 mUpdateLock.release(); 1663 } 1664 } 1665 break; 1666 } 1667 case PERSIST_URI_GRANTS_MSG: { 1668 writeGrantedUriPermissions(); 1669 break; 1670 } 1671 case REQUEST_ALL_PSS_MSG: { 1672 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1673 break; 1674 } 1675 case START_PROFILES_MSG: { 1676 synchronized (ActivityManagerService.this) { 1677 startProfilesLocked(); 1678 } 1679 break; 1680 } 1681 case UPDATE_TIME: { 1682 synchronized (ActivityManagerService.this) { 1683 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1684 ProcessRecord r = mLruProcesses.get(i); 1685 if (r.thread != null) { 1686 try { 1687 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1688 } catch (RemoteException ex) { 1689 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1690 } 1691 } 1692 } 1693 } 1694 break; 1695 } 1696 case SYSTEM_USER_START_MSG: { 1697 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1698 Integer.toString(msg.arg1), msg.arg1); 1699 mSystemServiceManager.startUser(msg.arg1); 1700 break; 1701 } 1702 case SYSTEM_USER_CURRENT_MSG: { 1703 mBatteryStatsService.noteEvent( 1704 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1705 Integer.toString(msg.arg2), msg.arg2); 1706 mBatteryStatsService.noteEvent( 1707 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1708 Integer.toString(msg.arg1), msg.arg1); 1709 mSystemServiceManager.switchUser(msg.arg1); 1710 break; 1711 } 1712 case ENTER_ANIMATION_COMPLETE_MSG: { 1713 synchronized (ActivityManagerService.this) { 1714 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1715 if (r != null && r.app != null && r.app.thread != null) { 1716 try { 1717 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1718 } catch (RemoteException e) { 1719 } 1720 } 1721 } 1722 break; 1723 } 1724 case FINISH_BOOTING_MSG: { 1725 if (msg.arg1 != 0) { 1726 finishBooting(); 1727 } 1728 if (msg.arg2 != 0) { 1729 enableScreenAfterBoot(); 1730 } 1731 break; 1732 } 1733 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1734 try { 1735 Locale l = (Locale) msg.obj; 1736 IBinder service = ServiceManager.getService("mount"); 1737 IMountService mountService = IMountService.Stub.asInterface(service); 1738 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1739 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1740 } catch (RemoteException e) { 1741 Log.e(TAG, "Error storing locale for decryption UI", e); 1742 } 1743 break; 1744 } 1745 case DISMISS_DIALOG_MSG: { 1746 final Dialog d = (Dialog) msg.obj; 1747 d.dismiss(); 1748 break; 1749 } 1750 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1751 synchronized (ActivityManagerService.this) { 1752 int i = mTaskStackListeners.beginBroadcast(); 1753 while (i > 0) { 1754 i--; 1755 try { 1756 // Make a one-way callback to the listener 1757 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1758 } catch (RemoteException e){ 1759 // Handled by the RemoteCallbackList 1760 } 1761 } 1762 mTaskStackListeners.finishBroadcast(); 1763 } 1764 break; 1765 } 1766 } 1767 } 1768 }; 1769 1770 static final int COLLECT_PSS_BG_MSG = 1; 1771 1772 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1773 @Override 1774 public void handleMessage(Message msg) { 1775 switch (msg.what) { 1776 case COLLECT_PSS_BG_MSG: { 1777 long start = SystemClock.uptimeMillis(); 1778 MemInfoReader memInfo = null; 1779 synchronized (ActivityManagerService.this) { 1780 if (mFullPssPending) { 1781 mFullPssPending = false; 1782 memInfo = new MemInfoReader(); 1783 } 1784 } 1785 if (memInfo != null) { 1786 updateCpuStatsNow(); 1787 long nativeTotalPss = 0; 1788 synchronized (mProcessCpuTracker) { 1789 final int N = mProcessCpuTracker.countStats(); 1790 for (int j=0; j<N; j++) { 1791 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1792 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1793 // This is definitely an application process; skip it. 1794 continue; 1795 } 1796 synchronized (mPidsSelfLocked) { 1797 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1798 // This is one of our own processes; skip it. 1799 continue; 1800 } 1801 } 1802 nativeTotalPss += Debug.getPss(st.pid, null); 1803 } 1804 } 1805 memInfo.readMemInfo(); 1806 synchronized (ActivityManagerService.this) { 1807 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1808 + (SystemClock.uptimeMillis()-start) + "ms"); 1809 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1810 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1811 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1812 } 1813 } 1814 1815 int i = 0; 1816 int num = 0; 1817 long[] tmp = new long[1]; 1818 do { 1819 ProcessRecord proc; 1820 int procState; 1821 int pid; 1822 synchronized (ActivityManagerService.this) { 1823 if (i >= mPendingPssProcesses.size()) { 1824 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1825 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1826 mPendingPssProcesses.clear(); 1827 return; 1828 } 1829 proc = mPendingPssProcesses.get(i); 1830 procState = proc.pssProcState; 1831 if (proc.thread != null && procState == proc.setProcState) { 1832 pid = proc.pid; 1833 } else { 1834 proc = null; 1835 pid = 0; 1836 } 1837 i++; 1838 } 1839 if (proc != null) { 1840 long pss = Debug.getPss(pid, tmp); 1841 synchronized (ActivityManagerService.this) { 1842 if (proc.thread != null && proc.setProcState == procState 1843 && proc.pid == pid) { 1844 num++; 1845 proc.lastPssTime = SystemClock.uptimeMillis(); 1846 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1847 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1848 + ": " + pss + " lastPss=" + proc.lastPss 1849 + " state=" + ProcessList.makeProcStateString(procState)); 1850 if (proc.initialIdlePss == 0) { 1851 proc.initialIdlePss = pss; 1852 } 1853 proc.lastPss = pss; 1854 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1855 proc.lastCachedPss = pss; 1856 } 1857 } 1858 } 1859 } 1860 } while (true); 1861 } 1862 } 1863 } 1864 }; 1865 1866 public void setSystemProcess() { 1867 try { 1868 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1869 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1870 ServiceManager.addService("meminfo", new MemBinder(this)); 1871 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1872 ServiceManager.addService("dbinfo", new DbBinder(this)); 1873 if (MONITOR_CPU_USAGE) { 1874 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1875 } 1876 ServiceManager.addService("permission", new PermissionController(this)); 1877 1878 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1879 "android", STOCK_PM_FLAGS); 1880 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1881 1882 synchronized (this) { 1883 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1884 app.persistent = true; 1885 app.pid = MY_PID; 1886 app.maxAdj = ProcessList.SYSTEM_ADJ; 1887 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1888 mProcessNames.put(app.processName, app.uid, app); 1889 synchronized (mPidsSelfLocked) { 1890 mPidsSelfLocked.put(app.pid, app); 1891 } 1892 updateLruProcessLocked(app, false, null); 1893 updateOomAdjLocked(); 1894 } 1895 } catch (PackageManager.NameNotFoundException e) { 1896 throw new RuntimeException( 1897 "Unable to find android system package", e); 1898 } 1899 } 1900 1901 public void setWindowManager(WindowManagerService wm) { 1902 mWindowManager = wm; 1903 mStackSupervisor.setWindowManager(wm); 1904 } 1905 1906 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1907 mUsageStatsService = usageStatsManager; 1908 } 1909 1910 public void startObservingNativeCrashes() { 1911 final NativeCrashListener ncl = new NativeCrashListener(this); 1912 ncl.start(); 1913 } 1914 1915 public IAppOpsService getAppOpsService() { 1916 return mAppOpsService; 1917 } 1918 1919 static class MemBinder extends Binder { 1920 ActivityManagerService mActivityManagerService; 1921 MemBinder(ActivityManagerService activityManagerService) { 1922 mActivityManagerService = activityManagerService; 1923 } 1924 1925 @Override 1926 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1927 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1928 != PackageManager.PERMISSION_GRANTED) { 1929 pw.println("Permission Denial: can't dump meminfo from from pid=" 1930 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1931 + " without permission " + android.Manifest.permission.DUMP); 1932 return; 1933 } 1934 1935 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1936 } 1937 } 1938 1939 static class GraphicsBinder extends Binder { 1940 ActivityManagerService mActivityManagerService; 1941 GraphicsBinder(ActivityManagerService activityManagerService) { 1942 mActivityManagerService = activityManagerService; 1943 } 1944 1945 @Override 1946 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1947 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1948 != PackageManager.PERMISSION_GRANTED) { 1949 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1950 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1951 + " without permission " + android.Manifest.permission.DUMP); 1952 return; 1953 } 1954 1955 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1956 } 1957 } 1958 1959 static class DbBinder extends Binder { 1960 ActivityManagerService mActivityManagerService; 1961 DbBinder(ActivityManagerService activityManagerService) { 1962 mActivityManagerService = activityManagerService; 1963 } 1964 1965 @Override 1966 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1967 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1968 != PackageManager.PERMISSION_GRANTED) { 1969 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1970 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1971 + " without permission " + android.Manifest.permission.DUMP); 1972 return; 1973 } 1974 1975 mActivityManagerService.dumpDbInfo(fd, pw, args); 1976 } 1977 } 1978 1979 static class CpuBinder extends Binder { 1980 ActivityManagerService mActivityManagerService; 1981 CpuBinder(ActivityManagerService activityManagerService) { 1982 mActivityManagerService = activityManagerService; 1983 } 1984 1985 @Override 1986 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1987 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1988 != PackageManager.PERMISSION_GRANTED) { 1989 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1990 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1991 + " without permission " + android.Manifest.permission.DUMP); 1992 return; 1993 } 1994 1995 synchronized (mActivityManagerService.mProcessCpuTracker) { 1996 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1997 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1998 SystemClock.uptimeMillis())); 1999 } 2000 } 2001 } 2002 2003 public static final class Lifecycle extends SystemService { 2004 private final ActivityManagerService mService; 2005 2006 public Lifecycle(Context context) { 2007 super(context); 2008 mService = new ActivityManagerService(context); 2009 } 2010 2011 @Override 2012 public void onStart() { 2013 mService.start(); 2014 } 2015 2016 public ActivityManagerService getService() { 2017 return mService; 2018 } 2019 } 2020 2021 // Note: This method is invoked on the main thread but may need to attach various 2022 // handlers to other threads. So take care to be explicit about the looper. 2023 public ActivityManagerService(Context systemContext) { 2024 mContext = systemContext; 2025 mFactoryTest = FactoryTest.getMode(); 2026 mSystemThread = ActivityThread.currentActivityThread(); 2027 2028 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2029 2030 mHandlerThread = new ServiceThread(TAG, 2031 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2032 mHandlerThread.start(); 2033 mHandler = new MainHandler(mHandlerThread.getLooper()); 2034 2035 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2036 "foreground", BROADCAST_FG_TIMEOUT, false); 2037 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2038 "background", BROADCAST_BG_TIMEOUT, true); 2039 mBroadcastQueues[0] = mFgBroadcastQueue; 2040 mBroadcastQueues[1] = mBgBroadcastQueue; 2041 2042 mServices = new ActiveServices(this); 2043 mProviderMap = new ProviderMap(this); 2044 2045 // TODO: Move creation of battery stats service outside of activity manager service. 2046 File dataDir = Environment.getDataDirectory(); 2047 File systemDir = new File(dataDir, "system"); 2048 systemDir.mkdirs(); 2049 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2050 mBatteryStatsService.getActiveStatistics().readLocked(); 2051 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2052 mOnBattery = DEBUG_POWER ? true 2053 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2054 mBatteryStatsService.getActiveStatistics().setCallback(this); 2055 2056 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2057 2058 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2059 2060 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2061 2062 // User 0 is the first and only user that runs at boot. 2063 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2064 mUserLru.add(Integer.valueOf(0)); 2065 updateStartedUserArrayLocked(); 2066 2067 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2068 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2069 2070 mConfiguration.setToDefaults(); 2071 mConfiguration.setLocale(Locale.getDefault()); 2072 2073 mConfigurationSeq = mConfiguration.seq = 1; 2074 mProcessCpuTracker.init(); 2075 2076 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2077 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2078 mStackSupervisor = new ActivityStackSupervisor(this); 2079 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2080 2081 mProcessCpuThread = new Thread("CpuTracker") { 2082 @Override 2083 public void run() { 2084 while (true) { 2085 try { 2086 try { 2087 synchronized(this) { 2088 final long now = SystemClock.uptimeMillis(); 2089 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2090 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2091 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2092 // + ", write delay=" + nextWriteDelay); 2093 if (nextWriteDelay < nextCpuDelay) { 2094 nextCpuDelay = nextWriteDelay; 2095 } 2096 if (nextCpuDelay > 0) { 2097 mProcessCpuMutexFree.set(true); 2098 this.wait(nextCpuDelay); 2099 } 2100 } 2101 } catch (InterruptedException e) { 2102 } 2103 updateCpuStatsNow(); 2104 } catch (Exception e) { 2105 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2106 } 2107 } 2108 } 2109 }; 2110 2111 Watchdog.getInstance().addMonitor(this); 2112 Watchdog.getInstance().addThread(mHandler); 2113 } 2114 2115 public void setSystemServiceManager(SystemServiceManager mgr) { 2116 mSystemServiceManager = mgr; 2117 } 2118 2119 public void setInstaller(Installer installer) { 2120 mInstaller = installer; 2121 } 2122 2123 private void start() { 2124 Process.removeAllProcessGroups(); 2125 mProcessCpuThread.start(); 2126 2127 mBatteryStatsService.publish(mContext); 2128 mAppOpsService.publish(mContext); 2129 Slog.d("AppOps", "AppOpsService published"); 2130 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2131 } 2132 2133 public void initPowerManagement() { 2134 mStackSupervisor.initPowerManagement(); 2135 mBatteryStatsService.initPowerManagement(); 2136 } 2137 2138 @Override 2139 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2140 throws RemoteException { 2141 if (code == SYSPROPS_TRANSACTION) { 2142 // We need to tell all apps about the system property change. 2143 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2144 synchronized(this) { 2145 final int NP = mProcessNames.getMap().size(); 2146 for (int ip=0; ip<NP; ip++) { 2147 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2148 final int NA = apps.size(); 2149 for (int ia=0; ia<NA; ia++) { 2150 ProcessRecord app = apps.valueAt(ia); 2151 if (app.thread != null) { 2152 procs.add(app.thread.asBinder()); 2153 } 2154 } 2155 } 2156 } 2157 2158 int N = procs.size(); 2159 for (int i=0; i<N; i++) { 2160 Parcel data2 = Parcel.obtain(); 2161 try { 2162 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2163 } catch (RemoteException e) { 2164 } 2165 data2.recycle(); 2166 } 2167 } 2168 try { 2169 return super.onTransact(code, data, reply, flags); 2170 } catch (RuntimeException e) { 2171 // The activity manager only throws security exceptions, so let's 2172 // log all others. 2173 if (!(e instanceof SecurityException)) { 2174 Slog.wtf(TAG, "Activity Manager Crash", e); 2175 } 2176 throw e; 2177 } 2178 } 2179 2180 void updateCpuStats() { 2181 final long now = SystemClock.uptimeMillis(); 2182 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2183 return; 2184 } 2185 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2186 synchronized (mProcessCpuThread) { 2187 mProcessCpuThread.notify(); 2188 } 2189 } 2190 } 2191 2192 void updateCpuStatsNow() { 2193 synchronized (mProcessCpuTracker) { 2194 mProcessCpuMutexFree.set(false); 2195 final long now = SystemClock.uptimeMillis(); 2196 boolean haveNewCpuStats = false; 2197 2198 if (MONITOR_CPU_USAGE && 2199 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2200 mLastCpuTime.set(now); 2201 haveNewCpuStats = true; 2202 mProcessCpuTracker.update(); 2203 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2204 //Slog.i(TAG, "Total CPU usage: " 2205 // + mProcessCpu.getTotalCpuPercent() + "%"); 2206 2207 // Slog the cpu usage if the property is set. 2208 if ("true".equals(SystemProperties.get("events.cpu"))) { 2209 int user = mProcessCpuTracker.getLastUserTime(); 2210 int system = mProcessCpuTracker.getLastSystemTime(); 2211 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2212 int irq = mProcessCpuTracker.getLastIrqTime(); 2213 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2214 int idle = mProcessCpuTracker.getLastIdleTime(); 2215 2216 int total = user + system + iowait + irq + softIrq + idle; 2217 if (total == 0) total = 1; 2218 2219 EventLog.writeEvent(EventLogTags.CPU, 2220 ((user+system+iowait+irq+softIrq) * 100) / total, 2221 (user * 100) / total, 2222 (system * 100) / total, 2223 (iowait * 100) / total, 2224 (irq * 100) / total, 2225 (softIrq * 100) / total); 2226 } 2227 } 2228 2229 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2230 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2231 synchronized(bstats) { 2232 synchronized(mPidsSelfLocked) { 2233 if (haveNewCpuStats) { 2234 if (mOnBattery) { 2235 int perc = bstats.startAddingCpuLocked(); 2236 int totalUTime = 0; 2237 int totalSTime = 0; 2238 final int N = mProcessCpuTracker.countStats(); 2239 for (int i=0; i<N; i++) { 2240 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2241 if (!st.working) { 2242 continue; 2243 } 2244 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2245 int otherUTime = (st.rel_utime*perc)/100; 2246 int otherSTime = (st.rel_stime*perc)/100; 2247 totalUTime += otherUTime; 2248 totalSTime += otherSTime; 2249 if (pr != null) { 2250 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2251 if (ps == null || !ps.isActive()) { 2252 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2253 pr.info.uid, pr.processName); 2254 } 2255 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2256 st.rel_stime-otherSTime); 2257 ps.addSpeedStepTimes(cpuSpeedTimes); 2258 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2259 } else { 2260 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2261 if (ps == null || !ps.isActive()) { 2262 st.batteryStats = ps = bstats.getProcessStatsLocked( 2263 bstats.mapUid(st.uid), st.name); 2264 } 2265 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2266 st.rel_stime-otherSTime); 2267 ps.addSpeedStepTimes(cpuSpeedTimes); 2268 } 2269 } 2270 bstats.finishAddingCpuLocked(perc, totalUTime, 2271 totalSTime, cpuSpeedTimes); 2272 } 2273 } 2274 } 2275 2276 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2277 mLastWriteTime = now; 2278 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2279 } 2280 } 2281 } 2282 } 2283 2284 @Override 2285 public void batteryNeedsCpuUpdate() { 2286 updateCpuStatsNow(); 2287 } 2288 2289 @Override 2290 public void batteryPowerChanged(boolean onBattery) { 2291 // When plugging in, update the CPU stats first before changing 2292 // the plug state. 2293 updateCpuStatsNow(); 2294 synchronized (this) { 2295 synchronized(mPidsSelfLocked) { 2296 mOnBattery = DEBUG_POWER ? true : onBattery; 2297 } 2298 } 2299 } 2300 2301 /** 2302 * Initialize the application bind args. These are passed to each 2303 * process when the bindApplication() IPC is sent to the process. They're 2304 * lazily setup to make sure the services are running when they're asked for. 2305 */ 2306 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2307 if (mAppBindArgs == null) { 2308 mAppBindArgs = new HashMap<>(); 2309 2310 // Isolated processes won't get this optimization, so that we don't 2311 // violate the rules about which services they have access to. 2312 if (!isolated) { 2313 // Setup the application init args 2314 mAppBindArgs.put("package", ServiceManager.getService("package")); 2315 mAppBindArgs.put("window", ServiceManager.getService("window")); 2316 mAppBindArgs.put(Context.ALARM_SERVICE, 2317 ServiceManager.getService(Context.ALARM_SERVICE)); 2318 } 2319 } 2320 return mAppBindArgs; 2321 } 2322 2323 final void setFocusedActivityLocked(ActivityRecord r) { 2324 if (mFocusedActivity != r) { 2325 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2326 mFocusedActivity = r; 2327 if (r.task != null && r.task.voiceInteractor != null) { 2328 startRunningVoiceLocked(); 2329 } else { 2330 finishRunningVoiceLocked(); 2331 } 2332 mStackSupervisor.setFocusedStack(r); 2333 if (r != null) { 2334 mWindowManager.setFocusedApp(r.appToken, true); 2335 } 2336 applyUpdateLockStateLocked(r); 2337 } 2338 } 2339 2340 final void clearFocusedActivity(ActivityRecord r) { 2341 if (mFocusedActivity == r) { 2342 mFocusedActivity = null; 2343 } 2344 } 2345 2346 @Override 2347 public void setFocusedStack(int stackId) { 2348 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2349 synchronized (ActivityManagerService.this) { 2350 ActivityStack stack = mStackSupervisor.getStack(stackId); 2351 if (stack != null) { 2352 ActivityRecord r = stack.topRunningActivityLocked(null); 2353 if (r != null) { 2354 setFocusedActivityLocked(r); 2355 } 2356 } 2357 } 2358 } 2359 2360 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2361 @Override 2362 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2363 synchronized (ActivityManagerService.this) { 2364 if (listener != null) { 2365 mTaskStackListeners.register(listener); 2366 } 2367 } 2368 } 2369 2370 @Override 2371 public void notifyActivityDrawn(IBinder token) { 2372 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2373 synchronized (this) { 2374 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2375 if (r != null) { 2376 r.task.stack.notifyActivityDrawnLocked(r); 2377 } 2378 } 2379 } 2380 2381 final void applyUpdateLockStateLocked(ActivityRecord r) { 2382 // Modifications to the UpdateLock state are done on our handler, outside 2383 // the activity manager's locks. The new state is determined based on the 2384 // state *now* of the relevant activity record. The object is passed to 2385 // the handler solely for logging detail, not to be consulted/modified. 2386 final boolean nextState = r != null && r.immersive; 2387 mHandler.sendMessage( 2388 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2389 } 2390 2391 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2392 Message msg = Message.obtain(); 2393 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2394 msg.obj = r.task.askedCompatMode ? null : r; 2395 mHandler.sendMessage(msg); 2396 } 2397 2398 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2399 String what, Object obj, ProcessRecord srcApp) { 2400 app.lastActivityTime = now; 2401 2402 if (app.activities.size() > 0) { 2403 // Don't want to touch dependent processes that are hosting activities. 2404 return index; 2405 } 2406 2407 int lrui = mLruProcesses.lastIndexOf(app); 2408 if (lrui < 0) { 2409 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2410 + what + " " + obj + " from " + srcApp); 2411 return index; 2412 } 2413 2414 if (lrui >= index) { 2415 // Don't want to cause this to move dependent processes *back* in the 2416 // list as if they were less frequently used. 2417 return index; 2418 } 2419 2420 if (lrui >= mLruProcessActivityStart) { 2421 // Don't want to touch dependent processes that are hosting activities. 2422 return index; 2423 } 2424 2425 mLruProcesses.remove(lrui); 2426 if (index > 0) { 2427 index--; 2428 } 2429 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2430 + " in LRU list: " + app); 2431 mLruProcesses.add(index, app); 2432 return index; 2433 } 2434 2435 final void removeLruProcessLocked(ProcessRecord app) { 2436 int lrui = mLruProcesses.lastIndexOf(app); 2437 if (lrui >= 0) { 2438 if (!app.killed) { 2439 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2440 Process.killProcessQuiet(app.pid); 2441 Process.killProcessGroup(app.info.uid, app.pid); 2442 } 2443 if (lrui <= mLruProcessActivityStart) { 2444 mLruProcessActivityStart--; 2445 } 2446 if (lrui <= mLruProcessServiceStart) { 2447 mLruProcessServiceStart--; 2448 } 2449 mLruProcesses.remove(lrui); 2450 } 2451 } 2452 2453 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2454 ProcessRecord client) { 2455 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2456 || app.treatLikeActivity; 2457 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2458 if (!activityChange && hasActivity) { 2459 // The process has activities, so we are only allowing activity-based adjustments 2460 // to move it. It should be kept in the front of the list with other 2461 // processes that have activities, and we don't want those to change their 2462 // order except due to activity operations. 2463 return; 2464 } 2465 2466 mLruSeq++; 2467 final long now = SystemClock.uptimeMillis(); 2468 app.lastActivityTime = now; 2469 2470 // First a quick reject: if the app is already at the position we will 2471 // put it, then there is nothing to do. 2472 if (hasActivity) { 2473 final int N = mLruProcesses.size(); 2474 if (N > 0 && mLruProcesses.get(N-1) == app) { 2475 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2476 return; 2477 } 2478 } else { 2479 if (mLruProcessServiceStart > 0 2480 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2481 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2482 return; 2483 } 2484 } 2485 2486 int lrui = mLruProcesses.lastIndexOf(app); 2487 2488 if (app.persistent && lrui >= 0) { 2489 // We don't care about the position of persistent processes, as long as 2490 // they are in the list. 2491 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2492 return; 2493 } 2494 2495 /* In progress: compute new position first, so we can avoid doing work 2496 if the process is not actually going to move. Not yet working. 2497 int addIndex; 2498 int nextIndex; 2499 boolean inActivity = false, inService = false; 2500 if (hasActivity) { 2501 // Process has activities, put it at the very tipsy-top. 2502 addIndex = mLruProcesses.size(); 2503 nextIndex = mLruProcessServiceStart; 2504 inActivity = true; 2505 } else if (hasService) { 2506 // Process has services, put it at the top of the service list. 2507 addIndex = mLruProcessActivityStart; 2508 nextIndex = mLruProcessServiceStart; 2509 inActivity = true; 2510 inService = true; 2511 } else { 2512 // Process not otherwise of interest, it goes to the top of the non-service area. 2513 addIndex = mLruProcessServiceStart; 2514 if (client != null) { 2515 int clientIndex = mLruProcesses.lastIndexOf(client); 2516 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2517 + app); 2518 if (clientIndex >= 0 && addIndex > clientIndex) { 2519 addIndex = clientIndex; 2520 } 2521 } 2522 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2523 } 2524 2525 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2526 + mLruProcessActivityStart + "): " + app); 2527 */ 2528 2529 if (lrui >= 0) { 2530 if (lrui < mLruProcessActivityStart) { 2531 mLruProcessActivityStart--; 2532 } 2533 if (lrui < mLruProcessServiceStart) { 2534 mLruProcessServiceStart--; 2535 } 2536 /* 2537 if (addIndex > lrui) { 2538 addIndex--; 2539 } 2540 if (nextIndex > lrui) { 2541 nextIndex--; 2542 } 2543 */ 2544 mLruProcesses.remove(lrui); 2545 } 2546 2547 /* 2548 mLruProcesses.add(addIndex, app); 2549 if (inActivity) { 2550 mLruProcessActivityStart++; 2551 } 2552 if (inService) { 2553 mLruProcessActivityStart++; 2554 } 2555 */ 2556 2557 int nextIndex; 2558 if (hasActivity) { 2559 final int N = mLruProcesses.size(); 2560 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2561 // Process doesn't have activities, but has clients with 2562 // activities... move it up, but one below the top (the top 2563 // should always have a real activity). 2564 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2565 mLruProcesses.add(N-1, app); 2566 // To keep it from spamming the LRU list (by making a bunch of clients), 2567 // we will push down any other entries owned by the app. 2568 final int uid = app.info.uid; 2569 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2570 ProcessRecord subProc = mLruProcesses.get(i); 2571 if (subProc.info.uid == uid) { 2572 // We want to push this one down the list. If the process after 2573 // it is for the same uid, however, don't do so, because we don't 2574 // want them internally to be re-ordered. 2575 if (mLruProcesses.get(i-1).info.uid != uid) { 2576 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2577 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2578 ProcessRecord tmp = mLruProcesses.get(i); 2579 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2580 mLruProcesses.set(i-1, tmp); 2581 i--; 2582 } 2583 } else { 2584 // A gap, we can stop here. 2585 break; 2586 } 2587 } 2588 } else { 2589 // Process has activities, put it at the very tipsy-top. 2590 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2591 mLruProcesses.add(app); 2592 } 2593 nextIndex = mLruProcessServiceStart; 2594 } else if (hasService) { 2595 // Process has services, put it at the top of the service list. 2596 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2597 mLruProcesses.add(mLruProcessActivityStart, app); 2598 nextIndex = mLruProcessServiceStart; 2599 mLruProcessActivityStart++; 2600 } else { 2601 // Process not otherwise of interest, it goes to the top of the non-service area. 2602 int index = mLruProcessServiceStart; 2603 if (client != null) { 2604 // If there is a client, don't allow the process to be moved up higher 2605 // in the list than that client. 2606 int clientIndex = mLruProcesses.lastIndexOf(client); 2607 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2608 + " when updating " + app); 2609 if (clientIndex <= lrui) { 2610 // Don't allow the client index restriction to push it down farther in the 2611 // list than it already is. 2612 clientIndex = lrui; 2613 } 2614 if (clientIndex >= 0 && index > clientIndex) { 2615 index = clientIndex; 2616 } 2617 } 2618 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2619 mLruProcesses.add(index, app); 2620 nextIndex = index-1; 2621 mLruProcessActivityStart++; 2622 mLruProcessServiceStart++; 2623 } 2624 2625 // If the app is currently using a content provider or service, 2626 // bump those processes as well. 2627 for (int j=app.connections.size()-1; j>=0; j--) { 2628 ConnectionRecord cr = app.connections.valueAt(j); 2629 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2630 && cr.binding.service.app != null 2631 && cr.binding.service.app.lruSeq != mLruSeq 2632 && !cr.binding.service.app.persistent) { 2633 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2634 "service connection", cr, app); 2635 } 2636 } 2637 for (int j=app.conProviders.size()-1; j>=0; j--) { 2638 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2639 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2640 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2641 "provider reference", cpr, app); 2642 } 2643 } 2644 } 2645 2646 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2647 if (uid == Process.SYSTEM_UID) { 2648 // The system gets to run in any process. If there are multiple 2649 // processes with the same uid, just pick the first (this 2650 // should never happen). 2651 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2652 if (procs == null) return null; 2653 final int N = procs.size(); 2654 for (int i = 0; i < N; i++) { 2655 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2656 } 2657 } 2658 ProcessRecord proc = mProcessNames.get(processName, uid); 2659 if (false && proc != null && !keepIfLarge 2660 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2661 && proc.lastCachedPss >= 4000) { 2662 // Turn this condition on to cause killing to happen regularly, for testing. 2663 if (proc.baseProcessTracker != null) { 2664 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2665 } 2666 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2667 } else if (proc != null && !keepIfLarge 2668 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2669 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2670 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2671 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2672 if (proc.baseProcessTracker != null) { 2673 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2674 } 2675 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2676 } 2677 } 2678 return proc; 2679 } 2680 2681 void ensurePackageDexOpt(String packageName) { 2682 IPackageManager pm = AppGlobals.getPackageManager(); 2683 try { 2684 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2685 mDidDexOpt = true; 2686 } 2687 } catch (RemoteException e) { 2688 } 2689 } 2690 2691 boolean isNextTransitionForward() { 2692 int transit = mWindowManager.getPendingAppTransition(); 2693 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2694 || transit == AppTransition.TRANSIT_TASK_OPEN 2695 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2696 } 2697 2698 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2699 String processName, String abiOverride, int uid, Runnable crashHandler) { 2700 synchronized(this) { 2701 ApplicationInfo info = new ApplicationInfo(); 2702 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2703 // For isolated processes, the former contains the parent's uid and the latter the 2704 // actual uid of the isolated process. 2705 // In the special case introduced by this method (which is, starting an isolated 2706 // process directly from the SystemServer without an actual parent app process) the 2707 // closest thing to a parent's uid is SYSTEM_UID. 2708 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2709 // the |isolated| logic in the ProcessRecord constructor. 2710 info.uid = Process.SYSTEM_UID; 2711 info.processName = processName; 2712 info.className = entryPoint; 2713 info.packageName = "android"; 2714 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2715 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2716 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2717 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2718 crashHandler); 2719 return proc != null ? proc.pid : 0; 2720 } 2721 } 2722 2723 final ProcessRecord startProcessLocked(String processName, 2724 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2725 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2726 boolean isolated, boolean keepIfLarge) { 2727 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2728 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2729 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2730 null /* crashHandler */); 2731 } 2732 2733 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2734 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2735 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2736 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2737 long startTime = SystemClock.elapsedRealtime(); 2738 ProcessRecord app; 2739 if (!isolated) { 2740 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2741 checkTime(startTime, "startProcess: after getProcessRecord"); 2742 } else { 2743 // If this is an isolated process, it can't re-use an existing process. 2744 app = null; 2745 } 2746 // We don't have to do anything more if: 2747 // (1) There is an existing application record; and 2748 // (2) The caller doesn't think it is dead, OR there is no thread 2749 // object attached to it so we know it couldn't have crashed; and 2750 // (3) There is a pid assigned to it, so it is either starting or 2751 // already running. 2752 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2753 + " app=" + app + " knownToBeDead=" + knownToBeDead 2754 + " thread=" + (app != null ? app.thread : null) 2755 + " pid=" + (app != null ? app.pid : -1)); 2756 if (app != null && app.pid > 0) { 2757 if (!knownToBeDead || app.thread == null) { 2758 // We already have the app running, or are waiting for it to 2759 // come up (we have a pid but not yet its thread), so keep it. 2760 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2761 // If this is a new package in the process, add the package to the list 2762 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2763 checkTime(startTime, "startProcess: done, added package to proc"); 2764 return app; 2765 } 2766 2767 // An application record is attached to a previous process, 2768 // clean it up now. 2769 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2770 checkTime(startTime, "startProcess: bad proc running, killing"); 2771 Process.killProcessGroup(app.info.uid, app.pid); 2772 handleAppDiedLocked(app, true, true); 2773 checkTime(startTime, "startProcess: done killing old proc"); 2774 } 2775 2776 String hostingNameStr = hostingName != null 2777 ? hostingName.flattenToShortString() : null; 2778 2779 if (!isolated) { 2780 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2781 // If we are in the background, then check to see if this process 2782 // is bad. If so, we will just silently fail. 2783 if (mBadProcesses.get(info.processName, info.uid) != null) { 2784 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2785 + "/" + info.processName); 2786 return null; 2787 } 2788 } else { 2789 // When the user is explicitly starting a process, then clear its 2790 // crash count so that we won't make it bad until they see at 2791 // least one crash dialog again, and make the process good again 2792 // if it had been bad. 2793 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2794 + "/" + info.processName); 2795 mProcessCrashTimes.remove(info.processName, info.uid); 2796 if (mBadProcesses.get(info.processName, info.uid) != null) { 2797 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2798 UserHandle.getUserId(info.uid), info.uid, 2799 info.processName); 2800 mBadProcesses.remove(info.processName, info.uid); 2801 if (app != null) { 2802 app.bad = false; 2803 } 2804 } 2805 } 2806 } 2807 2808 if (app == null) { 2809 checkTime(startTime, "startProcess: creating new process record"); 2810 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2811 app.crashHandler = crashHandler; 2812 if (app == null) { 2813 Slog.w(TAG, "Failed making new process record for " 2814 + processName + "/" + info.uid + " isolated=" + isolated); 2815 return null; 2816 } 2817 mProcessNames.put(processName, app.uid, app); 2818 if (isolated) { 2819 mIsolatedProcesses.put(app.uid, app); 2820 } 2821 checkTime(startTime, "startProcess: done creating new process record"); 2822 } else { 2823 // If this is a new package in the process, add the package to the list 2824 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2825 checkTime(startTime, "startProcess: added package to existing proc"); 2826 } 2827 2828 // If the system is not ready yet, then hold off on starting this 2829 // process until it is. 2830 if (!mProcessesReady 2831 && !isAllowedWhileBooting(info) 2832 && !allowWhileBooting) { 2833 if (!mProcessesOnHold.contains(app)) { 2834 mProcessesOnHold.add(app); 2835 } 2836 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2837 checkTime(startTime, "startProcess: returning with proc on hold"); 2838 return app; 2839 } 2840 2841 checkTime(startTime, "startProcess: stepping in to startProcess"); 2842 startProcessLocked( 2843 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2844 checkTime(startTime, "startProcess: done starting proc!"); 2845 return (app.pid != 0) ? app : null; 2846 } 2847 2848 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2849 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2850 } 2851 2852 private final void startProcessLocked(ProcessRecord app, 2853 String hostingType, String hostingNameStr) { 2854 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2855 null /* entryPoint */, null /* entryPointArgs */); 2856 } 2857 2858 private final void startProcessLocked(ProcessRecord app, String hostingType, 2859 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2860 long startTime = SystemClock.elapsedRealtime(); 2861 if (app.pid > 0 && app.pid != MY_PID) { 2862 checkTime(startTime, "startProcess: removing from pids map"); 2863 synchronized (mPidsSelfLocked) { 2864 mPidsSelfLocked.remove(app.pid); 2865 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2866 } 2867 checkTime(startTime, "startProcess: done removing from pids map"); 2868 app.setPid(0); 2869 } 2870 2871 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2872 "startProcessLocked removing on hold: " + app); 2873 mProcessesOnHold.remove(app); 2874 2875 checkTime(startTime, "startProcess: starting to update cpu stats"); 2876 updateCpuStats(); 2877 checkTime(startTime, "startProcess: done updating cpu stats"); 2878 2879 try { 2880 int uid = app.uid; 2881 2882 int[] gids = null; 2883 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2884 if (!app.isolated) { 2885 int[] permGids = null; 2886 try { 2887 checkTime(startTime, "startProcess: getting gids from package manager"); 2888 final PackageManager pm = mContext.getPackageManager(); 2889 permGids = pm.getPackageGids(app.info.packageName); 2890 2891 if (Environment.isExternalStorageEmulated()) { 2892 checkTime(startTime, "startProcess: checking external storage perm"); 2893 if (pm.checkPermission( 2894 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2895 app.info.packageName) == PERMISSION_GRANTED) { 2896 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2897 } else { 2898 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2899 } 2900 } 2901 } catch (PackageManager.NameNotFoundException e) { 2902 Slog.w(TAG, "Unable to retrieve gids", e); 2903 } 2904 2905 /* 2906 * Add shared application and profile GIDs so applications can share some 2907 * resources like shared libraries and access user-wide resources 2908 */ 2909 if (permGids == null) { 2910 gids = new int[2]; 2911 } else { 2912 gids = new int[permGids.length + 2]; 2913 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2914 } 2915 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2916 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2917 } 2918 checkTime(startTime, "startProcess: building args"); 2919 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2920 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2921 && mTopComponent != null 2922 && app.processName.equals(mTopComponent.getPackageName())) { 2923 uid = 0; 2924 } 2925 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2926 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2927 uid = 0; 2928 } 2929 } 2930 int debugFlags = 0; 2931 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2932 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2933 // Also turn on CheckJNI for debuggable apps. It's quite 2934 // awkward to turn on otherwise. 2935 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2936 } 2937 // Run the app in safe mode if its manifest requests so or the 2938 // system is booted in safe mode. 2939 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2940 mSafeMode == true) { 2941 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2942 } 2943 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2944 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2945 } 2946 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2947 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2948 } 2949 if ("1".equals(SystemProperties.get("debug.assert"))) { 2950 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2951 } 2952 2953 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2954 if (requiredAbi == null) { 2955 requiredAbi = Build.SUPPORTED_ABIS[0]; 2956 } 2957 2958 String instructionSet = null; 2959 if (app.info.primaryCpuAbi != null) { 2960 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2961 } 2962 2963 // Start the process. It will either succeed and return a result containing 2964 // the PID of the new process, or else throw a RuntimeException. 2965 boolean isActivityProcess = (entryPoint == null); 2966 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2967 checkTime(startTime, "startProcess: asking zygote to start proc"); 2968 Process.ProcessStartResult startResult = Process.start(entryPoint, 2969 app.processName, uid, uid, gids, debugFlags, mountExternal, 2970 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2971 app.info.dataDir, entryPointArgs); 2972 checkTime(startTime, "startProcess: returned from zygote!"); 2973 2974 if (app.isolated) { 2975 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2976 } 2977 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2978 checkTime(startTime, "startProcess: done updating battery stats"); 2979 2980 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2981 UserHandle.getUserId(uid), startResult.pid, uid, 2982 app.processName, hostingType, 2983 hostingNameStr != null ? hostingNameStr : ""); 2984 2985 if (app.persistent) { 2986 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2987 } 2988 2989 checkTime(startTime, "startProcess: building log message"); 2990 StringBuilder buf = mStringBuilder; 2991 buf.setLength(0); 2992 buf.append("Start proc "); 2993 buf.append(app.processName); 2994 if (!isActivityProcess) { 2995 buf.append(" ["); 2996 buf.append(entryPoint); 2997 buf.append("]"); 2998 } 2999 buf.append(" for "); 3000 buf.append(hostingType); 3001 if (hostingNameStr != null) { 3002 buf.append(" "); 3003 buf.append(hostingNameStr); 3004 } 3005 buf.append(": pid="); 3006 buf.append(startResult.pid); 3007 buf.append(" uid="); 3008 buf.append(uid); 3009 buf.append(" gids={"); 3010 if (gids != null) { 3011 for (int gi=0; gi<gids.length; gi++) { 3012 if (gi != 0) buf.append(", "); 3013 buf.append(gids[gi]); 3014 3015 } 3016 } 3017 buf.append("}"); 3018 if (requiredAbi != null) { 3019 buf.append(" abi="); 3020 buf.append(requiredAbi); 3021 } 3022 Slog.i(TAG, buf.toString()); 3023 app.setPid(startResult.pid); 3024 app.usingWrapper = startResult.usingWrapper; 3025 app.removed = false; 3026 app.killed = false; 3027 app.killedByAm = false; 3028 checkTime(startTime, "startProcess: starting to update pids map"); 3029 synchronized (mPidsSelfLocked) { 3030 this.mPidsSelfLocked.put(startResult.pid, app); 3031 if (isActivityProcess) { 3032 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3033 msg.obj = app; 3034 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3035 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3036 } 3037 } 3038 checkTime(startTime, "startProcess: done updating pids map"); 3039 } catch (RuntimeException e) { 3040 // XXX do better error recovery. 3041 app.setPid(0); 3042 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3043 if (app.isolated) { 3044 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3045 } 3046 Slog.e(TAG, "Failure starting process " + app.processName, e); 3047 } 3048 } 3049 3050 void updateUsageStats(ActivityRecord component, boolean resumed) { 3051 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3052 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3053 if (resumed) { 3054 if (mUsageStatsService != null) { 3055 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3056 UsageEvents.Event.MOVE_TO_FOREGROUND); 3057 } 3058 synchronized (stats) { 3059 stats.noteActivityResumedLocked(component.app.uid); 3060 } 3061 } else { 3062 if (mUsageStatsService != null) { 3063 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3064 UsageEvents.Event.MOVE_TO_BACKGROUND); 3065 } 3066 synchronized (stats) { 3067 stats.noteActivityPausedLocked(component.app.uid); 3068 } 3069 } 3070 } 3071 3072 Intent getHomeIntent() { 3073 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3074 intent.setComponent(mTopComponent); 3075 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3076 intent.addCategory(Intent.CATEGORY_HOME); 3077 } 3078 return intent; 3079 } 3080 3081 boolean startHomeActivityLocked(int userId) { 3082 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3083 && mTopAction == null) { 3084 // We are running in factory test mode, but unable to find 3085 // the factory test app, so just sit around displaying the 3086 // error message and don't try to start anything. 3087 return false; 3088 } 3089 Intent intent = getHomeIntent(); 3090 ActivityInfo aInfo = 3091 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3092 if (aInfo != null) { 3093 intent.setComponent(new ComponentName( 3094 aInfo.applicationInfo.packageName, aInfo.name)); 3095 // Don't do this if the home app is currently being 3096 // instrumented. 3097 aInfo = new ActivityInfo(aInfo); 3098 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3099 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3100 aInfo.applicationInfo.uid, true); 3101 if (app == null || app.instrumentationClass == null) { 3102 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3103 mStackSupervisor.startHomeActivity(intent, aInfo); 3104 } 3105 } 3106 3107 return true; 3108 } 3109 3110 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3111 ActivityInfo ai = null; 3112 ComponentName comp = intent.getComponent(); 3113 try { 3114 if (comp != null) { 3115 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3116 } else { 3117 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3118 intent, 3119 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3120 flags, userId); 3121 3122 if (info != null) { 3123 ai = info.activityInfo; 3124 } 3125 } 3126 } catch (RemoteException e) { 3127 // ignore 3128 } 3129 3130 return ai; 3131 } 3132 3133 /** 3134 * Starts the "new version setup screen" if appropriate. 3135 */ 3136 void startSetupActivityLocked() { 3137 // Only do this once per boot. 3138 if (mCheckedForSetup) { 3139 return; 3140 } 3141 3142 // We will show this screen if the current one is a different 3143 // version than the last one shown, and we are not running in 3144 // low-level factory test mode. 3145 final ContentResolver resolver = mContext.getContentResolver(); 3146 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3147 Settings.Global.getInt(resolver, 3148 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3149 mCheckedForSetup = true; 3150 3151 // See if we should be showing the platform update setup UI. 3152 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3153 List<ResolveInfo> ris = mContext.getPackageManager() 3154 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3155 3156 // We don't allow third party apps to replace this. 3157 ResolveInfo ri = null; 3158 for (int i=0; ris != null && i<ris.size(); i++) { 3159 if ((ris.get(i).activityInfo.applicationInfo.flags 3160 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3161 ri = ris.get(i); 3162 break; 3163 } 3164 } 3165 3166 if (ri != null) { 3167 String vers = ri.activityInfo.metaData != null 3168 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3169 : null; 3170 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3171 vers = ri.activityInfo.applicationInfo.metaData.getString( 3172 Intent.METADATA_SETUP_VERSION); 3173 } 3174 String lastVers = Settings.Secure.getString( 3175 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3176 if (vers != null && !vers.equals(lastVers)) { 3177 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3178 intent.setComponent(new ComponentName( 3179 ri.activityInfo.packageName, ri.activityInfo.name)); 3180 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3181 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3182 null); 3183 } 3184 } 3185 } 3186 } 3187 3188 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3189 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3190 } 3191 3192 void enforceNotIsolatedCaller(String caller) { 3193 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3194 throw new SecurityException("Isolated process not allowed to call " + caller); 3195 } 3196 } 3197 3198 void enforceShellRestriction(String restriction, int userHandle) { 3199 if (Binder.getCallingUid() == Process.SHELL_UID) { 3200 if (userHandle < 0 3201 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3202 throw new SecurityException("Shell does not have permission to access user " 3203 + userHandle); 3204 } 3205 } 3206 } 3207 3208 @Override 3209 public int getFrontActivityScreenCompatMode() { 3210 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3211 synchronized (this) { 3212 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3213 } 3214 } 3215 3216 @Override 3217 public void setFrontActivityScreenCompatMode(int mode) { 3218 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3219 "setFrontActivityScreenCompatMode"); 3220 synchronized (this) { 3221 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3222 } 3223 } 3224 3225 @Override 3226 public int getPackageScreenCompatMode(String packageName) { 3227 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3228 synchronized (this) { 3229 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3230 } 3231 } 3232 3233 @Override 3234 public void setPackageScreenCompatMode(String packageName, int mode) { 3235 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3236 "setPackageScreenCompatMode"); 3237 synchronized (this) { 3238 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3239 } 3240 } 3241 3242 @Override 3243 public boolean getPackageAskScreenCompat(String packageName) { 3244 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3245 synchronized (this) { 3246 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3247 } 3248 } 3249 3250 @Override 3251 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3252 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3253 "setPackageAskScreenCompat"); 3254 synchronized (this) { 3255 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3256 } 3257 } 3258 3259 private void dispatchProcessesChanged() { 3260 int N; 3261 synchronized (this) { 3262 N = mPendingProcessChanges.size(); 3263 if (mActiveProcessChanges.length < N) { 3264 mActiveProcessChanges = new ProcessChangeItem[N]; 3265 } 3266 mPendingProcessChanges.toArray(mActiveProcessChanges); 3267 mAvailProcessChanges.addAll(mPendingProcessChanges); 3268 mPendingProcessChanges.clear(); 3269 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3270 } 3271 3272 int i = mProcessObservers.beginBroadcast(); 3273 while (i > 0) { 3274 i--; 3275 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3276 if (observer != null) { 3277 try { 3278 for (int j=0; j<N; j++) { 3279 ProcessChangeItem item = mActiveProcessChanges[j]; 3280 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3281 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3282 + item.pid + " uid=" + item.uid + ": " 3283 + item.foregroundActivities); 3284 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3285 item.foregroundActivities); 3286 } 3287 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3289 + item.pid + " uid=" + item.uid + ": " + item.processState); 3290 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3291 } 3292 } 3293 } catch (RemoteException e) { 3294 } 3295 } 3296 } 3297 mProcessObservers.finishBroadcast(); 3298 } 3299 3300 private void dispatchProcessDied(int pid, int uid) { 3301 int i = mProcessObservers.beginBroadcast(); 3302 while (i > 0) { 3303 i--; 3304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3305 if (observer != null) { 3306 try { 3307 observer.onProcessDied(pid, uid); 3308 } catch (RemoteException e) { 3309 } 3310 } 3311 } 3312 mProcessObservers.finishBroadcast(); 3313 } 3314 3315 @Override 3316 public final int startActivity(IApplicationThread caller, String callingPackage, 3317 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3318 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3319 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3320 resultWho, requestCode, startFlags, profilerInfo, options, 3321 UserHandle.getCallingUserId()); 3322 } 3323 3324 @Override 3325 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3326 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3327 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3328 enforceNotIsolatedCaller("startActivity"); 3329 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3330 false, ALLOW_FULL_ONLY, "startActivity", null); 3331 // TODO: Switch to user app stacks here. 3332 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3333 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3334 profilerInfo, null, null, options, userId, null, null); 3335 } 3336 3337 @Override 3338 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3339 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3340 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3341 3342 // This is very dangerous -- it allows you to perform a start activity (including 3343 // permission grants) as any app that may launch one of your own activities. So 3344 // we will only allow this to be done from activities that are part of the core framework, 3345 // and then only when they are running as the system. 3346 final ActivityRecord sourceRecord; 3347 final int targetUid; 3348 final String targetPackage; 3349 synchronized (this) { 3350 if (resultTo == null) { 3351 throw new SecurityException("Must be called from an activity"); 3352 } 3353 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3354 if (sourceRecord == null) { 3355 throw new SecurityException("Called with bad activity token: " + resultTo); 3356 } 3357 if (!sourceRecord.info.packageName.equals("android")) { 3358 throw new SecurityException( 3359 "Must be called from an activity that is declared in the android package"); 3360 } 3361 if (sourceRecord.app == null) { 3362 throw new SecurityException("Called without a process attached to activity"); 3363 } 3364 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3365 // This is still okay, as long as this activity is running under the 3366 // uid of the original calling activity. 3367 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3368 throw new SecurityException( 3369 "Calling activity in uid " + sourceRecord.app.uid 3370 + " must be system uid or original calling uid " 3371 + sourceRecord.launchedFromUid); 3372 } 3373 } 3374 targetUid = sourceRecord.launchedFromUid; 3375 targetPackage = sourceRecord.launchedFromPackage; 3376 } 3377 3378 if (userId == UserHandle.USER_NULL) { 3379 userId = UserHandle.getUserId(sourceRecord.app.uid); 3380 } 3381 3382 // TODO: Switch to user app stacks here. 3383 try { 3384 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3385 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3386 null, null, options, userId, null, null); 3387 return ret; 3388 } catch (SecurityException e) { 3389 // XXX need to figure out how to propagate to original app. 3390 // A SecurityException here is generally actually a fault of the original 3391 // calling activity (such as a fairly granting permissions), so propagate it 3392 // back to them. 3393 /* 3394 StringBuilder msg = new StringBuilder(); 3395 msg.append("While launching"); 3396 msg.append(intent.toString()); 3397 msg.append(": "); 3398 msg.append(e.getMessage()); 3399 */ 3400 throw e; 3401 } 3402 } 3403 3404 @Override 3405 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3406 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3407 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3408 enforceNotIsolatedCaller("startActivityAndWait"); 3409 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3410 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3411 WaitResult res = new WaitResult(); 3412 // TODO: Switch to user app stacks here. 3413 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3414 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3415 options, userId, null, null); 3416 return res; 3417 } 3418 3419 @Override 3420 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3421 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3422 int startFlags, Configuration config, Bundle options, int userId) { 3423 enforceNotIsolatedCaller("startActivityWithConfig"); 3424 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3425 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3426 // TODO: Switch to user app stacks here. 3427 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3428 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3429 null, null, config, options, userId, null, null); 3430 return ret; 3431 } 3432 3433 @Override 3434 public int startActivityIntentSender(IApplicationThread caller, 3435 IntentSender intent, Intent fillInIntent, String resolvedType, 3436 IBinder resultTo, String resultWho, int requestCode, 3437 int flagsMask, int flagsValues, Bundle options) { 3438 enforceNotIsolatedCaller("startActivityIntentSender"); 3439 // Refuse possible leaked file descriptors 3440 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3441 throw new IllegalArgumentException("File descriptors passed in Intent"); 3442 } 3443 3444 IIntentSender sender = intent.getTarget(); 3445 if (!(sender instanceof PendingIntentRecord)) { 3446 throw new IllegalArgumentException("Bad PendingIntent object"); 3447 } 3448 3449 PendingIntentRecord pir = (PendingIntentRecord)sender; 3450 3451 synchronized (this) { 3452 // If this is coming from the currently resumed activity, it is 3453 // effectively saying that app switches are allowed at this point. 3454 final ActivityStack stack = getFocusedStack(); 3455 if (stack.mResumedActivity != null && 3456 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3457 mAppSwitchesAllowedTime = 0; 3458 } 3459 } 3460 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3461 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3462 return ret; 3463 } 3464 3465 @Override 3466 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3467 Intent intent, String resolvedType, IVoiceInteractionSession session, 3468 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3469 Bundle options, int userId) { 3470 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3471 != PackageManager.PERMISSION_GRANTED) { 3472 String msg = "Permission Denial: startVoiceActivity() from pid=" 3473 + Binder.getCallingPid() 3474 + ", uid=" + Binder.getCallingUid() 3475 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3476 Slog.w(TAG, msg); 3477 throw new SecurityException(msg); 3478 } 3479 if (session == null || interactor == null) { 3480 throw new NullPointerException("null session or interactor"); 3481 } 3482 userId = handleIncomingUser(callingPid, callingUid, userId, 3483 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3484 // TODO: Switch to user app stacks here. 3485 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3486 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3487 null, options, userId, null, null); 3488 } 3489 3490 @Override 3491 public boolean startNextMatchingActivity(IBinder callingActivity, 3492 Intent intent, Bundle options) { 3493 // Refuse possible leaked file descriptors 3494 if (intent != null && intent.hasFileDescriptors() == true) { 3495 throw new IllegalArgumentException("File descriptors passed in Intent"); 3496 } 3497 3498 synchronized (this) { 3499 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3500 if (r == null) { 3501 ActivityOptions.abort(options); 3502 return false; 3503 } 3504 if (r.app == null || r.app.thread == null) { 3505 // The caller is not running... d'oh! 3506 ActivityOptions.abort(options); 3507 return false; 3508 } 3509 intent = new Intent(intent); 3510 // The caller is not allowed to change the data. 3511 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3512 // And we are resetting to find the next component... 3513 intent.setComponent(null); 3514 3515 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3516 3517 ActivityInfo aInfo = null; 3518 try { 3519 List<ResolveInfo> resolves = 3520 AppGlobals.getPackageManager().queryIntentActivities( 3521 intent, r.resolvedType, 3522 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3523 UserHandle.getCallingUserId()); 3524 3525 // Look for the original activity in the list... 3526 final int N = resolves != null ? resolves.size() : 0; 3527 for (int i=0; i<N; i++) { 3528 ResolveInfo rInfo = resolves.get(i); 3529 if (rInfo.activityInfo.packageName.equals(r.packageName) 3530 && rInfo.activityInfo.name.equals(r.info.name)) { 3531 // We found the current one... the next matching is 3532 // after it. 3533 i++; 3534 if (i<N) { 3535 aInfo = resolves.get(i).activityInfo; 3536 } 3537 if (debug) { 3538 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3539 + "/" + r.info.name); 3540 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3541 + "/" + aInfo.name); 3542 } 3543 break; 3544 } 3545 } 3546 } catch (RemoteException e) { 3547 } 3548 3549 if (aInfo == null) { 3550 // Nobody who is next! 3551 ActivityOptions.abort(options); 3552 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3553 return false; 3554 } 3555 3556 intent.setComponent(new ComponentName( 3557 aInfo.applicationInfo.packageName, aInfo.name)); 3558 intent.setFlags(intent.getFlags()&~( 3559 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3560 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3561 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3562 Intent.FLAG_ACTIVITY_NEW_TASK)); 3563 3564 // Okay now we need to start the new activity, replacing the 3565 // currently running activity. This is a little tricky because 3566 // we want to start the new one as if the current one is finished, 3567 // but not finish the current one first so that there is no flicker. 3568 // And thus... 3569 final boolean wasFinishing = r.finishing; 3570 r.finishing = true; 3571 3572 // Propagate reply information over to the new activity. 3573 final ActivityRecord resultTo = r.resultTo; 3574 final String resultWho = r.resultWho; 3575 final int requestCode = r.requestCode; 3576 r.resultTo = null; 3577 if (resultTo != null) { 3578 resultTo.removeResultsLocked(r, resultWho, requestCode); 3579 } 3580 3581 final long origId = Binder.clearCallingIdentity(); 3582 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3583 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3584 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3585 -1, r.launchedFromUid, 0, options, false, null, null, null); 3586 Binder.restoreCallingIdentity(origId); 3587 3588 r.finishing = wasFinishing; 3589 if (res != ActivityManager.START_SUCCESS) { 3590 return false; 3591 } 3592 return true; 3593 } 3594 } 3595 3596 @Override 3597 public final int startActivityFromRecents(int taskId, Bundle options) { 3598 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3599 String msg = "Permission Denial: startActivityFromRecents called without " + 3600 START_TASKS_FROM_RECENTS; 3601 Slog.w(TAG, msg); 3602 throw new SecurityException(msg); 3603 } 3604 return startActivityFromRecentsInner(taskId, options); 3605 } 3606 3607 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3608 final TaskRecord task; 3609 final int callingUid; 3610 final String callingPackage; 3611 final Intent intent; 3612 final int userId; 3613 synchronized (this) { 3614 task = recentTaskForIdLocked(taskId); 3615 if (task == null) { 3616 throw new IllegalArgumentException("Task " + taskId + " not found."); 3617 } 3618 callingUid = task.mCallingUid; 3619 callingPackage = task.mCallingPackage; 3620 intent = task.intent; 3621 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3622 userId = task.userId; 3623 } 3624 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3625 options, userId, null, task); 3626 } 3627 3628 final int startActivityInPackage(int uid, String callingPackage, 3629 Intent intent, String resolvedType, IBinder resultTo, 3630 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3631 IActivityContainer container, TaskRecord inTask) { 3632 3633 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3634 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3635 3636 // TODO: Switch to user app stacks here. 3637 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3638 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3639 null, null, null, options, userId, container, inTask); 3640 return ret; 3641 } 3642 3643 @Override 3644 public final int startActivities(IApplicationThread caller, String callingPackage, 3645 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3646 int userId) { 3647 enforceNotIsolatedCaller("startActivities"); 3648 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3649 false, ALLOW_FULL_ONLY, "startActivity", null); 3650 // TODO: Switch to user app stacks here. 3651 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3652 resolvedTypes, resultTo, options, userId); 3653 return ret; 3654 } 3655 3656 final int startActivitiesInPackage(int uid, String callingPackage, 3657 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3658 Bundle options, int userId) { 3659 3660 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3661 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3662 // TODO: Switch to user app stacks here. 3663 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3664 resultTo, options, userId); 3665 return ret; 3666 } 3667 3668 //explicitly remove thd old information in mRecentTasks when removing existing user. 3669 private void removeRecentTasksForUserLocked(int userId) { 3670 if(userId <= 0) { 3671 Slog.i(TAG, "Can't remove recent task on user " + userId); 3672 return; 3673 } 3674 3675 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3676 TaskRecord tr = mRecentTasks.get(i); 3677 if (tr.userId == userId) { 3678 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3679 + " when finishing user" + userId); 3680 mRecentTasks.remove(i); 3681 tr.removedFromRecents(); 3682 } 3683 } 3684 3685 // Remove tasks from persistent storage. 3686 notifyTaskPersisterLocked(null, true); 3687 } 3688 3689 // Sort by taskId 3690 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3691 @Override 3692 public int compare(TaskRecord lhs, TaskRecord rhs) { 3693 return rhs.taskId - lhs.taskId; 3694 } 3695 }; 3696 3697 // Extract the affiliates of the chain containing mRecentTasks[start]. 3698 private int processNextAffiliateChainLocked(int start) { 3699 final TaskRecord startTask = mRecentTasks.get(start); 3700 final int affiliateId = startTask.mAffiliatedTaskId; 3701 3702 // Quick identification of isolated tasks. I.e. those not launched behind. 3703 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3704 startTask.mNextAffiliate == null) { 3705 // There is still a slim chance that there are other tasks that point to this task 3706 // and that the chain is so messed up that this task no longer points to them but 3707 // the gain of this optimization outweighs the risk. 3708 startTask.inRecents = true; 3709 return start + 1; 3710 } 3711 3712 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3713 mTmpRecents.clear(); 3714 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3715 final TaskRecord task = mRecentTasks.get(i); 3716 if (task.mAffiliatedTaskId == affiliateId) { 3717 mRecentTasks.remove(i); 3718 mTmpRecents.add(task); 3719 } 3720 } 3721 3722 // Sort them all by taskId. That is the order they were create in and that order will 3723 // always be correct. 3724 Collections.sort(mTmpRecents, mTaskRecordComparator); 3725 3726 // Go through and fix up the linked list. 3727 // The first one is the end of the chain and has no next. 3728 final TaskRecord first = mTmpRecents.get(0); 3729 first.inRecents = true; 3730 if (first.mNextAffiliate != null) { 3731 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3732 first.setNextAffiliate(null); 3733 notifyTaskPersisterLocked(first, false); 3734 } 3735 // Everything in the middle is doubly linked from next to prev. 3736 final int tmpSize = mTmpRecents.size(); 3737 for (int i = 0; i < tmpSize - 1; ++i) { 3738 final TaskRecord next = mTmpRecents.get(i); 3739 final TaskRecord prev = mTmpRecents.get(i + 1); 3740 if (next.mPrevAffiliate != prev) { 3741 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3742 " setting prev=" + prev); 3743 next.setPrevAffiliate(prev); 3744 notifyTaskPersisterLocked(next, false); 3745 } 3746 if (prev.mNextAffiliate != next) { 3747 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3748 " setting next=" + next); 3749 prev.setNextAffiliate(next); 3750 notifyTaskPersisterLocked(prev, false); 3751 } 3752 prev.inRecents = true; 3753 } 3754 // The last one is the beginning of the list and has no prev. 3755 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3756 if (last.mPrevAffiliate != null) { 3757 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3758 last.setPrevAffiliate(null); 3759 notifyTaskPersisterLocked(last, false); 3760 } 3761 3762 // Insert the group back into mRecentTasks at start. 3763 mRecentTasks.addAll(start, mTmpRecents); 3764 3765 // Let the caller know where we left off. 3766 return start + tmpSize; 3767 } 3768 3769 /** 3770 * Update the recent tasks lists: make sure tasks should still be here (their 3771 * applications / activities still exist), update their availability, fixup ordering 3772 * of affiliations. 3773 */ 3774 void cleanupRecentTasksLocked(int userId) { 3775 if (mRecentTasks == null) { 3776 // Happens when called from the packagemanager broadcast before boot. 3777 return; 3778 } 3779 3780 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3781 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3782 final IPackageManager pm = AppGlobals.getPackageManager(); 3783 final ActivityInfo dummyAct = new ActivityInfo(); 3784 final ApplicationInfo dummyApp = new ApplicationInfo(); 3785 3786 int N = mRecentTasks.size(); 3787 3788 int[] users = userId == UserHandle.USER_ALL 3789 ? getUsersLocked() : new int[] { userId }; 3790 for (int user : users) { 3791 for (int i = 0; i < N; i++) { 3792 TaskRecord task = mRecentTasks.get(i); 3793 if (task.userId != user) { 3794 // Only look at tasks for the user ID of interest. 3795 continue; 3796 } 3797 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3798 // This situation is broken, and we should just get rid of it now. 3799 mRecentTasks.remove(i); 3800 task.removedFromRecents(); 3801 i--; 3802 N--; 3803 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3804 continue; 3805 } 3806 // Check whether this activity is currently available. 3807 if (task.realActivity != null) { 3808 ActivityInfo ai = availActCache.get(task.realActivity); 3809 if (ai == null) { 3810 try { 3811 ai = pm.getActivityInfo(task.realActivity, 3812 PackageManager.GET_UNINSTALLED_PACKAGES 3813 | PackageManager.GET_DISABLED_COMPONENTS, user); 3814 } catch (RemoteException e) { 3815 // Will never happen. 3816 continue; 3817 } 3818 if (ai == null) { 3819 ai = dummyAct; 3820 } 3821 availActCache.put(task.realActivity, ai); 3822 } 3823 if (ai == dummyAct) { 3824 // This could be either because the activity no longer exists, or the 3825 // app is temporarily gone. For the former we want to remove the recents 3826 // entry; for the latter we want to mark it as unavailable. 3827 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3828 if (app == null) { 3829 try { 3830 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3831 PackageManager.GET_UNINSTALLED_PACKAGES 3832 | PackageManager.GET_DISABLED_COMPONENTS, user); 3833 } catch (RemoteException e) { 3834 // Will never happen. 3835 continue; 3836 } 3837 if (app == null) { 3838 app = dummyApp; 3839 } 3840 availAppCache.put(task.realActivity.getPackageName(), app); 3841 } 3842 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3843 // Doesn't exist any more! Good-bye. 3844 mRecentTasks.remove(i); 3845 task.removedFromRecents(); 3846 i--; 3847 N--; 3848 Slog.w(TAG, "Removing no longer valid recent: " + task); 3849 continue; 3850 } else { 3851 // Otherwise just not available for now. 3852 if (task.isAvailable) { 3853 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3854 + task); 3855 } 3856 task.isAvailable = false; 3857 } 3858 } else { 3859 if (!ai.enabled || !ai.applicationInfo.enabled 3860 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3861 if (task.isAvailable) { 3862 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3863 + task + " (enabled=" + ai.enabled + "/" 3864 + ai.applicationInfo.enabled + " flags=" 3865 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3866 } 3867 task.isAvailable = false; 3868 } else { 3869 if (!task.isAvailable) { 3870 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3871 + task); 3872 } 3873 task.isAvailable = true; 3874 } 3875 } 3876 } 3877 } 3878 } 3879 3880 // Verify the affiliate chain for each task. 3881 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3882 } 3883 3884 mTmpRecents.clear(); 3885 // mRecentTasks is now in sorted, affiliated order. 3886 } 3887 3888 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3889 int N = mRecentTasks.size(); 3890 TaskRecord top = task; 3891 int topIndex = taskIndex; 3892 while (top.mNextAffiliate != null && topIndex > 0) { 3893 top = top.mNextAffiliate; 3894 topIndex--; 3895 } 3896 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3897 + topIndex + " from intial " + taskIndex); 3898 // Find the end of the chain, doing a sanity check along the way. 3899 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3900 int endIndex = topIndex; 3901 TaskRecord prev = top; 3902 while (endIndex < N) { 3903 TaskRecord cur = mRecentTasks.get(endIndex); 3904 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3905 + endIndex + " " + cur); 3906 if (cur == top) { 3907 // Verify start of the chain. 3908 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3909 Slog.wtf(TAG, "Bad chain @" + endIndex 3910 + ": first task has next affiliate: " + prev); 3911 sane = false; 3912 break; 3913 } 3914 } else { 3915 // Verify middle of the chain's next points back to the one before. 3916 if (cur.mNextAffiliate != prev 3917 || cur.mNextAffiliateTaskId != prev.taskId) { 3918 Slog.wtf(TAG, "Bad chain @" + endIndex 3919 + ": middle task " + cur + " @" + endIndex 3920 + " has bad next affiliate " 3921 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3922 + ", expected " + prev); 3923 sane = false; 3924 break; 3925 } 3926 } 3927 if (cur.mPrevAffiliateTaskId == -1) { 3928 // Chain ends here. 3929 if (cur.mPrevAffiliate != null) { 3930 Slog.wtf(TAG, "Bad chain @" + endIndex 3931 + ": last task " + cur + " has previous affiliate " 3932 + cur.mPrevAffiliate); 3933 sane = false; 3934 } 3935 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3936 break; 3937 } else { 3938 // Verify middle of the chain's prev points to a valid item. 3939 if (cur.mPrevAffiliate == null) { 3940 Slog.wtf(TAG, "Bad chain @" + endIndex 3941 + ": task " + cur + " has previous affiliate " 3942 + cur.mPrevAffiliate + " but should be id " 3943 + cur.mPrevAffiliate); 3944 sane = false; 3945 break; 3946 } 3947 } 3948 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3949 Slog.wtf(TAG, "Bad chain @" + endIndex 3950 + ": task " + cur + " has affiliated id " 3951 + cur.mAffiliatedTaskId + " but should be " 3952 + task.mAffiliatedTaskId); 3953 sane = false; 3954 break; 3955 } 3956 prev = cur; 3957 endIndex++; 3958 if (endIndex >= N) { 3959 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3960 + ": last task " + prev); 3961 sane = false; 3962 break; 3963 } 3964 } 3965 if (sane) { 3966 if (endIndex < taskIndex) { 3967 Slog.wtf(TAG, "Bad chain @" + endIndex 3968 + ": did not extend to task " + task + " @" + taskIndex); 3969 sane = false; 3970 } 3971 } 3972 if (sane) { 3973 // All looks good, we can just move all of the affiliated tasks 3974 // to the top. 3975 for (int i=topIndex; i<=endIndex; i++) { 3976 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3977 + " from " + i + " to " + (i-topIndex)); 3978 TaskRecord cur = mRecentTasks.remove(i); 3979 mRecentTasks.add(i-topIndex, cur); 3980 } 3981 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3982 + " to " + endIndex); 3983 return true; 3984 } 3985 3986 // Whoops, couldn't do it. 3987 return false; 3988 } 3989 3990 final void addRecentTaskLocked(TaskRecord task) { 3991 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3992 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3993 3994 int N = mRecentTasks.size(); 3995 // Quick case: check if the top-most recent task is the same. 3996 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3997 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 3998 return; 3999 } 4000 // Another quick case: check if this is part of a set of affiliated 4001 // tasks that are at the top. 4002 if (isAffiliated && N > 0 && task.inRecents 4003 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4004 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4005 + " at top when adding " + task); 4006 return; 4007 } 4008 // Another quick case: never add voice sessions. 4009 if (task.voiceSession != null) { 4010 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4011 return; 4012 } 4013 4014 boolean needAffiliationFix = false; 4015 4016 // Slightly less quick case: the task is already in recents, so all we need 4017 // to do is move it. 4018 if (task.inRecents) { 4019 int taskIndex = mRecentTasks.indexOf(task); 4020 if (taskIndex >= 0) { 4021 if (!isAffiliated) { 4022 // Simple case: this is not an affiliated task, so we just move it to the front. 4023 mRecentTasks.remove(taskIndex); 4024 mRecentTasks.add(0, task); 4025 notifyTaskPersisterLocked(task, false); 4026 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4027 + " from " + taskIndex); 4028 return; 4029 } else { 4030 // More complicated: need to keep all affiliated tasks together. 4031 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4032 // All went well. 4033 return; 4034 } 4035 4036 // Uh oh... something bad in the affiliation chain, try to rebuild 4037 // everything and then go through our general path of adding a new task. 4038 needAffiliationFix = true; 4039 } 4040 } else { 4041 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4042 needAffiliationFix = true; 4043 } 4044 } 4045 4046 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4047 trimRecentsForTaskLocked(task, true); 4048 4049 N = mRecentTasks.size(); 4050 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4051 final TaskRecord tr = mRecentTasks.remove(N - 1); 4052 tr.removedFromRecents(); 4053 N--; 4054 } 4055 task.inRecents = true; 4056 if (!isAffiliated || needAffiliationFix) { 4057 // If this is a simple non-affiliated task, or we had some failure trying to 4058 // handle it as part of an affilated task, then just place it at the top. 4059 mRecentTasks.add(0, task); 4060 } else if (isAffiliated) { 4061 // If this is a new affiliated task, then move all of the affiliated tasks 4062 // to the front and insert this new one. 4063 TaskRecord other = task.mNextAffiliate; 4064 if (other == null) { 4065 other = task.mPrevAffiliate; 4066 } 4067 if (other != null) { 4068 int otherIndex = mRecentTasks.indexOf(other); 4069 if (otherIndex >= 0) { 4070 // Insert new task at appropriate location. 4071 int taskIndex; 4072 if (other == task.mNextAffiliate) { 4073 // We found the index of our next affiliation, which is who is 4074 // before us in the list, so add after that point. 4075 taskIndex = otherIndex+1; 4076 } else { 4077 // We found the index of our previous affiliation, which is who is 4078 // after us in the list, so add at their position. 4079 taskIndex = otherIndex; 4080 } 4081 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4082 + taskIndex + ": " + task); 4083 mRecentTasks.add(taskIndex, task); 4084 4085 // Now move everything to the front. 4086 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4087 // All went well. 4088 return; 4089 } 4090 4091 // Uh oh... something bad in the affiliation chain, try to rebuild 4092 // everything and then go through our general path of adding a new task. 4093 needAffiliationFix = true; 4094 } else { 4095 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4096 + other); 4097 needAffiliationFix = true; 4098 } 4099 } else { 4100 if (DEBUG_RECENTS) Slog.d(TAG, 4101 "addRecent: adding affiliated task without next/prev:" + task); 4102 needAffiliationFix = true; 4103 } 4104 } 4105 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4106 4107 if (needAffiliationFix) { 4108 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4109 cleanupRecentTasksLocked(task.userId); 4110 } 4111 } 4112 4113 /** 4114 * If needed, remove oldest existing entries in recents that are for the same kind 4115 * of task as the given one. 4116 */ 4117 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4118 int N = mRecentTasks.size(); 4119 final Intent intent = task.intent; 4120 final boolean document = intent != null && intent.isDocument(); 4121 4122 int maxRecents = task.maxRecents - 1; 4123 for (int i=0; i<N; i++) { 4124 final TaskRecord tr = mRecentTasks.get(i); 4125 if (task != tr) { 4126 if (task.userId != tr.userId) { 4127 continue; 4128 } 4129 if (i > MAX_RECENT_BITMAPS) { 4130 tr.freeLastThumbnail(); 4131 } 4132 final Intent trIntent = tr.intent; 4133 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4134 (intent == null || !intent.filterEquals(trIntent))) { 4135 continue; 4136 } 4137 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4138 if (document && trIsDocument) { 4139 // These are the same document activity (not necessarily the same doc). 4140 if (maxRecents > 0) { 4141 --maxRecents; 4142 continue; 4143 } 4144 // Hit the maximum number of documents for this task. Fall through 4145 // and remove this document from recents. 4146 } else if (document || trIsDocument) { 4147 // Only one of these is a document. Not the droid we're looking for. 4148 continue; 4149 } 4150 } 4151 4152 if (!doTrim) { 4153 // If the caller is not actually asking for a trim, just tell them we reached 4154 // a point where the trim would happen. 4155 return i; 4156 } 4157 4158 // Either task and tr are the same or, their affinities match or their intents match 4159 // and neither of them is a document, or they are documents using the same activity 4160 // and their maxRecents has been reached. 4161 tr.disposeThumbnail(); 4162 mRecentTasks.remove(i); 4163 if (task != tr) { 4164 tr.removedFromRecents(); 4165 } 4166 i--; 4167 N--; 4168 if (task.intent == null) { 4169 // If the new recent task we are adding is not fully 4170 // specified, then replace it with the existing recent task. 4171 task = tr; 4172 } 4173 notifyTaskPersisterLocked(tr, false); 4174 } 4175 4176 return -1; 4177 } 4178 4179 @Override 4180 public void reportActivityFullyDrawn(IBinder token) { 4181 synchronized (this) { 4182 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4183 if (r == null) { 4184 return; 4185 } 4186 r.reportFullyDrawnLocked(); 4187 } 4188 } 4189 4190 @Override 4191 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4192 synchronized (this) { 4193 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4194 if (r == null) { 4195 return; 4196 } 4197 final long origId = Binder.clearCallingIdentity(); 4198 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4199 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4200 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4201 if (config != null) { 4202 r.frozenBeforeDestroy = true; 4203 if (!updateConfigurationLocked(config, r, false, false)) { 4204 mStackSupervisor.resumeTopActivitiesLocked(); 4205 } 4206 } 4207 Binder.restoreCallingIdentity(origId); 4208 } 4209 } 4210 4211 @Override 4212 public int getRequestedOrientation(IBinder token) { 4213 synchronized (this) { 4214 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4215 if (r == null) { 4216 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4217 } 4218 return mWindowManager.getAppOrientation(r.appToken); 4219 } 4220 } 4221 4222 /** 4223 * This is the internal entry point for handling Activity.finish(). 4224 * 4225 * @param token The Binder token referencing the Activity we want to finish. 4226 * @param resultCode Result code, if any, from this Activity. 4227 * @param resultData Result data (Intent), if any, from this Activity. 4228 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4229 * the root Activity in the task. 4230 * 4231 * @return Returns true if the activity successfully finished, or false if it is still running. 4232 */ 4233 @Override 4234 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4235 boolean finishTask) { 4236 // Refuse possible leaked file descriptors 4237 if (resultData != null && resultData.hasFileDescriptors() == true) { 4238 throw new IllegalArgumentException("File descriptors passed in Intent"); 4239 } 4240 4241 synchronized(this) { 4242 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4243 if (r == null) { 4244 return true; 4245 } 4246 // Keep track of the root activity of the task before we finish it 4247 TaskRecord tr = r.task; 4248 ActivityRecord rootR = tr.getRootActivity(); 4249 if (rootR == null) { 4250 Slog.w(TAG, "Finishing task with all activities already finished"); 4251 } 4252 // Do not allow task to finish in Lock Task mode. 4253 if (tr == mStackSupervisor.mLockTaskModeTask) { 4254 if (rootR == r) { 4255 Slog.i(TAG, "Not finishing task in lock task mode"); 4256 mStackSupervisor.showLockTaskToast(); 4257 return false; 4258 } 4259 } 4260 if (mController != null) { 4261 // Find the first activity that is not finishing. 4262 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4263 if (next != null) { 4264 // ask watcher if this is allowed 4265 boolean resumeOK = true; 4266 try { 4267 resumeOK = mController.activityResuming(next.packageName); 4268 } catch (RemoteException e) { 4269 mController = null; 4270 Watchdog.getInstance().setActivityController(null); 4271 } 4272 4273 if (!resumeOK) { 4274 Slog.i(TAG, "Not finishing activity because controller resumed"); 4275 return false; 4276 } 4277 } 4278 } 4279 final long origId = Binder.clearCallingIdentity(); 4280 try { 4281 boolean res; 4282 if (finishTask && r == rootR) { 4283 // If requested, remove the task that is associated to this activity only if it 4284 // was the root activity in the task. The result code and data is ignored 4285 // because we don't support returning them across task boundaries. 4286 res = removeTaskByIdLocked(tr.taskId, false); 4287 if (!res) { 4288 Slog.i(TAG, "Removing task failed to finish activity"); 4289 } 4290 } else { 4291 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4292 resultData, "app-request", true); 4293 if (!res) { 4294 Slog.i(TAG, "Failed to finish by app-request"); 4295 } 4296 } 4297 return res; 4298 } finally { 4299 Binder.restoreCallingIdentity(origId); 4300 } 4301 } 4302 } 4303 4304 @Override 4305 public final void finishHeavyWeightApp() { 4306 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4307 != PackageManager.PERMISSION_GRANTED) { 4308 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4309 + Binder.getCallingPid() 4310 + ", uid=" + Binder.getCallingUid() 4311 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4312 Slog.w(TAG, msg); 4313 throw new SecurityException(msg); 4314 } 4315 4316 synchronized(this) { 4317 if (mHeavyWeightProcess == null) { 4318 return; 4319 } 4320 4321 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4322 mHeavyWeightProcess.activities); 4323 for (int i=0; i<activities.size(); i++) { 4324 ActivityRecord r = activities.get(i); 4325 if (!r.finishing) { 4326 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4327 null, "finish-heavy", true); 4328 } 4329 } 4330 4331 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4332 mHeavyWeightProcess.userId, 0)); 4333 mHeavyWeightProcess = null; 4334 } 4335 } 4336 4337 @Override 4338 public void crashApplication(int uid, int initialPid, String packageName, 4339 String message) { 4340 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4341 != PackageManager.PERMISSION_GRANTED) { 4342 String msg = "Permission Denial: crashApplication() from pid=" 4343 + Binder.getCallingPid() 4344 + ", uid=" + Binder.getCallingUid() 4345 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4346 Slog.w(TAG, msg); 4347 throw new SecurityException(msg); 4348 } 4349 4350 synchronized(this) { 4351 ProcessRecord proc = null; 4352 4353 // Figure out which process to kill. We don't trust that initialPid 4354 // still has any relation to current pids, so must scan through the 4355 // list. 4356 synchronized (mPidsSelfLocked) { 4357 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4358 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4359 if (p.uid != uid) { 4360 continue; 4361 } 4362 if (p.pid == initialPid) { 4363 proc = p; 4364 break; 4365 } 4366 if (p.pkgList.containsKey(packageName)) { 4367 proc = p; 4368 } 4369 } 4370 } 4371 4372 if (proc == null) { 4373 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4374 + " initialPid=" + initialPid 4375 + " packageName=" + packageName); 4376 return; 4377 } 4378 4379 if (proc.thread != null) { 4380 if (proc.pid == Process.myPid()) { 4381 Log.w(TAG, "crashApplication: trying to crash self!"); 4382 return; 4383 } 4384 long ident = Binder.clearCallingIdentity(); 4385 try { 4386 proc.thread.scheduleCrash(message); 4387 } catch (RemoteException e) { 4388 } 4389 Binder.restoreCallingIdentity(ident); 4390 } 4391 } 4392 } 4393 4394 @Override 4395 public final void finishSubActivity(IBinder token, String resultWho, 4396 int requestCode) { 4397 synchronized(this) { 4398 final long origId = Binder.clearCallingIdentity(); 4399 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4400 if (r != null) { 4401 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4402 } 4403 Binder.restoreCallingIdentity(origId); 4404 } 4405 } 4406 4407 @Override 4408 public boolean finishActivityAffinity(IBinder token) { 4409 synchronized(this) { 4410 final long origId = Binder.clearCallingIdentity(); 4411 try { 4412 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4413 4414 ActivityRecord rootR = r.task.getRootActivity(); 4415 // Do not allow task to finish in Lock Task mode. 4416 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4417 if (rootR == r) { 4418 mStackSupervisor.showLockTaskToast(); 4419 return false; 4420 } 4421 } 4422 boolean res = false; 4423 if (r != null) { 4424 res = r.task.stack.finishActivityAffinityLocked(r); 4425 } 4426 return res; 4427 } finally { 4428 Binder.restoreCallingIdentity(origId); 4429 } 4430 } 4431 } 4432 4433 @Override 4434 public void finishVoiceTask(IVoiceInteractionSession session) { 4435 synchronized(this) { 4436 final long origId = Binder.clearCallingIdentity(); 4437 try { 4438 mStackSupervisor.finishVoiceTask(session); 4439 } finally { 4440 Binder.restoreCallingIdentity(origId); 4441 } 4442 } 4443 4444 } 4445 4446 @Override 4447 public boolean releaseActivityInstance(IBinder token) { 4448 synchronized(this) { 4449 final long origId = Binder.clearCallingIdentity(); 4450 try { 4451 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4452 if (r.task == null || r.task.stack == null) { 4453 return false; 4454 } 4455 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4456 } finally { 4457 Binder.restoreCallingIdentity(origId); 4458 } 4459 } 4460 } 4461 4462 @Override 4463 public void releaseSomeActivities(IApplicationThread appInt) { 4464 synchronized(this) { 4465 final long origId = Binder.clearCallingIdentity(); 4466 try { 4467 ProcessRecord app = getRecordForAppLocked(appInt); 4468 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4469 } finally { 4470 Binder.restoreCallingIdentity(origId); 4471 } 4472 } 4473 } 4474 4475 @Override 4476 public boolean willActivityBeVisible(IBinder token) { 4477 synchronized(this) { 4478 ActivityStack stack = ActivityRecord.getStackLocked(token); 4479 if (stack != null) { 4480 return stack.willActivityBeVisibleLocked(token); 4481 } 4482 return false; 4483 } 4484 } 4485 4486 @Override 4487 public void overridePendingTransition(IBinder token, String packageName, 4488 int enterAnim, int exitAnim) { 4489 synchronized(this) { 4490 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4491 if (self == null) { 4492 return; 4493 } 4494 4495 final long origId = Binder.clearCallingIdentity(); 4496 4497 if (self.state == ActivityState.RESUMED 4498 || self.state == ActivityState.PAUSING) { 4499 mWindowManager.overridePendingAppTransition(packageName, 4500 enterAnim, exitAnim, null); 4501 } 4502 4503 Binder.restoreCallingIdentity(origId); 4504 } 4505 } 4506 4507 /** 4508 * Main function for removing an existing process from the activity manager 4509 * as a result of that process going away. Clears out all connections 4510 * to the process. 4511 */ 4512 private final void handleAppDiedLocked(ProcessRecord app, 4513 boolean restarting, boolean allowRestart) { 4514 int pid = app.pid; 4515 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4516 if (!kept && !restarting) { 4517 removeLruProcessLocked(app); 4518 if (pid > 0) { 4519 ProcessList.remove(pid); 4520 } 4521 } 4522 4523 if (mProfileProc == app) { 4524 clearProfilerLocked(); 4525 } 4526 4527 // Remove this application's activities from active lists. 4528 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4529 4530 app.activities.clear(); 4531 4532 if (app.instrumentationClass != null) { 4533 Slog.w(TAG, "Crash of app " + app.processName 4534 + " running instrumentation " + app.instrumentationClass); 4535 Bundle info = new Bundle(); 4536 info.putString("shortMsg", "Process crashed."); 4537 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4538 } 4539 4540 if (!restarting) { 4541 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4542 // If there was nothing to resume, and we are not already 4543 // restarting this process, but there is a visible activity that 4544 // is hosted by the process... then make sure all visible 4545 // activities are running, taking care of restarting this 4546 // process. 4547 if (hasVisibleActivities) { 4548 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4549 } 4550 } 4551 } 4552 } 4553 4554 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4555 IBinder threadBinder = thread.asBinder(); 4556 // Find the application record. 4557 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4558 ProcessRecord rec = mLruProcesses.get(i); 4559 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4560 return i; 4561 } 4562 } 4563 return -1; 4564 } 4565 4566 final ProcessRecord getRecordForAppLocked( 4567 IApplicationThread thread) { 4568 if (thread == null) { 4569 return null; 4570 } 4571 4572 int appIndex = getLRURecordIndexForAppLocked(thread); 4573 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4574 } 4575 4576 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4577 // If there are no longer any background processes running, 4578 // and the app that died was not running instrumentation, 4579 // then tell everyone we are now low on memory. 4580 boolean haveBg = false; 4581 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4582 ProcessRecord rec = mLruProcesses.get(i); 4583 if (rec.thread != null 4584 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4585 haveBg = true; 4586 break; 4587 } 4588 } 4589 4590 if (!haveBg) { 4591 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4592 if (doReport) { 4593 long now = SystemClock.uptimeMillis(); 4594 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4595 doReport = false; 4596 } else { 4597 mLastMemUsageReportTime = now; 4598 } 4599 } 4600 final ArrayList<ProcessMemInfo> memInfos 4601 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4602 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4603 long now = SystemClock.uptimeMillis(); 4604 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4605 ProcessRecord rec = mLruProcesses.get(i); 4606 if (rec == dyingProc || rec.thread == null) { 4607 continue; 4608 } 4609 if (doReport) { 4610 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4611 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4612 } 4613 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4614 // The low memory report is overriding any current 4615 // state for a GC request. Make sure to do 4616 // heavy/important/visible/foreground processes first. 4617 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4618 rec.lastRequestedGc = 0; 4619 } else { 4620 rec.lastRequestedGc = rec.lastLowMemory; 4621 } 4622 rec.reportLowMemory = true; 4623 rec.lastLowMemory = now; 4624 mProcessesToGc.remove(rec); 4625 addProcessToGcListLocked(rec); 4626 } 4627 } 4628 if (doReport) { 4629 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4630 mHandler.sendMessage(msg); 4631 } 4632 scheduleAppGcsLocked(); 4633 } 4634 } 4635 4636 final void appDiedLocked(ProcessRecord app) { 4637 appDiedLocked(app, app.pid, app.thread); 4638 } 4639 4640 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4641 // First check if this ProcessRecord is actually active for the pid. 4642 synchronized (mPidsSelfLocked) { 4643 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4644 if (curProc != app) { 4645 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4646 return; 4647 } 4648 } 4649 4650 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4651 synchronized (stats) { 4652 stats.noteProcessDiedLocked(app.info.uid, pid); 4653 } 4654 4655 Process.killProcessQuiet(pid); 4656 Process.killProcessGroup(app.info.uid, pid); 4657 app.killed = true; 4658 4659 // Clean up already done if the process has been re-started. 4660 if (app.pid == pid && app.thread != null && 4661 app.thread.asBinder() == thread.asBinder()) { 4662 boolean doLowMem = app.instrumentationClass == null; 4663 boolean doOomAdj = doLowMem; 4664 if (!app.killedByAm) { 4665 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4666 + ") has died"); 4667 mAllowLowerMemLevel = true; 4668 } else { 4669 // Note that we always want to do oom adj to update our state with the 4670 // new number of procs. 4671 mAllowLowerMemLevel = false; 4672 doLowMem = false; 4673 } 4674 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4675 if (DEBUG_CLEANUP) Slog.v( 4676 TAG, "Dying app: " + app + ", pid: " + pid 4677 + ", thread: " + thread.asBinder()); 4678 handleAppDiedLocked(app, false, true); 4679 4680 if (doOomAdj) { 4681 updateOomAdjLocked(); 4682 } 4683 if (doLowMem) { 4684 doLowMemReportIfNeededLocked(app); 4685 } 4686 } else if (app.pid != pid) { 4687 // A new process has already been started. 4688 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4689 + ") has died and restarted (pid " + app.pid + ")."); 4690 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4691 } else if (DEBUG_PROCESSES) { 4692 Slog.d(TAG, "Received spurious death notification for thread " 4693 + thread.asBinder()); 4694 } 4695 } 4696 4697 /** 4698 * If a stack trace dump file is configured, dump process stack traces. 4699 * @param clearTraces causes the dump file to be erased prior to the new 4700 * traces being written, if true; when false, the new traces will be 4701 * appended to any existing file content. 4702 * @param firstPids of dalvik VM processes to dump stack traces for first 4703 * @param lastPids of dalvik VM processes to dump stack traces for last 4704 * @param nativeProcs optional list of native process names to dump stack crawls 4705 * @return file containing stack traces, or null if no dump file is configured 4706 */ 4707 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4708 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4709 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4710 if (tracesPath == null || tracesPath.length() == 0) { 4711 return null; 4712 } 4713 4714 File tracesFile = new File(tracesPath); 4715 try { 4716 File tracesDir = tracesFile.getParentFile(); 4717 if (!tracesDir.exists()) { 4718 tracesDir.mkdirs(); 4719 if (!SELinux.restorecon(tracesDir)) { 4720 return null; 4721 } 4722 } 4723 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4724 4725 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4726 tracesFile.createNewFile(); 4727 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4728 } catch (IOException e) { 4729 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4730 return null; 4731 } 4732 4733 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4734 return tracesFile; 4735 } 4736 4737 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4738 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4739 // Use a FileObserver to detect when traces finish writing. 4740 // The order of traces is considered important to maintain for legibility. 4741 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4742 @Override 4743 public synchronized void onEvent(int event, String path) { notify(); } 4744 }; 4745 4746 try { 4747 observer.startWatching(); 4748 4749 // First collect all of the stacks of the most important pids. 4750 if (firstPids != null) { 4751 try { 4752 int num = firstPids.size(); 4753 for (int i = 0; i < num; i++) { 4754 synchronized (observer) { 4755 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4756 observer.wait(200); // Wait for write-close, give up after 200msec 4757 } 4758 } 4759 } catch (InterruptedException e) { 4760 Slog.wtf(TAG, e); 4761 } 4762 } 4763 4764 // Next collect the stacks of the native pids 4765 if (nativeProcs != null) { 4766 int[] pids = Process.getPidsForCommands(nativeProcs); 4767 if (pids != null) { 4768 for (int pid : pids) { 4769 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4770 } 4771 } 4772 } 4773 4774 // Lastly, measure CPU usage. 4775 if (processCpuTracker != null) { 4776 processCpuTracker.init(); 4777 System.gc(); 4778 processCpuTracker.update(); 4779 try { 4780 synchronized (processCpuTracker) { 4781 processCpuTracker.wait(500); // measure over 1/2 second. 4782 } 4783 } catch (InterruptedException e) { 4784 } 4785 processCpuTracker.update(); 4786 4787 // We'll take the stack crawls of just the top apps using CPU. 4788 final int N = processCpuTracker.countWorkingStats(); 4789 int numProcs = 0; 4790 for (int i=0; i<N && numProcs<5; i++) { 4791 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4792 if (lastPids.indexOfKey(stats.pid) >= 0) { 4793 numProcs++; 4794 try { 4795 synchronized (observer) { 4796 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4797 observer.wait(200); // Wait for write-close, give up after 200msec 4798 } 4799 } catch (InterruptedException e) { 4800 Slog.wtf(TAG, e); 4801 } 4802 4803 } 4804 } 4805 } 4806 } finally { 4807 observer.stopWatching(); 4808 } 4809 } 4810 4811 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4812 if (true || IS_USER_BUILD) { 4813 return; 4814 } 4815 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4816 if (tracesPath == null || tracesPath.length() == 0) { 4817 return; 4818 } 4819 4820 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4821 StrictMode.allowThreadDiskWrites(); 4822 try { 4823 final File tracesFile = new File(tracesPath); 4824 final File tracesDir = tracesFile.getParentFile(); 4825 final File tracesTmp = new File(tracesDir, "__tmp__"); 4826 try { 4827 if (!tracesDir.exists()) { 4828 tracesDir.mkdirs(); 4829 if (!SELinux.restorecon(tracesDir.getPath())) { 4830 return; 4831 } 4832 } 4833 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4834 4835 if (tracesFile.exists()) { 4836 tracesTmp.delete(); 4837 tracesFile.renameTo(tracesTmp); 4838 } 4839 StringBuilder sb = new StringBuilder(); 4840 Time tobj = new Time(); 4841 tobj.set(System.currentTimeMillis()); 4842 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4843 sb.append(": "); 4844 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4845 sb.append(" since "); 4846 sb.append(msg); 4847 FileOutputStream fos = new FileOutputStream(tracesFile); 4848 fos.write(sb.toString().getBytes()); 4849 if (app == null) { 4850 fos.write("\n*** No application process!".getBytes()); 4851 } 4852 fos.close(); 4853 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4854 } catch (IOException e) { 4855 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4856 return; 4857 } 4858 4859 if (app != null) { 4860 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4861 firstPids.add(app.pid); 4862 dumpStackTraces(tracesPath, firstPids, null, null, null); 4863 } 4864 4865 File lastTracesFile = null; 4866 File curTracesFile = null; 4867 for (int i=9; i>=0; i--) { 4868 String name = String.format(Locale.US, "slow%02d.txt", i); 4869 curTracesFile = new File(tracesDir, name); 4870 if (curTracesFile.exists()) { 4871 if (lastTracesFile != null) { 4872 curTracesFile.renameTo(lastTracesFile); 4873 } else { 4874 curTracesFile.delete(); 4875 } 4876 } 4877 lastTracesFile = curTracesFile; 4878 } 4879 tracesFile.renameTo(curTracesFile); 4880 if (tracesTmp.exists()) { 4881 tracesTmp.renameTo(tracesFile); 4882 } 4883 } finally { 4884 StrictMode.setThreadPolicy(oldPolicy); 4885 } 4886 } 4887 4888 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4889 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4890 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4891 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4892 4893 if (mController != null) { 4894 try { 4895 // 0 == continue, -1 = kill process immediately 4896 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4897 if (res < 0 && app.pid != MY_PID) { 4898 app.kill("anr", true); 4899 } 4900 } catch (RemoteException e) { 4901 mController = null; 4902 Watchdog.getInstance().setActivityController(null); 4903 } 4904 } 4905 4906 long anrTime = SystemClock.uptimeMillis(); 4907 if (MONITOR_CPU_USAGE) { 4908 updateCpuStatsNow(); 4909 } 4910 4911 synchronized (this) { 4912 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4913 if (mShuttingDown) { 4914 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4915 return; 4916 } else if (app.notResponding) { 4917 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4918 return; 4919 } else if (app.crashing) { 4920 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4921 return; 4922 } 4923 4924 // In case we come through here for the same app before completing 4925 // this one, mark as anring now so we will bail out. 4926 app.notResponding = true; 4927 4928 // Log the ANR to the event log. 4929 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4930 app.processName, app.info.flags, annotation); 4931 4932 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4933 firstPids.add(app.pid); 4934 4935 int parentPid = app.pid; 4936 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4937 if (parentPid != app.pid) firstPids.add(parentPid); 4938 4939 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4940 4941 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4942 ProcessRecord r = mLruProcesses.get(i); 4943 if (r != null && r.thread != null) { 4944 int pid = r.pid; 4945 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4946 if (r.persistent) { 4947 firstPids.add(pid); 4948 } else { 4949 lastPids.put(pid, Boolean.TRUE); 4950 } 4951 } 4952 } 4953 } 4954 } 4955 4956 // Log the ANR to the main log. 4957 StringBuilder info = new StringBuilder(); 4958 info.setLength(0); 4959 info.append("ANR in ").append(app.processName); 4960 if (activity != null && activity.shortComponentName != null) { 4961 info.append(" (").append(activity.shortComponentName).append(")"); 4962 } 4963 info.append("\n"); 4964 info.append("PID: ").append(app.pid).append("\n"); 4965 if (annotation != null) { 4966 info.append("Reason: ").append(annotation).append("\n"); 4967 } 4968 if (parent != null && parent != activity) { 4969 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4970 } 4971 4972 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4973 4974 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4975 NATIVE_STACKS_OF_INTEREST); 4976 4977 String cpuInfo = null; 4978 if (MONITOR_CPU_USAGE) { 4979 updateCpuStatsNow(); 4980 synchronized (mProcessCpuTracker) { 4981 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4982 } 4983 info.append(processCpuTracker.printCurrentLoad()); 4984 info.append(cpuInfo); 4985 } 4986 4987 info.append(processCpuTracker.printCurrentState(anrTime)); 4988 4989 Slog.e(TAG, info.toString()); 4990 if (tracesFile == null) { 4991 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4992 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4993 } 4994 4995 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4996 cpuInfo, tracesFile, null); 4997 4998 if (mController != null) { 4999 try { 5000 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5001 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5002 if (res != 0) { 5003 if (res < 0 && app.pid != MY_PID) { 5004 app.kill("anr", true); 5005 } else { 5006 synchronized (this) { 5007 mServices.scheduleServiceTimeoutLocked(app); 5008 } 5009 } 5010 return; 5011 } 5012 } catch (RemoteException e) { 5013 mController = null; 5014 Watchdog.getInstance().setActivityController(null); 5015 } 5016 } 5017 5018 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5019 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5020 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5021 5022 synchronized (this) { 5023 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5024 app.kill("bg anr", true); 5025 return; 5026 } 5027 5028 // Set the app's notResponding state, and look up the errorReportReceiver 5029 makeAppNotRespondingLocked(app, 5030 activity != null ? activity.shortComponentName : null, 5031 annotation != null ? "ANR " + annotation : "ANR", 5032 info.toString()); 5033 5034 // Bring up the infamous App Not Responding dialog 5035 Message msg = Message.obtain(); 5036 HashMap<String, Object> map = new HashMap<String, Object>(); 5037 msg.what = SHOW_NOT_RESPONDING_MSG; 5038 msg.obj = map; 5039 msg.arg1 = aboveSystem ? 1 : 0; 5040 map.put("app", app); 5041 if (activity != null) { 5042 map.put("activity", activity); 5043 } 5044 5045 mHandler.sendMessage(msg); 5046 } 5047 } 5048 5049 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5050 if (!mLaunchWarningShown) { 5051 mLaunchWarningShown = true; 5052 mHandler.post(new Runnable() { 5053 @Override 5054 public void run() { 5055 synchronized (ActivityManagerService.this) { 5056 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5057 d.show(); 5058 mHandler.postDelayed(new Runnable() { 5059 @Override 5060 public void run() { 5061 synchronized (ActivityManagerService.this) { 5062 d.dismiss(); 5063 mLaunchWarningShown = false; 5064 } 5065 } 5066 }, 4000); 5067 } 5068 } 5069 }); 5070 } 5071 } 5072 5073 @Override 5074 public boolean clearApplicationUserData(final String packageName, 5075 final IPackageDataObserver observer, int userId) { 5076 enforceNotIsolatedCaller("clearApplicationUserData"); 5077 int uid = Binder.getCallingUid(); 5078 int pid = Binder.getCallingPid(); 5079 userId = handleIncomingUser(pid, uid, 5080 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5081 long callingId = Binder.clearCallingIdentity(); 5082 try { 5083 IPackageManager pm = AppGlobals.getPackageManager(); 5084 int pkgUid = -1; 5085 synchronized(this) { 5086 try { 5087 pkgUid = pm.getPackageUid(packageName, userId); 5088 } catch (RemoteException e) { 5089 } 5090 if (pkgUid == -1) { 5091 Slog.w(TAG, "Invalid packageName: " + packageName); 5092 if (observer != null) { 5093 try { 5094 observer.onRemoveCompleted(packageName, false); 5095 } catch (RemoteException e) { 5096 Slog.i(TAG, "Observer no longer exists."); 5097 } 5098 } 5099 return false; 5100 } 5101 if (uid == pkgUid || checkComponentPermission( 5102 android.Manifest.permission.CLEAR_APP_USER_DATA, 5103 pid, uid, -1, true) 5104 == PackageManager.PERMISSION_GRANTED) { 5105 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5106 } else { 5107 throw new SecurityException("PID " + pid + " does not have permission " 5108 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5109 + " of package " + packageName); 5110 } 5111 5112 // Remove all tasks match the cleared application package and user 5113 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5114 final TaskRecord tr = mRecentTasks.get(i); 5115 final String taskPackageName = 5116 tr.getBaseIntent().getComponent().getPackageName(); 5117 if (tr.userId != userId) continue; 5118 if (!taskPackageName.equals(packageName)) continue; 5119 removeTaskByIdLocked(tr.taskId, false); 5120 } 5121 } 5122 5123 try { 5124 // Clear application user data 5125 pm.clearApplicationUserData(packageName, observer, userId); 5126 5127 synchronized(this) { 5128 // Remove all permissions granted from/to this package 5129 removeUriPermissionsForPackageLocked(packageName, userId, true); 5130 } 5131 5132 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5133 Uri.fromParts("package", packageName, null)); 5134 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5135 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5136 null, null, 0, null, null, null, false, false, userId); 5137 } catch (RemoteException e) { 5138 } 5139 } finally { 5140 Binder.restoreCallingIdentity(callingId); 5141 } 5142 return true; 5143 } 5144 5145 @Override 5146 public void killBackgroundProcesses(final String packageName, int userId) { 5147 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5148 != PackageManager.PERMISSION_GRANTED && 5149 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5150 != PackageManager.PERMISSION_GRANTED) { 5151 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5152 + Binder.getCallingPid() 5153 + ", uid=" + Binder.getCallingUid() 5154 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5155 Slog.w(TAG, msg); 5156 throw new SecurityException(msg); 5157 } 5158 5159 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5160 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5161 long callingId = Binder.clearCallingIdentity(); 5162 try { 5163 IPackageManager pm = AppGlobals.getPackageManager(); 5164 synchronized(this) { 5165 int appId = -1; 5166 try { 5167 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5168 } catch (RemoteException e) { 5169 } 5170 if (appId == -1) { 5171 Slog.w(TAG, "Invalid packageName: " + packageName); 5172 return; 5173 } 5174 killPackageProcessesLocked(packageName, appId, userId, 5175 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5176 } 5177 } finally { 5178 Binder.restoreCallingIdentity(callingId); 5179 } 5180 } 5181 5182 @Override 5183 public void killAllBackgroundProcesses() { 5184 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5185 != PackageManager.PERMISSION_GRANTED) { 5186 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5187 + Binder.getCallingPid() 5188 + ", uid=" + Binder.getCallingUid() 5189 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5190 Slog.w(TAG, msg); 5191 throw new SecurityException(msg); 5192 } 5193 5194 long callingId = Binder.clearCallingIdentity(); 5195 try { 5196 synchronized(this) { 5197 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5198 final int NP = mProcessNames.getMap().size(); 5199 for (int ip=0; ip<NP; ip++) { 5200 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5201 final int NA = apps.size(); 5202 for (int ia=0; ia<NA; ia++) { 5203 ProcessRecord app = apps.valueAt(ia); 5204 if (app.persistent) { 5205 // we don't kill persistent processes 5206 continue; 5207 } 5208 if (app.removed) { 5209 procs.add(app); 5210 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5211 app.removed = true; 5212 procs.add(app); 5213 } 5214 } 5215 } 5216 5217 int N = procs.size(); 5218 for (int i=0; i<N; i++) { 5219 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5220 } 5221 mAllowLowerMemLevel = true; 5222 updateOomAdjLocked(); 5223 doLowMemReportIfNeededLocked(null); 5224 } 5225 } finally { 5226 Binder.restoreCallingIdentity(callingId); 5227 } 5228 } 5229 5230 @Override 5231 public void forceStopPackage(final String packageName, int userId) { 5232 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5233 != PackageManager.PERMISSION_GRANTED) { 5234 String msg = "Permission Denial: forceStopPackage() from pid=" 5235 + Binder.getCallingPid() 5236 + ", uid=" + Binder.getCallingUid() 5237 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5238 Slog.w(TAG, msg); 5239 throw new SecurityException(msg); 5240 } 5241 final int callingPid = Binder.getCallingPid(); 5242 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5243 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5244 long callingId = Binder.clearCallingIdentity(); 5245 try { 5246 IPackageManager pm = AppGlobals.getPackageManager(); 5247 synchronized(this) { 5248 int[] users = userId == UserHandle.USER_ALL 5249 ? getUsersLocked() : new int[] { userId }; 5250 for (int user : users) { 5251 int pkgUid = -1; 5252 try { 5253 pkgUid = pm.getPackageUid(packageName, user); 5254 } catch (RemoteException e) { 5255 } 5256 if (pkgUid == -1) { 5257 Slog.w(TAG, "Invalid packageName: " + packageName); 5258 continue; 5259 } 5260 try { 5261 pm.setPackageStoppedState(packageName, true, user); 5262 } catch (RemoteException e) { 5263 } catch (IllegalArgumentException e) { 5264 Slog.w(TAG, "Failed trying to unstop package " 5265 + packageName + ": " + e); 5266 } 5267 if (isUserRunningLocked(user, false)) { 5268 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5269 } 5270 } 5271 } 5272 } finally { 5273 Binder.restoreCallingIdentity(callingId); 5274 } 5275 } 5276 5277 @Override 5278 public void addPackageDependency(String packageName) { 5279 synchronized (this) { 5280 int callingPid = Binder.getCallingPid(); 5281 if (callingPid == Process.myPid()) { 5282 // Yeah, um, no. 5283 Slog.w(TAG, "Can't addPackageDependency on system process"); 5284 return; 5285 } 5286 ProcessRecord proc; 5287 synchronized (mPidsSelfLocked) { 5288 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5289 } 5290 if (proc != null) { 5291 if (proc.pkgDeps == null) { 5292 proc.pkgDeps = new ArraySet<String>(1); 5293 } 5294 proc.pkgDeps.add(packageName); 5295 } 5296 } 5297 } 5298 5299 /* 5300 * The pkg name and app id have to be specified. 5301 */ 5302 @Override 5303 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5304 if (pkg == null) { 5305 return; 5306 } 5307 // Make sure the uid is valid. 5308 if (appid < 0) { 5309 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5310 return; 5311 } 5312 int callerUid = Binder.getCallingUid(); 5313 // Only the system server can kill an application 5314 if (callerUid == Process.SYSTEM_UID) { 5315 // Post an aysnc message to kill the application 5316 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5317 msg.arg1 = appid; 5318 msg.arg2 = 0; 5319 Bundle bundle = new Bundle(); 5320 bundle.putString("pkg", pkg); 5321 bundle.putString("reason", reason); 5322 msg.obj = bundle; 5323 mHandler.sendMessage(msg); 5324 } else { 5325 throw new SecurityException(callerUid + " cannot kill pkg: " + 5326 pkg); 5327 } 5328 } 5329 5330 @Override 5331 public void closeSystemDialogs(String reason) { 5332 enforceNotIsolatedCaller("closeSystemDialogs"); 5333 5334 final int pid = Binder.getCallingPid(); 5335 final int uid = Binder.getCallingUid(); 5336 final long origId = Binder.clearCallingIdentity(); 5337 try { 5338 synchronized (this) { 5339 // Only allow this from foreground processes, so that background 5340 // applications can't abuse it to prevent system UI from being shown. 5341 if (uid >= Process.FIRST_APPLICATION_UID) { 5342 ProcessRecord proc; 5343 synchronized (mPidsSelfLocked) { 5344 proc = mPidsSelfLocked.get(pid); 5345 } 5346 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5347 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5348 + " from background process " + proc); 5349 return; 5350 } 5351 } 5352 closeSystemDialogsLocked(reason); 5353 } 5354 } finally { 5355 Binder.restoreCallingIdentity(origId); 5356 } 5357 } 5358 5359 void closeSystemDialogsLocked(String reason) { 5360 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5361 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5362 | Intent.FLAG_RECEIVER_FOREGROUND); 5363 if (reason != null) { 5364 intent.putExtra("reason", reason); 5365 } 5366 mWindowManager.closeSystemDialogs(reason); 5367 5368 mStackSupervisor.closeSystemDialogsLocked(); 5369 5370 broadcastIntentLocked(null, null, intent, null, 5371 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5372 Process.SYSTEM_UID, UserHandle.USER_ALL); 5373 } 5374 5375 @Override 5376 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5377 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5378 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5379 for (int i=pids.length-1; i>=0; i--) { 5380 ProcessRecord proc; 5381 int oomAdj; 5382 synchronized (this) { 5383 synchronized (mPidsSelfLocked) { 5384 proc = mPidsSelfLocked.get(pids[i]); 5385 oomAdj = proc != null ? proc.setAdj : 0; 5386 } 5387 } 5388 infos[i] = new Debug.MemoryInfo(); 5389 Debug.getMemoryInfo(pids[i], infos[i]); 5390 if (proc != null) { 5391 synchronized (this) { 5392 if (proc.thread != null && proc.setAdj == oomAdj) { 5393 // Record this for posterity if the process has been stable. 5394 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5395 infos[i].getTotalUss(), false, proc.pkgList); 5396 } 5397 } 5398 } 5399 } 5400 return infos; 5401 } 5402 5403 @Override 5404 public long[] getProcessPss(int[] pids) { 5405 enforceNotIsolatedCaller("getProcessPss"); 5406 long[] pss = new long[pids.length]; 5407 for (int i=pids.length-1; i>=0; i--) { 5408 ProcessRecord proc; 5409 int oomAdj; 5410 synchronized (this) { 5411 synchronized (mPidsSelfLocked) { 5412 proc = mPidsSelfLocked.get(pids[i]); 5413 oomAdj = proc != null ? proc.setAdj : 0; 5414 } 5415 } 5416 long[] tmpUss = new long[1]; 5417 pss[i] = Debug.getPss(pids[i], tmpUss); 5418 if (proc != null) { 5419 synchronized (this) { 5420 if (proc.thread != null && proc.setAdj == oomAdj) { 5421 // Record this for posterity if the process has been stable. 5422 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5423 } 5424 } 5425 } 5426 } 5427 return pss; 5428 } 5429 5430 @Override 5431 public void killApplicationProcess(String processName, int uid) { 5432 if (processName == null) { 5433 return; 5434 } 5435 5436 int callerUid = Binder.getCallingUid(); 5437 // Only the system server can kill an application 5438 if (callerUid == Process.SYSTEM_UID) { 5439 synchronized (this) { 5440 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5441 if (app != null && app.thread != null) { 5442 try { 5443 app.thread.scheduleSuicide(); 5444 } catch (RemoteException e) { 5445 // If the other end already died, then our work here is done. 5446 } 5447 } else { 5448 Slog.w(TAG, "Process/uid not found attempting kill of " 5449 + processName + " / " + uid); 5450 } 5451 } 5452 } else { 5453 throw new SecurityException(callerUid + " cannot kill app process: " + 5454 processName); 5455 } 5456 } 5457 5458 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5459 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5460 false, true, false, false, UserHandle.getUserId(uid), reason); 5461 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5462 Uri.fromParts("package", packageName, null)); 5463 if (!mProcessesReady) { 5464 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5465 | Intent.FLAG_RECEIVER_FOREGROUND); 5466 } 5467 intent.putExtra(Intent.EXTRA_UID, uid); 5468 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5469 broadcastIntentLocked(null, null, intent, 5470 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5471 false, false, 5472 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5473 } 5474 5475 private void forceStopUserLocked(int userId, String reason) { 5476 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5477 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5478 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5479 | Intent.FLAG_RECEIVER_FOREGROUND); 5480 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5481 broadcastIntentLocked(null, null, intent, 5482 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5483 false, false, 5484 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5485 } 5486 5487 private final boolean killPackageProcessesLocked(String packageName, int appId, 5488 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5489 boolean doit, boolean evenPersistent, String reason) { 5490 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5491 5492 // Remove all processes this package may have touched: all with the 5493 // same UID (except for the system or root user), and all whose name 5494 // matches the package name. 5495 final int NP = mProcessNames.getMap().size(); 5496 for (int ip=0; ip<NP; ip++) { 5497 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5498 final int NA = apps.size(); 5499 for (int ia=0; ia<NA; ia++) { 5500 ProcessRecord app = apps.valueAt(ia); 5501 if (app.persistent && !evenPersistent) { 5502 // we don't kill persistent processes 5503 continue; 5504 } 5505 if (app.removed) { 5506 if (doit) { 5507 procs.add(app); 5508 } 5509 continue; 5510 } 5511 5512 // Skip process if it doesn't meet our oom adj requirement. 5513 if (app.setAdj < minOomAdj) { 5514 continue; 5515 } 5516 5517 // If no package is specified, we call all processes under the 5518 // give user id. 5519 if (packageName == null) { 5520 if (app.userId != userId) { 5521 continue; 5522 } 5523 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5524 continue; 5525 } 5526 // Package has been specified, we want to hit all processes 5527 // that match it. We need to qualify this by the processes 5528 // that are running under the specified app and user ID. 5529 } else { 5530 final boolean isDep = app.pkgDeps != null 5531 && app.pkgDeps.contains(packageName); 5532 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5533 continue; 5534 } 5535 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5536 continue; 5537 } 5538 if (!app.pkgList.containsKey(packageName) && !isDep) { 5539 continue; 5540 } 5541 } 5542 5543 // Process has passed all conditions, kill it! 5544 if (!doit) { 5545 return true; 5546 } 5547 app.removed = true; 5548 procs.add(app); 5549 } 5550 } 5551 5552 int N = procs.size(); 5553 for (int i=0; i<N; i++) { 5554 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5555 } 5556 updateOomAdjLocked(); 5557 return N > 0; 5558 } 5559 5560 private final boolean forceStopPackageLocked(String name, int appId, 5561 boolean callerWillRestart, boolean purgeCache, boolean doit, 5562 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5563 int i; 5564 int N; 5565 5566 if (userId == UserHandle.USER_ALL && name == null) { 5567 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5568 } 5569 5570 if (appId < 0 && name != null) { 5571 try { 5572 appId = UserHandle.getAppId( 5573 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5574 } catch (RemoteException e) { 5575 } 5576 } 5577 5578 if (doit) { 5579 if (name != null) { 5580 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5581 + " user=" + userId + ": " + reason); 5582 } else { 5583 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5584 } 5585 5586 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5587 for (int ip=pmap.size()-1; ip>=0; ip--) { 5588 SparseArray<Long> ba = pmap.valueAt(ip); 5589 for (i=ba.size()-1; i>=0; i--) { 5590 boolean remove = false; 5591 final int entUid = ba.keyAt(i); 5592 if (name != null) { 5593 if (userId == UserHandle.USER_ALL) { 5594 if (UserHandle.getAppId(entUid) == appId) { 5595 remove = true; 5596 } 5597 } else { 5598 if (entUid == UserHandle.getUid(userId, appId)) { 5599 remove = true; 5600 } 5601 } 5602 } else if (UserHandle.getUserId(entUid) == userId) { 5603 remove = true; 5604 } 5605 if (remove) { 5606 ba.removeAt(i); 5607 } 5608 } 5609 if (ba.size() == 0) { 5610 pmap.removeAt(ip); 5611 } 5612 } 5613 } 5614 5615 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5616 -100, callerWillRestart, true, doit, evenPersistent, 5617 name == null ? ("stop user " + userId) : ("stop " + name)); 5618 5619 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5620 if (!doit) { 5621 return true; 5622 } 5623 didSomething = true; 5624 } 5625 5626 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5627 if (!doit) { 5628 return true; 5629 } 5630 didSomething = true; 5631 } 5632 5633 if (name == null) { 5634 // Remove all sticky broadcasts from this user. 5635 mStickyBroadcasts.remove(userId); 5636 } 5637 5638 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5639 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5640 userId, providers)) { 5641 if (!doit) { 5642 return true; 5643 } 5644 didSomething = true; 5645 } 5646 N = providers.size(); 5647 for (i=0; i<N; i++) { 5648 removeDyingProviderLocked(null, providers.get(i), true); 5649 } 5650 5651 // Remove transient permissions granted from/to this package/user 5652 removeUriPermissionsForPackageLocked(name, userId, false); 5653 5654 if (name == null || uninstalling) { 5655 // Remove pending intents. For now we only do this when force 5656 // stopping users, because we have some problems when doing this 5657 // for packages -- app widgets are not currently cleaned up for 5658 // such packages, so they can be left with bad pending intents. 5659 if (mIntentSenderRecords.size() > 0) { 5660 Iterator<WeakReference<PendingIntentRecord>> it 5661 = mIntentSenderRecords.values().iterator(); 5662 while (it.hasNext()) { 5663 WeakReference<PendingIntentRecord> wpir = it.next(); 5664 if (wpir == null) { 5665 it.remove(); 5666 continue; 5667 } 5668 PendingIntentRecord pir = wpir.get(); 5669 if (pir == null) { 5670 it.remove(); 5671 continue; 5672 } 5673 if (name == null) { 5674 // Stopping user, remove all objects for the user. 5675 if (pir.key.userId != userId) { 5676 // Not the same user, skip it. 5677 continue; 5678 } 5679 } else { 5680 if (UserHandle.getAppId(pir.uid) != appId) { 5681 // Different app id, skip it. 5682 continue; 5683 } 5684 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5685 // Different user, skip it. 5686 continue; 5687 } 5688 if (!pir.key.packageName.equals(name)) { 5689 // Different package, skip it. 5690 continue; 5691 } 5692 } 5693 if (!doit) { 5694 return true; 5695 } 5696 didSomething = true; 5697 it.remove(); 5698 pir.canceled = true; 5699 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5700 pir.key.activity.pendingResults.remove(pir.ref); 5701 } 5702 } 5703 } 5704 } 5705 5706 if (doit) { 5707 if (purgeCache && name != null) { 5708 AttributeCache ac = AttributeCache.instance(); 5709 if (ac != null) { 5710 ac.removePackage(name); 5711 } 5712 } 5713 if (mBooted) { 5714 mStackSupervisor.resumeTopActivitiesLocked(); 5715 mStackSupervisor.scheduleIdleLocked(); 5716 } 5717 } 5718 5719 return didSomething; 5720 } 5721 5722 private final boolean removeProcessLocked(ProcessRecord app, 5723 boolean callerWillRestart, boolean allowRestart, String reason) { 5724 final String name = app.processName; 5725 final int uid = app.uid; 5726 if (DEBUG_PROCESSES) Slog.d( 5727 TAG, "Force removing proc " + app.toShortString() + " (" + name 5728 + "/" + uid + ")"); 5729 5730 mProcessNames.remove(name, uid); 5731 mIsolatedProcesses.remove(app.uid); 5732 if (mHeavyWeightProcess == app) { 5733 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5734 mHeavyWeightProcess.userId, 0)); 5735 mHeavyWeightProcess = null; 5736 } 5737 boolean needRestart = false; 5738 if (app.pid > 0 && app.pid != MY_PID) { 5739 int pid = app.pid; 5740 synchronized (mPidsSelfLocked) { 5741 mPidsSelfLocked.remove(pid); 5742 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5743 } 5744 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5745 if (app.isolated) { 5746 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5747 } 5748 app.kill(reason, true); 5749 handleAppDiedLocked(app, true, allowRestart); 5750 removeLruProcessLocked(app); 5751 5752 if (app.persistent && !app.isolated) { 5753 if (!callerWillRestart) { 5754 addAppLocked(app.info, false, null /* ABI override */); 5755 } else { 5756 needRestart = true; 5757 } 5758 } 5759 } else { 5760 mRemovedProcesses.add(app); 5761 } 5762 5763 return needRestart; 5764 } 5765 5766 private final void processStartTimedOutLocked(ProcessRecord app) { 5767 final int pid = app.pid; 5768 boolean gone = false; 5769 synchronized (mPidsSelfLocked) { 5770 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5771 if (knownApp != null && knownApp.thread == null) { 5772 mPidsSelfLocked.remove(pid); 5773 gone = true; 5774 } 5775 } 5776 5777 if (gone) { 5778 Slog.w(TAG, "Process " + app + " failed to attach"); 5779 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5780 pid, app.uid, app.processName); 5781 mProcessNames.remove(app.processName, app.uid); 5782 mIsolatedProcesses.remove(app.uid); 5783 if (mHeavyWeightProcess == app) { 5784 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5785 mHeavyWeightProcess.userId, 0)); 5786 mHeavyWeightProcess = null; 5787 } 5788 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5789 if (app.isolated) { 5790 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5791 } 5792 // Take care of any launching providers waiting for this process. 5793 checkAppInLaunchingProvidersLocked(app, true); 5794 // Take care of any services that are waiting for the process. 5795 mServices.processStartTimedOutLocked(app); 5796 app.kill("start timeout", true); 5797 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5798 Slog.w(TAG, "Unattached app died before backup, skipping"); 5799 try { 5800 IBackupManager bm = IBackupManager.Stub.asInterface( 5801 ServiceManager.getService(Context.BACKUP_SERVICE)); 5802 bm.agentDisconnected(app.info.packageName); 5803 } catch (RemoteException e) { 5804 // Can't happen; the backup manager is local 5805 } 5806 } 5807 if (isPendingBroadcastProcessLocked(pid)) { 5808 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5809 skipPendingBroadcastLocked(pid); 5810 } 5811 } else { 5812 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5813 } 5814 } 5815 5816 private final boolean attachApplicationLocked(IApplicationThread thread, 5817 int pid) { 5818 5819 // Find the application record that is being attached... either via 5820 // the pid if we are running in multiple processes, or just pull the 5821 // next app record if we are emulating process with anonymous threads. 5822 ProcessRecord app; 5823 if (pid != MY_PID && pid >= 0) { 5824 synchronized (mPidsSelfLocked) { 5825 app = mPidsSelfLocked.get(pid); 5826 } 5827 } else { 5828 app = null; 5829 } 5830 5831 if (app == null) { 5832 Slog.w(TAG, "No pending application record for pid " + pid 5833 + " (IApplicationThread " + thread + "); dropping process"); 5834 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5835 if (pid > 0 && pid != MY_PID) { 5836 Process.killProcessQuiet(pid); 5837 //TODO: Process.killProcessGroup(app.info.uid, pid); 5838 } else { 5839 try { 5840 thread.scheduleExit(); 5841 } catch (Exception e) { 5842 // Ignore exceptions. 5843 } 5844 } 5845 return false; 5846 } 5847 5848 // If this application record is still attached to a previous 5849 // process, clean it up now. 5850 if (app.thread != null) { 5851 handleAppDiedLocked(app, true, true); 5852 } 5853 5854 // Tell the process all about itself. 5855 5856 if (localLOGV) Slog.v( 5857 TAG, "Binding process pid " + pid + " to record " + app); 5858 5859 final String processName = app.processName; 5860 try { 5861 AppDeathRecipient adr = new AppDeathRecipient( 5862 app, pid, thread); 5863 thread.asBinder().linkToDeath(adr, 0); 5864 app.deathRecipient = adr; 5865 } catch (RemoteException e) { 5866 app.resetPackageList(mProcessStats); 5867 startProcessLocked(app, "link fail", processName); 5868 return false; 5869 } 5870 5871 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5872 5873 app.makeActive(thread, mProcessStats); 5874 app.curAdj = app.setAdj = -100; 5875 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5876 app.forcingToForeground = null; 5877 updateProcessForegroundLocked(app, false, false); 5878 app.hasShownUi = false; 5879 app.debugging = false; 5880 app.cached = false; 5881 5882 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5883 5884 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5885 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5886 5887 if (!normalMode) { 5888 Slog.i(TAG, "Launching preboot mode app: " + app); 5889 } 5890 5891 if (localLOGV) Slog.v( 5892 TAG, "New app record " + app 5893 + " thread=" + thread.asBinder() + " pid=" + pid); 5894 try { 5895 int testMode = IApplicationThread.DEBUG_OFF; 5896 if (mDebugApp != null && mDebugApp.equals(processName)) { 5897 testMode = mWaitForDebugger 5898 ? IApplicationThread.DEBUG_WAIT 5899 : IApplicationThread.DEBUG_ON; 5900 app.debugging = true; 5901 if (mDebugTransient) { 5902 mDebugApp = mOrigDebugApp; 5903 mWaitForDebugger = mOrigWaitForDebugger; 5904 } 5905 } 5906 String profileFile = app.instrumentationProfileFile; 5907 ParcelFileDescriptor profileFd = null; 5908 int samplingInterval = 0; 5909 boolean profileAutoStop = false; 5910 if (mProfileApp != null && mProfileApp.equals(processName)) { 5911 mProfileProc = app; 5912 profileFile = mProfileFile; 5913 profileFd = mProfileFd; 5914 samplingInterval = mSamplingInterval; 5915 profileAutoStop = mAutoStopProfiler; 5916 } 5917 boolean enableOpenGlTrace = false; 5918 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5919 enableOpenGlTrace = true; 5920 mOpenGlTraceApp = null; 5921 } 5922 5923 // If the app is being launched for restore or full backup, set it up specially 5924 boolean isRestrictedBackupMode = false; 5925 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5926 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5927 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5928 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5929 } 5930 5931 ensurePackageDexOpt(app.instrumentationInfo != null 5932 ? app.instrumentationInfo.packageName 5933 : app.info.packageName); 5934 if (app.instrumentationClass != null) { 5935 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5936 } 5937 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5938 + processName + " with config " + mConfiguration); 5939 ApplicationInfo appInfo = app.instrumentationInfo != null 5940 ? app.instrumentationInfo : app.info; 5941 app.compat = compatibilityInfoForPackageLocked(appInfo); 5942 if (profileFd != null) { 5943 profileFd = profileFd.dup(); 5944 } 5945 ProfilerInfo profilerInfo = profileFile == null ? null 5946 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5947 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5948 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5949 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5950 isRestrictedBackupMode || !normalMode, app.persistent, 5951 new Configuration(mConfiguration), app.compat, 5952 getCommonServicesLocked(app.isolated), 5953 mCoreSettingsObserver.getCoreSettingsLocked()); 5954 updateLruProcessLocked(app, false, null); 5955 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5956 } catch (Exception e) { 5957 // todo: Yikes! What should we do? For now we will try to 5958 // start another process, but that could easily get us in 5959 // an infinite loop of restarting processes... 5960 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5961 5962 app.resetPackageList(mProcessStats); 5963 app.unlinkDeathRecipient(); 5964 startProcessLocked(app, "bind fail", processName); 5965 return false; 5966 } 5967 5968 // Remove this record from the list of starting applications. 5969 mPersistentStartingProcesses.remove(app); 5970 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5971 "Attach application locked removing on hold: " + app); 5972 mProcessesOnHold.remove(app); 5973 5974 boolean badApp = false; 5975 boolean didSomething = false; 5976 5977 // See if the top visible activity is waiting to run in this process... 5978 if (normalMode) { 5979 try { 5980 if (mStackSupervisor.attachApplicationLocked(app)) { 5981 didSomething = true; 5982 } 5983 } catch (Exception e) { 5984 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5985 badApp = true; 5986 } 5987 } 5988 5989 // Find any services that should be running in this process... 5990 if (!badApp) { 5991 try { 5992 didSomething |= mServices.attachApplicationLocked(app, processName); 5993 } catch (Exception e) { 5994 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5995 badApp = true; 5996 } 5997 } 5998 5999 // Check if a next-broadcast receiver is in this process... 6000 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6001 try { 6002 didSomething |= sendPendingBroadcastsLocked(app); 6003 } catch (Exception e) { 6004 // If the app died trying to launch the receiver we declare it 'bad' 6005 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6006 badApp = true; 6007 } 6008 } 6009 6010 // Check whether the next backup agent is in this process... 6011 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6012 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6013 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6014 try { 6015 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6016 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6017 mBackupTarget.backupMode); 6018 } catch (Exception e) { 6019 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6020 badApp = true; 6021 } 6022 } 6023 6024 if (badApp) { 6025 app.kill("error during init", true); 6026 handleAppDiedLocked(app, false, true); 6027 return false; 6028 } 6029 6030 if (!didSomething) { 6031 updateOomAdjLocked(); 6032 } 6033 6034 return true; 6035 } 6036 6037 @Override 6038 public final void attachApplication(IApplicationThread thread) { 6039 synchronized (this) { 6040 int callingPid = Binder.getCallingPid(); 6041 final long origId = Binder.clearCallingIdentity(); 6042 attachApplicationLocked(thread, callingPid); 6043 Binder.restoreCallingIdentity(origId); 6044 } 6045 } 6046 6047 @Override 6048 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6049 final long origId = Binder.clearCallingIdentity(); 6050 synchronized (this) { 6051 ActivityStack stack = ActivityRecord.getStackLocked(token); 6052 if (stack != null) { 6053 ActivityRecord r = 6054 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6055 if (stopProfiling) { 6056 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6057 try { 6058 mProfileFd.close(); 6059 } catch (IOException e) { 6060 } 6061 clearProfilerLocked(); 6062 } 6063 } 6064 } 6065 } 6066 Binder.restoreCallingIdentity(origId); 6067 } 6068 6069 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6070 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6071 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6072 } 6073 6074 void enableScreenAfterBoot() { 6075 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6076 SystemClock.uptimeMillis()); 6077 mWindowManager.enableScreenAfterBoot(); 6078 6079 synchronized (this) { 6080 updateEventDispatchingLocked(); 6081 } 6082 } 6083 6084 @Override 6085 public void showBootMessage(final CharSequence msg, final boolean always) { 6086 enforceNotIsolatedCaller("showBootMessage"); 6087 mWindowManager.showBootMessage(msg, always); 6088 } 6089 6090 @Override 6091 public void keyguardWaitingForActivityDrawn() { 6092 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6093 final long token = Binder.clearCallingIdentity(); 6094 try { 6095 synchronized (this) { 6096 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6097 mWindowManager.keyguardWaitingForActivityDrawn(); 6098 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6099 mLockScreenShown = LOCK_SCREEN_LEAVING; 6100 updateSleepIfNeededLocked(); 6101 } 6102 } 6103 } finally { 6104 Binder.restoreCallingIdentity(token); 6105 } 6106 } 6107 6108 final void finishBooting() { 6109 synchronized (this) { 6110 if (!mBootAnimationComplete) { 6111 mCallFinishBooting = true; 6112 return; 6113 } 6114 mCallFinishBooting = false; 6115 } 6116 6117 ArraySet<String> completedIsas = new ArraySet<String>(); 6118 for (String abi : Build.SUPPORTED_ABIS) { 6119 Process.establishZygoteConnectionForAbi(abi); 6120 final String instructionSet = VMRuntime.getInstructionSet(abi); 6121 if (!completedIsas.contains(instructionSet)) { 6122 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6123 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6124 } 6125 completedIsas.add(instructionSet); 6126 } 6127 } 6128 6129 IntentFilter pkgFilter = new IntentFilter(); 6130 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6131 pkgFilter.addDataScheme("package"); 6132 mContext.registerReceiver(new BroadcastReceiver() { 6133 @Override 6134 public void onReceive(Context context, Intent intent) { 6135 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6136 if (pkgs != null) { 6137 for (String pkg : pkgs) { 6138 synchronized (ActivityManagerService.this) { 6139 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6140 0, "finished booting")) { 6141 setResultCode(Activity.RESULT_OK); 6142 return; 6143 } 6144 } 6145 } 6146 } 6147 } 6148 }, pkgFilter); 6149 6150 // Let system services know. 6151 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6152 6153 synchronized (this) { 6154 // Ensure that any processes we had put on hold are now started 6155 // up. 6156 final int NP = mProcessesOnHold.size(); 6157 if (NP > 0) { 6158 ArrayList<ProcessRecord> procs = 6159 new ArrayList<ProcessRecord>(mProcessesOnHold); 6160 for (int ip=0; ip<NP; ip++) { 6161 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6162 + procs.get(ip)); 6163 startProcessLocked(procs.get(ip), "on-hold", null); 6164 } 6165 } 6166 6167 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6168 // Start looking for apps that are abusing wake locks. 6169 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6170 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6171 // Tell anyone interested that we are done booting! 6172 SystemProperties.set("sys.boot_completed", "1"); 6173 6174 // And trigger dev.bootcomplete if we are not showing encryption progress 6175 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6176 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6177 SystemProperties.set("dev.bootcomplete", "1"); 6178 } 6179 for (int i=0; i<mStartedUsers.size(); i++) { 6180 UserStartedState uss = mStartedUsers.valueAt(i); 6181 if (uss.mState == UserStartedState.STATE_BOOTING) { 6182 uss.mState = UserStartedState.STATE_RUNNING; 6183 final int userId = mStartedUsers.keyAt(i); 6184 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6185 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6186 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6187 broadcastIntentLocked(null, null, intent, null, 6188 new IIntentReceiver.Stub() { 6189 @Override 6190 public void performReceive(Intent intent, int resultCode, 6191 String data, Bundle extras, boolean ordered, 6192 boolean sticky, int sendingUser) { 6193 synchronized (ActivityManagerService.this) { 6194 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6195 true, false); 6196 } 6197 } 6198 }, 6199 0, null, null, 6200 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6201 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6202 userId); 6203 } 6204 } 6205 scheduleStartProfilesLocked(); 6206 } 6207 } 6208 } 6209 6210 @Override 6211 public void bootAnimationComplete() { 6212 final boolean callFinishBooting; 6213 synchronized (this) { 6214 callFinishBooting = mCallFinishBooting; 6215 mBootAnimationComplete = true; 6216 } 6217 if (callFinishBooting) { 6218 finishBooting(); 6219 } 6220 } 6221 6222 final void ensureBootCompleted() { 6223 boolean booting; 6224 boolean enableScreen; 6225 synchronized (this) { 6226 booting = mBooting; 6227 mBooting = false; 6228 enableScreen = !mBooted; 6229 mBooted = true; 6230 } 6231 6232 if (booting) { 6233 finishBooting(); 6234 } 6235 6236 if (enableScreen) { 6237 enableScreenAfterBoot(); 6238 } 6239 } 6240 6241 @Override 6242 public final void activityResumed(IBinder token) { 6243 final long origId = Binder.clearCallingIdentity(); 6244 synchronized(this) { 6245 ActivityStack stack = ActivityRecord.getStackLocked(token); 6246 if (stack != null) { 6247 ActivityRecord.activityResumedLocked(token); 6248 } 6249 } 6250 Binder.restoreCallingIdentity(origId); 6251 } 6252 6253 @Override 6254 public final void activityPaused(IBinder token) { 6255 final long origId = Binder.clearCallingIdentity(); 6256 synchronized(this) { 6257 ActivityStack stack = ActivityRecord.getStackLocked(token); 6258 if (stack != null) { 6259 stack.activityPausedLocked(token, false); 6260 } 6261 } 6262 Binder.restoreCallingIdentity(origId); 6263 } 6264 6265 @Override 6266 public final void activityStopped(IBinder token, Bundle icicle, 6267 PersistableBundle persistentState, CharSequence description) { 6268 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6269 6270 // Refuse possible leaked file descriptors 6271 if (icicle != null && icicle.hasFileDescriptors()) { 6272 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6273 } 6274 6275 final long origId = Binder.clearCallingIdentity(); 6276 6277 synchronized (this) { 6278 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6279 if (r != null) { 6280 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6281 } 6282 } 6283 6284 trimApplications(); 6285 6286 Binder.restoreCallingIdentity(origId); 6287 } 6288 6289 @Override 6290 public final void activityDestroyed(IBinder token) { 6291 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6292 synchronized (this) { 6293 ActivityStack stack = ActivityRecord.getStackLocked(token); 6294 if (stack != null) { 6295 stack.activityDestroyedLocked(token); 6296 } 6297 } 6298 } 6299 6300 @Override 6301 public final void backgroundResourcesReleased(IBinder token) { 6302 final long origId = Binder.clearCallingIdentity(); 6303 try { 6304 synchronized (this) { 6305 ActivityStack stack = ActivityRecord.getStackLocked(token); 6306 if (stack != null) { 6307 stack.backgroundResourcesReleased(); 6308 } 6309 } 6310 } finally { 6311 Binder.restoreCallingIdentity(origId); 6312 } 6313 } 6314 6315 @Override 6316 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6317 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6318 } 6319 6320 @Override 6321 public final void notifyEnterAnimationComplete(IBinder token) { 6322 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6323 } 6324 6325 @Override 6326 public String getCallingPackage(IBinder token) { 6327 synchronized (this) { 6328 ActivityRecord r = getCallingRecordLocked(token); 6329 return r != null ? r.info.packageName : null; 6330 } 6331 } 6332 6333 @Override 6334 public ComponentName getCallingActivity(IBinder token) { 6335 synchronized (this) { 6336 ActivityRecord r = getCallingRecordLocked(token); 6337 return r != null ? r.intent.getComponent() : null; 6338 } 6339 } 6340 6341 private ActivityRecord getCallingRecordLocked(IBinder token) { 6342 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6343 if (r == null) { 6344 return null; 6345 } 6346 return r.resultTo; 6347 } 6348 6349 @Override 6350 public ComponentName getActivityClassForToken(IBinder token) { 6351 synchronized(this) { 6352 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6353 if (r == null) { 6354 return null; 6355 } 6356 return r.intent.getComponent(); 6357 } 6358 } 6359 6360 @Override 6361 public String getPackageForToken(IBinder token) { 6362 synchronized(this) { 6363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6364 if (r == null) { 6365 return null; 6366 } 6367 return r.packageName; 6368 } 6369 } 6370 6371 @Override 6372 public IIntentSender getIntentSender(int type, 6373 String packageName, IBinder token, String resultWho, 6374 int requestCode, Intent[] intents, String[] resolvedTypes, 6375 int flags, Bundle options, int userId) { 6376 enforceNotIsolatedCaller("getIntentSender"); 6377 // Refuse possible leaked file descriptors 6378 if (intents != null) { 6379 if (intents.length < 1) { 6380 throw new IllegalArgumentException("Intents array length must be >= 1"); 6381 } 6382 for (int i=0; i<intents.length; i++) { 6383 Intent intent = intents[i]; 6384 if (intent != null) { 6385 if (intent.hasFileDescriptors()) { 6386 throw new IllegalArgumentException("File descriptors passed in Intent"); 6387 } 6388 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6389 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6390 throw new IllegalArgumentException( 6391 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6392 } 6393 intents[i] = new Intent(intent); 6394 } 6395 } 6396 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6397 throw new IllegalArgumentException( 6398 "Intent array length does not match resolvedTypes length"); 6399 } 6400 } 6401 if (options != null) { 6402 if (options.hasFileDescriptors()) { 6403 throw new IllegalArgumentException("File descriptors passed in options"); 6404 } 6405 } 6406 6407 synchronized(this) { 6408 int callingUid = Binder.getCallingUid(); 6409 int origUserId = userId; 6410 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6411 type == ActivityManager.INTENT_SENDER_BROADCAST, 6412 ALLOW_NON_FULL, "getIntentSender", null); 6413 if (origUserId == UserHandle.USER_CURRENT) { 6414 // We don't want to evaluate this until the pending intent is 6415 // actually executed. However, we do want to always do the 6416 // security checking for it above. 6417 userId = UserHandle.USER_CURRENT; 6418 } 6419 try { 6420 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6421 int uid = AppGlobals.getPackageManager() 6422 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6423 if (!UserHandle.isSameApp(callingUid, uid)) { 6424 String msg = "Permission Denial: getIntentSender() from pid=" 6425 + Binder.getCallingPid() 6426 + ", uid=" + Binder.getCallingUid() 6427 + ", (need uid=" + uid + ")" 6428 + " is not allowed to send as package " + packageName; 6429 Slog.w(TAG, msg); 6430 throw new SecurityException(msg); 6431 } 6432 } 6433 6434 return getIntentSenderLocked(type, packageName, callingUid, userId, 6435 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6436 6437 } catch (RemoteException e) { 6438 throw new SecurityException(e); 6439 } 6440 } 6441 } 6442 6443 IIntentSender getIntentSenderLocked(int type, String packageName, 6444 int callingUid, int userId, IBinder token, String resultWho, 6445 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6446 Bundle options) { 6447 if (DEBUG_MU) 6448 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6449 ActivityRecord activity = null; 6450 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6451 activity = ActivityRecord.isInStackLocked(token); 6452 if (activity == null) { 6453 return null; 6454 } 6455 if (activity.finishing) { 6456 return null; 6457 } 6458 } 6459 6460 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6461 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6462 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6463 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6464 |PendingIntent.FLAG_UPDATE_CURRENT); 6465 6466 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6467 type, packageName, activity, resultWho, 6468 requestCode, intents, resolvedTypes, flags, options, userId); 6469 WeakReference<PendingIntentRecord> ref; 6470 ref = mIntentSenderRecords.get(key); 6471 PendingIntentRecord rec = ref != null ? ref.get() : null; 6472 if (rec != null) { 6473 if (!cancelCurrent) { 6474 if (updateCurrent) { 6475 if (rec.key.requestIntent != null) { 6476 rec.key.requestIntent.replaceExtras(intents != null ? 6477 intents[intents.length - 1] : null); 6478 } 6479 if (intents != null) { 6480 intents[intents.length-1] = rec.key.requestIntent; 6481 rec.key.allIntents = intents; 6482 rec.key.allResolvedTypes = resolvedTypes; 6483 } else { 6484 rec.key.allIntents = null; 6485 rec.key.allResolvedTypes = null; 6486 } 6487 } 6488 return rec; 6489 } 6490 rec.canceled = true; 6491 mIntentSenderRecords.remove(key); 6492 } 6493 if (noCreate) { 6494 return rec; 6495 } 6496 rec = new PendingIntentRecord(this, key, callingUid); 6497 mIntentSenderRecords.put(key, rec.ref); 6498 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6499 if (activity.pendingResults == null) { 6500 activity.pendingResults 6501 = new HashSet<WeakReference<PendingIntentRecord>>(); 6502 } 6503 activity.pendingResults.add(rec.ref); 6504 } 6505 return rec; 6506 } 6507 6508 @Override 6509 public void cancelIntentSender(IIntentSender sender) { 6510 if (!(sender instanceof PendingIntentRecord)) { 6511 return; 6512 } 6513 synchronized(this) { 6514 PendingIntentRecord rec = (PendingIntentRecord)sender; 6515 try { 6516 int uid = AppGlobals.getPackageManager() 6517 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6518 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6519 String msg = "Permission Denial: cancelIntentSender() from pid=" 6520 + Binder.getCallingPid() 6521 + ", uid=" + Binder.getCallingUid() 6522 + " is not allowed to cancel packges " 6523 + rec.key.packageName; 6524 Slog.w(TAG, msg); 6525 throw new SecurityException(msg); 6526 } 6527 } catch (RemoteException e) { 6528 throw new SecurityException(e); 6529 } 6530 cancelIntentSenderLocked(rec, true); 6531 } 6532 } 6533 6534 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6535 rec.canceled = true; 6536 mIntentSenderRecords.remove(rec.key); 6537 if (cleanActivity && rec.key.activity != null) { 6538 rec.key.activity.pendingResults.remove(rec.ref); 6539 } 6540 } 6541 6542 @Override 6543 public String getPackageForIntentSender(IIntentSender pendingResult) { 6544 if (!(pendingResult instanceof PendingIntentRecord)) { 6545 return null; 6546 } 6547 try { 6548 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6549 return res.key.packageName; 6550 } catch (ClassCastException e) { 6551 } 6552 return null; 6553 } 6554 6555 @Override 6556 public int getUidForIntentSender(IIntentSender sender) { 6557 if (sender instanceof PendingIntentRecord) { 6558 try { 6559 PendingIntentRecord res = (PendingIntentRecord)sender; 6560 return res.uid; 6561 } catch (ClassCastException e) { 6562 } 6563 } 6564 return -1; 6565 } 6566 6567 @Override 6568 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6569 if (!(pendingResult instanceof PendingIntentRecord)) { 6570 return false; 6571 } 6572 try { 6573 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6574 if (res.key.allIntents == null) { 6575 return false; 6576 } 6577 for (int i=0; i<res.key.allIntents.length; i++) { 6578 Intent intent = res.key.allIntents[i]; 6579 if (intent.getPackage() != null && intent.getComponent() != null) { 6580 return false; 6581 } 6582 } 6583 return true; 6584 } catch (ClassCastException e) { 6585 } 6586 return false; 6587 } 6588 6589 @Override 6590 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6591 if (!(pendingResult instanceof PendingIntentRecord)) { 6592 return false; 6593 } 6594 try { 6595 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6596 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6597 return true; 6598 } 6599 return false; 6600 } catch (ClassCastException e) { 6601 } 6602 return false; 6603 } 6604 6605 @Override 6606 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6607 if (!(pendingResult instanceof PendingIntentRecord)) { 6608 return null; 6609 } 6610 try { 6611 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6612 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6613 } catch (ClassCastException e) { 6614 } 6615 return null; 6616 } 6617 6618 @Override 6619 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6620 if (!(pendingResult instanceof PendingIntentRecord)) { 6621 return null; 6622 } 6623 try { 6624 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6625 Intent intent = res.key.requestIntent; 6626 if (intent != null) { 6627 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6628 || res.lastTagPrefix.equals(prefix))) { 6629 return res.lastTag; 6630 } 6631 res.lastTagPrefix = prefix; 6632 StringBuilder sb = new StringBuilder(128); 6633 if (prefix != null) { 6634 sb.append(prefix); 6635 } 6636 if (intent.getAction() != null) { 6637 sb.append(intent.getAction()); 6638 } else if (intent.getComponent() != null) { 6639 intent.getComponent().appendShortString(sb); 6640 } else { 6641 sb.append("?"); 6642 } 6643 return res.lastTag = sb.toString(); 6644 } 6645 } catch (ClassCastException e) { 6646 } 6647 return null; 6648 } 6649 6650 @Override 6651 public void setProcessLimit(int max) { 6652 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6653 "setProcessLimit()"); 6654 synchronized (this) { 6655 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6656 mProcessLimitOverride = max; 6657 } 6658 trimApplications(); 6659 } 6660 6661 @Override 6662 public int getProcessLimit() { 6663 synchronized (this) { 6664 return mProcessLimitOverride; 6665 } 6666 } 6667 6668 void foregroundTokenDied(ForegroundToken token) { 6669 synchronized (ActivityManagerService.this) { 6670 synchronized (mPidsSelfLocked) { 6671 ForegroundToken cur 6672 = mForegroundProcesses.get(token.pid); 6673 if (cur != token) { 6674 return; 6675 } 6676 mForegroundProcesses.remove(token.pid); 6677 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6678 if (pr == null) { 6679 return; 6680 } 6681 pr.forcingToForeground = null; 6682 updateProcessForegroundLocked(pr, false, false); 6683 } 6684 updateOomAdjLocked(); 6685 } 6686 } 6687 6688 @Override 6689 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6690 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6691 "setProcessForeground()"); 6692 synchronized(this) { 6693 boolean changed = false; 6694 6695 synchronized (mPidsSelfLocked) { 6696 ProcessRecord pr = mPidsSelfLocked.get(pid); 6697 if (pr == null && isForeground) { 6698 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6699 return; 6700 } 6701 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6702 if (oldToken != null) { 6703 oldToken.token.unlinkToDeath(oldToken, 0); 6704 mForegroundProcesses.remove(pid); 6705 if (pr != null) { 6706 pr.forcingToForeground = null; 6707 } 6708 changed = true; 6709 } 6710 if (isForeground && token != null) { 6711 ForegroundToken newToken = new ForegroundToken() { 6712 @Override 6713 public void binderDied() { 6714 foregroundTokenDied(this); 6715 } 6716 }; 6717 newToken.pid = pid; 6718 newToken.token = token; 6719 try { 6720 token.linkToDeath(newToken, 0); 6721 mForegroundProcesses.put(pid, newToken); 6722 pr.forcingToForeground = token; 6723 changed = true; 6724 } catch (RemoteException e) { 6725 // If the process died while doing this, we will later 6726 // do the cleanup with the process death link. 6727 } 6728 } 6729 } 6730 6731 if (changed) { 6732 updateOomAdjLocked(); 6733 } 6734 } 6735 } 6736 6737 // ========================================================= 6738 // PERMISSIONS 6739 // ========================================================= 6740 6741 static class PermissionController extends IPermissionController.Stub { 6742 ActivityManagerService mActivityManagerService; 6743 PermissionController(ActivityManagerService activityManagerService) { 6744 mActivityManagerService = activityManagerService; 6745 } 6746 6747 @Override 6748 public boolean checkPermission(String permission, int pid, int uid) { 6749 return mActivityManagerService.checkPermission(permission, pid, 6750 uid) == PackageManager.PERMISSION_GRANTED; 6751 } 6752 } 6753 6754 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6755 @Override 6756 public int checkComponentPermission(String permission, int pid, int uid, 6757 int owningUid, boolean exported) { 6758 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6759 owningUid, exported); 6760 } 6761 6762 @Override 6763 public Object getAMSLock() { 6764 return ActivityManagerService.this; 6765 } 6766 } 6767 6768 /** 6769 * This can be called with or without the global lock held. 6770 */ 6771 int checkComponentPermission(String permission, int pid, int uid, 6772 int owningUid, boolean exported) { 6773 if (pid == MY_PID) { 6774 return PackageManager.PERMISSION_GRANTED; 6775 } 6776 return ActivityManager.checkComponentPermission(permission, uid, 6777 owningUid, exported); 6778 } 6779 6780 /** 6781 * As the only public entry point for permissions checking, this method 6782 * can enforce the semantic that requesting a check on a null global 6783 * permission is automatically denied. (Internally a null permission 6784 * string is used when calling {@link #checkComponentPermission} in cases 6785 * when only uid-based security is needed.) 6786 * 6787 * This can be called with or without the global lock held. 6788 */ 6789 @Override 6790 public int checkPermission(String permission, int pid, int uid) { 6791 if (permission == null) { 6792 return PackageManager.PERMISSION_DENIED; 6793 } 6794 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6795 } 6796 6797 @Override 6798 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6799 if (permission == null) { 6800 return PackageManager.PERMISSION_DENIED; 6801 } 6802 6803 // We might be performing an operation on behalf of an indirect binder 6804 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6805 // client identity accordingly before proceeding. 6806 Identity tlsIdentity = sCallerIdentity.get(); 6807 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6808 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6809 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6810 uid = tlsIdentity.uid; 6811 pid = tlsIdentity.pid; 6812 } 6813 6814 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6815 } 6816 6817 /** 6818 * Binder IPC calls go through the public entry point. 6819 * This can be called with or without the global lock held. 6820 */ 6821 int checkCallingPermission(String permission) { 6822 return checkPermission(permission, 6823 Binder.getCallingPid(), 6824 UserHandle.getAppId(Binder.getCallingUid())); 6825 } 6826 6827 /** 6828 * This can be called with or without the global lock held. 6829 */ 6830 void enforceCallingPermission(String permission, String func) { 6831 if (checkCallingPermission(permission) 6832 == PackageManager.PERMISSION_GRANTED) { 6833 return; 6834 } 6835 6836 String msg = "Permission Denial: " + func + " from pid=" 6837 + Binder.getCallingPid() 6838 + ", uid=" + Binder.getCallingUid() 6839 + " requires " + permission; 6840 Slog.w(TAG, msg); 6841 throw new SecurityException(msg); 6842 } 6843 6844 /** 6845 * Determine if UID is holding permissions required to access {@link Uri} in 6846 * the given {@link ProviderInfo}. Final permission checking is always done 6847 * in {@link ContentProvider}. 6848 */ 6849 private final boolean checkHoldingPermissionsLocked( 6850 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6851 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6852 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6853 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6854 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6855 != PERMISSION_GRANTED) { 6856 return false; 6857 } 6858 } 6859 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6860 } 6861 6862 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6863 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6864 if (pi.applicationInfo.uid == uid) { 6865 return true; 6866 } else if (!pi.exported) { 6867 return false; 6868 } 6869 6870 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6871 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6872 try { 6873 // check if target holds top-level <provider> permissions 6874 if (!readMet && pi.readPermission != null && considerUidPermissions 6875 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6876 readMet = true; 6877 } 6878 if (!writeMet && pi.writePermission != null && considerUidPermissions 6879 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6880 writeMet = true; 6881 } 6882 6883 // track if unprotected read/write is allowed; any denied 6884 // <path-permission> below removes this ability 6885 boolean allowDefaultRead = pi.readPermission == null; 6886 boolean allowDefaultWrite = pi.writePermission == null; 6887 6888 // check if target holds any <path-permission> that match uri 6889 final PathPermission[] pps = pi.pathPermissions; 6890 if (pps != null) { 6891 final String path = grantUri.uri.getPath(); 6892 int i = pps.length; 6893 while (i > 0 && (!readMet || !writeMet)) { 6894 i--; 6895 PathPermission pp = pps[i]; 6896 if (pp.match(path)) { 6897 if (!readMet) { 6898 final String pprperm = pp.getReadPermission(); 6899 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6900 + pprperm + " for " + pp.getPath() 6901 + ": match=" + pp.match(path) 6902 + " check=" + pm.checkUidPermission(pprperm, uid)); 6903 if (pprperm != null) { 6904 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6905 == PERMISSION_GRANTED) { 6906 readMet = true; 6907 } else { 6908 allowDefaultRead = false; 6909 } 6910 } 6911 } 6912 if (!writeMet) { 6913 final String ppwperm = pp.getWritePermission(); 6914 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6915 + ppwperm + " for " + pp.getPath() 6916 + ": match=" + pp.match(path) 6917 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6918 if (ppwperm != null) { 6919 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6920 == PERMISSION_GRANTED) { 6921 writeMet = true; 6922 } else { 6923 allowDefaultWrite = false; 6924 } 6925 } 6926 } 6927 } 6928 } 6929 } 6930 6931 // grant unprotected <provider> read/write, if not blocked by 6932 // <path-permission> above 6933 if (allowDefaultRead) readMet = true; 6934 if (allowDefaultWrite) writeMet = true; 6935 6936 } catch (RemoteException e) { 6937 return false; 6938 } 6939 6940 return readMet && writeMet; 6941 } 6942 6943 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6944 ProviderInfo pi = null; 6945 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6946 if (cpr != null) { 6947 pi = cpr.info; 6948 } else { 6949 try { 6950 pi = AppGlobals.getPackageManager().resolveContentProvider( 6951 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6952 } catch (RemoteException ex) { 6953 } 6954 } 6955 return pi; 6956 } 6957 6958 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6959 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6960 if (targetUris != null) { 6961 return targetUris.get(grantUri); 6962 } 6963 return null; 6964 } 6965 6966 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6967 String targetPkg, int targetUid, GrantUri grantUri) { 6968 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6969 if (targetUris == null) { 6970 targetUris = Maps.newArrayMap(); 6971 mGrantedUriPermissions.put(targetUid, targetUris); 6972 } 6973 6974 UriPermission perm = targetUris.get(grantUri); 6975 if (perm == null) { 6976 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6977 targetUris.put(grantUri, perm); 6978 } 6979 6980 return perm; 6981 } 6982 6983 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6984 final int modeFlags) { 6985 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6986 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6987 : UriPermission.STRENGTH_OWNED; 6988 6989 // Root gets to do everything. 6990 if (uid == 0) { 6991 return true; 6992 } 6993 6994 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6995 if (perms == null) return false; 6996 6997 // First look for exact match 6998 final UriPermission exactPerm = perms.get(grantUri); 6999 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7000 return true; 7001 } 7002 7003 // No exact match, look for prefixes 7004 final int N = perms.size(); 7005 for (int i = 0; i < N; i++) { 7006 final UriPermission perm = perms.valueAt(i); 7007 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7008 && perm.getStrength(modeFlags) >= minStrength) { 7009 return true; 7010 } 7011 } 7012 7013 return false; 7014 } 7015 7016 /** 7017 * @param uri This uri must NOT contain an embedded userId. 7018 * @param userId The userId in which the uri is to be resolved. 7019 */ 7020 @Override 7021 public int checkUriPermission(Uri uri, int pid, int uid, 7022 final int modeFlags, int userId, IBinder callerToken) { 7023 enforceNotIsolatedCaller("checkUriPermission"); 7024 7025 // Another redirected-binder-call permissions check as in 7026 // {@link checkPermissionWithToken}. 7027 Identity tlsIdentity = sCallerIdentity.get(); 7028 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7029 uid = tlsIdentity.uid; 7030 pid = tlsIdentity.pid; 7031 } 7032 7033 // Our own process gets to do everything. 7034 if (pid == MY_PID) { 7035 return PackageManager.PERMISSION_GRANTED; 7036 } 7037 synchronized (this) { 7038 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7039 ? PackageManager.PERMISSION_GRANTED 7040 : PackageManager.PERMISSION_DENIED; 7041 } 7042 } 7043 7044 /** 7045 * Check if the targetPkg can be granted permission to access uri by 7046 * the callingUid using the given modeFlags. Throws a security exception 7047 * if callingUid is not allowed to do this. Returns the uid of the target 7048 * if the URI permission grant should be performed; returns -1 if it is not 7049 * needed (for example targetPkg already has permission to access the URI). 7050 * If you already know the uid of the target, you can supply it in 7051 * lastTargetUid else set that to -1. 7052 */ 7053 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7054 final int modeFlags, int lastTargetUid) { 7055 if (!Intent.isAccessUriMode(modeFlags)) { 7056 return -1; 7057 } 7058 7059 if (targetPkg != null) { 7060 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7061 "Checking grant " + targetPkg + " permission to " + grantUri); 7062 } 7063 7064 final IPackageManager pm = AppGlobals.getPackageManager(); 7065 7066 // If this is not a content: uri, we can't do anything with it. 7067 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7068 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7069 "Can't grant URI permission for non-content URI: " + grantUri); 7070 return -1; 7071 } 7072 7073 final String authority = grantUri.uri.getAuthority(); 7074 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7075 if (pi == null) { 7076 Slog.w(TAG, "No content provider found for permission check: " + 7077 grantUri.uri.toSafeString()); 7078 return -1; 7079 } 7080 7081 int targetUid = lastTargetUid; 7082 if (targetUid < 0 && targetPkg != null) { 7083 try { 7084 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7085 if (targetUid < 0) { 7086 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7087 "Can't grant URI permission no uid for: " + targetPkg); 7088 return -1; 7089 } 7090 } catch (RemoteException ex) { 7091 return -1; 7092 } 7093 } 7094 7095 if (targetUid >= 0) { 7096 // First... does the target actually need this permission? 7097 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7098 // No need to grant the target this permission. 7099 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7100 "Target " + targetPkg + " already has full permission to " + grantUri); 7101 return -1; 7102 } 7103 } else { 7104 // First... there is no target package, so can anyone access it? 7105 boolean allowed = pi.exported; 7106 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7107 if (pi.readPermission != null) { 7108 allowed = false; 7109 } 7110 } 7111 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7112 if (pi.writePermission != null) { 7113 allowed = false; 7114 } 7115 } 7116 if (allowed) { 7117 return -1; 7118 } 7119 } 7120 7121 /* There is a special cross user grant if: 7122 * - The target is on another user. 7123 * - Apps on the current user can access the uri without any uid permissions. 7124 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7125 * grant uri permissions. 7126 */ 7127 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7128 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7129 modeFlags, false /*without considering the uid permissions*/); 7130 7131 // Second... is the provider allowing granting of URI permissions? 7132 if (!specialCrossUserGrant) { 7133 if (!pi.grantUriPermissions) { 7134 throw new SecurityException("Provider " + pi.packageName 7135 + "/" + pi.name 7136 + " does not allow granting of Uri permissions (uri " 7137 + grantUri + ")"); 7138 } 7139 if (pi.uriPermissionPatterns != null) { 7140 final int N = pi.uriPermissionPatterns.length; 7141 boolean allowed = false; 7142 for (int i=0; i<N; i++) { 7143 if (pi.uriPermissionPatterns[i] != null 7144 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7145 allowed = true; 7146 break; 7147 } 7148 } 7149 if (!allowed) { 7150 throw new SecurityException("Provider " + pi.packageName 7151 + "/" + pi.name 7152 + " does not allow granting of permission to path of Uri " 7153 + grantUri); 7154 } 7155 } 7156 } 7157 7158 // Third... does the caller itself have permission to access 7159 // this uri? 7160 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7161 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7162 // Require they hold a strong enough Uri permission 7163 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7164 throw new SecurityException("Uid " + callingUid 7165 + " does not have permission to uri " + grantUri); 7166 } 7167 } 7168 } 7169 return targetUid; 7170 } 7171 7172 /** 7173 * @param uri This uri must NOT contain an embedded userId. 7174 * @param userId The userId in which the uri is to be resolved. 7175 */ 7176 @Override 7177 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7178 final int modeFlags, int userId) { 7179 enforceNotIsolatedCaller("checkGrantUriPermission"); 7180 synchronized(this) { 7181 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7182 new GrantUri(userId, uri, false), modeFlags, -1); 7183 } 7184 } 7185 7186 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7187 final int modeFlags, UriPermissionOwner owner) { 7188 if (!Intent.isAccessUriMode(modeFlags)) { 7189 return; 7190 } 7191 7192 // So here we are: the caller has the assumed permission 7193 // to the uri, and the target doesn't. Let's now give this to 7194 // the target. 7195 7196 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7197 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7198 7199 final String authority = grantUri.uri.getAuthority(); 7200 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7201 if (pi == null) { 7202 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7203 return; 7204 } 7205 7206 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7207 grantUri.prefix = true; 7208 } 7209 final UriPermission perm = findOrCreateUriPermissionLocked( 7210 pi.packageName, targetPkg, targetUid, grantUri); 7211 perm.grantModes(modeFlags, owner); 7212 } 7213 7214 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7215 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7216 if (targetPkg == null) { 7217 throw new NullPointerException("targetPkg"); 7218 } 7219 int targetUid; 7220 final IPackageManager pm = AppGlobals.getPackageManager(); 7221 try { 7222 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7223 } catch (RemoteException ex) { 7224 return; 7225 } 7226 7227 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7228 targetUid); 7229 if (targetUid < 0) { 7230 return; 7231 } 7232 7233 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7234 owner); 7235 } 7236 7237 static class NeededUriGrants extends ArrayList<GrantUri> { 7238 final String targetPkg; 7239 final int targetUid; 7240 final int flags; 7241 7242 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7243 this.targetPkg = targetPkg; 7244 this.targetUid = targetUid; 7245 this.flags = flags; 7246 } 7247 } 7248 7249 /** 7250 * Like checkGrantUriPermissionLocked, but takes an Intent. 7251 */ 7252 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7253 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7254 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7255 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7256 + " clip=" + (intent != null ? intent.getClipData() : null) 7257 + " from " + intent + "; flags=0x" 7258 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7259 7260 if (targetPkg == null) { 7261 throw new NullPointerException("targetPkg"); 7262 } 7263 7264 if (intent == null) { 7265 return null; 7266 } 7267 Uri data = intent.getData(); 7268 ClipData clip = intent.getClipData(); 7269 if (data == null && clip == null) { 7270 return null; 7271 } 7272 // Default userId for uris in the intent (if they don't specify it themselves) 7273 int contentUserHint = intent.getContentUserHint(); 7274 if (contentUserHint == UserHandle.USER_CURRENT) { 7275 contentUserHint = UserHandle.getUserId(callingUid); 7276 } 7277 final IPackageManager pm = AppGlobals.getPackageManager(); 7278 int targetUid; 7279 if (needed != null) { 7280 targetUid = needed.targetUid; 7281 } else { 7282 try { 7283 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7284 } catch (RemoteException ex) { 7285 return null; 7286 } 7287 if (targetUid < 0) { 7288 if (DEBUG_URI_PERMISSION) { 7289 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7290 + " on user " + targetUserId); 7291 } 7292 return null; 7293 } 7294 } 7295 if (data != null) { 7296 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7297 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7298 targetUid); 7299 if (targetUid > 0) { 7300 if (needed == null) { 7301 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7302 } 7303 needed.add(grantUri); 7304 } 7305 } 7306 if (clip != null) { 7307 for (int i=0; i<clip.getItemCount(); i++) { 7308 Uri uri = clip.getItemAt(i).getUri(); 7309 if (uri != null) { 7310 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7311 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7312 targetUid); 7313 if (targetUid > 0) { 7314 if (needed == null) { 7315 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7316 } 7317 needed.add(grantUri); 7318 } 7319 } else { 7320 Intent clipIntent = clip.getItemAt(i).getIntent(); 7321 if (clipIntent != null) { 7322 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7323 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7324 if (newNeeded != null) { 7325 needed = newNeeded; 7326 } 7327 } 7328 } 7329 } 7330 } 7331 7332 return needed; 7333 } 7334 7335 /** 7336 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7337 */ 7338 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7339 UriPermissionOwner owner) { 7340 if (needed != null) { 7341 for (int i=0; i<needed.size(); i++) { 7342 GrantUri grantUri = needed.get(i); 7343 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7344 grantUri, needed.flags, owner); 7345 } 7346 } 7347 } 7348 7349 void grantUriPermissionFromIntentLocked(int callingUid, 7350 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7351 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7352 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7353 if (needed == null) { 7354 return; 7355 } 7356 7357 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7358 } 7359 7360 /** 7361 * @param uri This uri must NOT contain an embedded userId. 7362 * @param userId The userId in which the uri is to be resolved. 7363 */ 7364 @Override 7365 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7366 final int modeFlags, int userId) { 7367 enforceNotIsolatedCaller("grantUriPermission"); 7368 GrantUri grantUri = new GrantUri(userId, uri, false); 7369 synchronized(this) { 7370 final ProcessRecord r = getRecordForAppLocked(caller); 7371 if (r == null) { 7372 throw new SecurityException("Unable to find app for caller " 7373 + caller 7374 + " when granting permission to uri " + grantUri); 7375 } 7376 if (targetPkg == null) { 7377 throw new IllegalArgumentException("null target"); 7378 } 7379 if (grantUri == null) { 7380 throw new IllegalArgumentException("null uri"); 7381 } 7382 7383 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7384 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7385 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7386 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7387 7388 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7389 UserHandle.getUserId(r.uid)); 7390 } 7391 } 7392 7393 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7394 if (perm.modeFlags == 0) { 7395 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7396 perm.targetUid); 7397 if (perms != null) { 7398 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7399 "Removing " + perm.targetUid + " permission to " + perm.uri); 7400 7401 perms.remove(perm.uri); 7402 if (perms.isEmpty()) { 7403 mGrantedUriPermissions.remove(perm.targetUid); 7404 } 7405 } 7406 } 7407 } 7408 7409 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7410 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7411 7412 final IPackageManager pm = AppGlobals.getPackageManager(); 7413 final String authority = grantUri.uri.getAuthority(); 7414 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7415 if (pi == null) { 7416 Slog.w(TAG, "No content provider found for permission revoke: " 7417 + grantUri.toSafeString()); 7418 return; 7419 } 7420 7421 // Does the caller have this permission on the URI? 7422 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7423 // If they don't have direct access to the URI, then revoke any 7424 // ownerless URI permissions that have been granted to them. 7425 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7426 if (perms != null) { 7427 boolean persistChanged = false; 7428 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7429 final UriPermission perm = it.next(); 7430 if (perm.uri.sourceUserId == grantUri.sourceUserId 7431 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7432 if (DEBUG_URI_PERMISSION) 7433 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7434 " permission to " + perm.uri); 7435 persistChanged |= perm.revokeModes( 7436 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7437 if (perm.modeFlags == 0) { 7438 it.remove(); 7439 } 7440 } 7441 } 7442 if (perms.isEmpty()) { 7443 mGrantedUriPermissions.remove(callingUid); 7444 } 7445 if (persistChanged) { 7446 schedulePersistUriGrants(); 7447 } 7448 } 7449 return; 7450 } 7451 7452 boolean persistChanged = false; 7453 7454 // Go through all of the permissions and remove any that match. 7455 int N = mGrantedUriPermissions.size(); 7456 for (int i = 0; i < N; i++) { 7457 final int targetUid = mGrantedUriPermissions.keyAt(i); 7458 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7459 7460 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7461 final UriPermission perm = it.next(); 7462 if (perm.uri.sourceUserId == grantUri.sourceUserId 7463 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7464 if (DEBUG_URI_PERMISSION) 7465 Slog.v(TAG, 7466 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7467 persistChanged |= perm.revokeModes( 7468 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7469 if (perm.modeFlags == 0) { 7470 it.remove(); 7471 } 7472 } 7473 } 7474 7475 if (perms.isEmpty()) { 7476 mGrantedUriPermissions.remove(targetUid); 7477 N--; 7478 i--; 7479 } 7480 } 7481 7482 if (persistChanged) { 7483 schedulePersistUriGrants(); 7484 } 7485 } 7486 7487 /** 7488 * @param uri This uri must NOT contain an embedded userId. 7489 * @param userId The userId in which the uri is to be resolved. 7490 */ 7491 @Override 7492 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7493 int userId) { 7494 enforceNotIsolatedCaller("revokeUriPermission"); 7495 synchronized(this) { 7496 final ProcessRecord r = getRecordForAppLocked(caller); 7497 if (r == null) { 7498 throw new SecurityException("Unable to find app for caller " 7499 + caller 7500 + " when revoking permission to uri " + uri); 7501 } 7502 if (uri == null) { 7503 Slog.w(TAG, "revokeUriPermission: null uri"); 7504 return; 7505 } 7506 7507 if (!Intent.isAccessUriMode(modeFlags)) { 7508 return; 7509 } 7510 7511 final IPackageManager pm = AppGlobals.getPackageManager(); 7512 final String authority = uri.getAuthority(); 7513 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7514 if (pi == null) { 7515 Slog.w(TAG, "No content provider found for permission revoke: " 7516 + uri.toSafeString()); 7517 return; 7518 } 7519 7520 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7521 } 7522 } 7523 7524 /** 7525 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7526 * given package. 7527 * 7528 * @param packageName Package name to match, or {@code null} to apply to all 7529 * packages. 7530 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7531 * to all users. 7532 * @param persistable If persistable grants should be removed. 7533 */ 7534 private void removeUriPermissionsForPackageLocked( 7535 String packageName, int userHandle, boolean persistable) { 7536 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7537 throw new IllegalArgumentException("Must narrow by either package or user"); 7538 } 7539 7540 boolean persistChanged = false; 7541 7542 int N = mGrantedUriPermissions.size(); 7543 for (int i = 0; i < N; i++) { 7544 final int targetUid = mGrantedUriPermissions.keyAt(i); 7545 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7546 7547 // Only inspect grants matching user 7548 if (userHandle == UserHandle.USER_ALL 7549 || userHandle == UserHandle.getUserId(targetUid)) { 7550 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7551 final UriPermission perm = it.next(); 7552 7553 // Only inspect grants matching package 7554 if (packageName == null || perm.sourcePkg.equals(packageName) 7555 || perm.targetPkg.equals(packageName)) { 7556 persistChanged |= perm.revokeModes(persistable 7557 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7558 7559 // Only remove when no modes remain; any persisted grants 7560 // will keep this alive. 7561 if (perm.modeFlags == 0) { 7562 it.remove(); 7563 } 7564 } 7565 } 7566 7567 if (perms.isEmpty()) { 7568 mGrantedUriPermissions.remove(targetUid); 7569 N--; 7570 i--; 7571 } 7572 } 7573 } 7574 7575 if (persistChanged) { 7576 schedulePersistUriGrants(); 7577 } 7578 } 7579 7580 @Override 7581 public IBinder newUriPermissionOwner(String name) { 7582 enforceNotIsolatedCaller("newUriPermissionOwner"); 7583 synchronized(this) { 7584 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7585 return owner.getExternalTokenLocked(); 7586 } 7587 } 7588 7589 /** 7590 * @param uri This uri must NOT contain an embedded userId. 7591 * @param sourceUserId The userId in which the uri is to be resolved. 7592 * @param targetUserId The userId of the app that receives the grant. 7593 */ 7594 @Override 7595 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7596 final int modeFlags, int sourceUserId, int targetUserId) { 7597 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7598 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7599 synchronized(this) { 7600 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7601 if (owner == null) { 7602 throw new IllegalArgumentException("Unknown owner: " + token); 7603 } 7604 if (fromUid != Binder.getCallingUid()) { 7605 if (Binder.getCallingUid() != Process.myUid()) { 7606 // Only system code can grant URI permissions on behalf 7607 // of other users. 7608 throw new SecurityException("nice try"); 7609 } 7610 } 7611 if (targetPkg == null) { 7612 throw new IllegalArgumentException("null target"); 7613 } 7614 if (uri == null) { 7615 throw new IllegalArgumentException("null uri"); 7616 } 7617 7618 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7619 modeFlags, owner, targetUserId); 7620 } 7621 } 7622 7623 /** 7624 * @param uri This uri must NOT contain an embedded userId. 7625 * @param userId The userId in which the uri is to be resolved. 7626 */ 7627 @Override 7628 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7629 synchronized(this) { 7630 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7631 if (owner == null) { 7632 throw new IllegalArgumentException("Unknown owner: " + token); 7633 } 7634 7635 if (uri == null) { 7636 owner.removeUriPermissionsLocked(mode); 7637 } else { 7638 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7639 } 7640 } 7641 } 7642 7643 private void schedulePersistUriGrants() { 7644 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7645 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7646 10 * DateUtils.SECOND_IN_MILLIS); 7647 } 7648 } 7649 7650 private void writeGrantedUriPermissions() { 7651 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7652 7653 // Snapshot permissions so we can persist without lock 7654 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7655 synchronized (this) { 7656 final int size = mGrantedUriPermissions.size(); 7657 for (int i = 0; i < size; i++) { 7658 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7659 for (UriPermission perm : perms.values()) { 7660 if (perm.persistedModeFlags != 0) { 7661 persist.add(perm.snapshot()); 7662 } 7663 } 7664 } 7665 } 7666 7667 FileOutputStream fos = null; 7668 try { 7669 fos = mGrantFile.startWrite(); 7670 7671 XmlSerializer out = new FastXmlSerializer(); 7672 out.setOutput(fos, "utf-8"); 7673 out.startDocument(null, true); 7674 out.startTag(null, TAG_URI_GRANTS); 7675 for (UriPermission.Snapshot perm : persist) { 7676 out.startTag(null, TAG_URI_GRANT); 7677 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7678 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7679 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7680 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7681 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7682 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7683 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7684 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7685 out.endTag(null, TAG_URI_GRANT); 7686 } 7687 out.endTag(null, TAG_URI_GRANTS); 7688 out.endDocument(); 7689 7690 mGrantFile.finishWrite(fos); 7691 } catch (IOException e) { 7692 if (fos != null) { 7693 mGrantFile.failWrite(fos); 7694 } 7695 } 7696 } 7697 7698 private void readGrantedUriPermissionsLocked() { 7699 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7700 7701 final long now = System.currentTimeMillis(); 7702 7703 FileInputStream fis = null; 7704 try { 7705 fis = mGrantFile.openRead(); 7706 final XmlPullParser in = Xml.newPullParser(); 7707 in.setInput(fis, null); 7708 7709 int type; 7710 while ((type = in.next()) != END_DOCUMENT) { 7711 final String tag = in.getName(); 7712 if (type == START_TAG) { 7713 if (TAG_URI_GRANT.equals(tag)) { 7714 final int sourceUserId; 7715 final int targetUserId; 7716 final int userHandle = readIntAttribute(in, 7717 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7718 if (userHandle != UserHandle.USER_NULL) { 7719 // For backwards compatibility. 7720 sourceUserId = userHandle; 7721 targetUserId = userHandle; 7722 } else { 7723 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7724 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7725 } 7726 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7727 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7728 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7729 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7730 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7731 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7732 7733 // Sanity check that provider still belongs to source package 7734 final ProviderInfo pi = getProviderInfoLocked( 7735 uri.getAuthority(), sourceUserId); 7736 if (pi != null && sourcePkg.equals(pi.packageName)) { 7737 int targetUid = -1; 7738 try { 7739 targetUid = AppGlobals.getPackageManager() 7740 .getPackageUid(targetPkg, targetUserId); 7741 } catch (RemoteException e) { 7742 } 7743 if (targetUid != -1) { 7744 final UriPermission perm = findOrCreateUriPermissionLocked( 7745 sourcePkg, targetPkg, targetUid, 7746 new GrantUri(sourceUserId, uri, prefix)); 7747 perm.initPersistedModes(modeFlags, createdTime); 7748 } 7749 } else { 7750 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7751 + " but instead found " + pi); 7752 } 7753 } 7754 } 7755 } 7756 } catch (FileNotFoundException e) { 7757 // Missing grants is okay 7758 } catch (IOException e) { 7759 Slog.wtf(TAG, "Failed reading Uri grants", e); 7760 } catch (XmlPullParserException e) { 7761 Slog.wtf(TAG, "Failed reading Uri grants", e); 7762 } finally { 7763 IoUtils.closeQuietly(fis); 7764 } 7765 } 7766 7767 /** 7768 * @param uri This uri must NOT contain an embedded userId. 7769 * @param userId The userId in which the uri is to be resolved. 7770 */ 7771 @Override 7772 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7773 enforceNotIsolatedCaller("takePersistableUriPermission"); 7774 7775 Preconditions.checkFlagsArgument(modeFlags, 7776 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7777 7778 synchronized (this) { 7779 final int callingUid = Binder.getCallingUid(); 7780 boolean persistChanged = false; 7781 GrantUri grantUri = new GrantUri(userId, uri, false); 7782 7783 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7784 new GrantUri(userId, uri, false)); 7785 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7786 new GrantUri(userId, uri, true)); 7787 7788 final boolean exactValid = (exactPerm != null) 7789 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7790 final boolean prefixValid = (prefixPerm != null) 7791 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7792 7793 if (!(exactValid || prefixValid)) { 7794 throw new SecurityException("No persistable permission grants found for UID " 7795 + callingUid + " and Uri " + grantUri.toSafeString()); 7796 } 7797 7798 if (exactValid) { 7799 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7800 } 7801 if (prefixValid) { 7802 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7803 } 7804 7805 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7806 7807 if (persistChanged) { 7808 schedulePersistUriGrants(); 7809 } 7810 } 7811 } 7812 7813 /** 7814 * @param uri This uri must NOT contain an embedded userId. 7815 * @param userId The userId in which the uri is to be resolved. 7816 */ 7817 @Override 7818 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7819 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7820 7821 Preconditions.checkFlagsArgument(modeFlags, 7822 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7823 7824 synchronized (this) { 7825 final int callingUid = Binder.getCallingUid(); 7826 boolean persistChanged = false; 7827 7828 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7829 new GrantUri(userId, uri, false)); 7830 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7831 new GrantUri(userId, uri, true)); 7832 if (exactPerm == null && prefixPerm == null) { 7833 throw new SecurityException("No permission grants found for UID " + callingUid 7834 + " and Uri " + uri.toSafeString()); 7835 } 7836 7837 if (exactPerm != null) { 7838 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7839 removeUriPermissionIfNeededLocked(exactPerm); 7840 } 7841 if (prefixPerm != null) { 7842 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7843 removeUriPermissionIfNeededLocked(prefixPerm); 7844 } 7845 7846 if (persistChanged) { 7847 schedulePersistUriGrants(); 7848 } 7849 } 7850 } 7851 7852 /** 7853 * Prune any older {@link UriPermission} for the given UID until outstanding 7854 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7855 * 7856 * @return if any mutations occured that require persisting. 7857 */ 7858 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7859 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7860 if (perms == null) return false; 7861 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7862 7863 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7864 for (UriPermission perm : perms.values()) { 7865 if (perm.persistedModeFlags != 0) { 7866 persisted.add(perm); 7867 } 7868 } 7869 7870 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7871 if (trimCount <= 0) return false; 7872 7873 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7874 for (int i = 0; i < trimCount; i++) { 7875 final UriPermission perm = persisted.get(i); 7876 7877 if (DEBUG_URI_PERMISSION) { 7878 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7879 } 7880 7881 perm.releasePersistableModes(~0); 7882 removeUriPermissionIfNeededLocked(perm); 7883 } 7884 7885 return true; 7886 } 7887 7888 @Override 7889 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7890 String packageName, boolean incoming) { 7891 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7892 Preconditions.checkNotNull(packageName, "packageName"); 7893 7894 final int callingUid = Binder.getCallingUid(); 7895 final IPackageManager pm = AppGlobals.getPackageManager(); 7896 try { 7897 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7898 if (packageUid != callingUid) { 7899 throw new SecurityException( 7900 "Package " + packageName + " does not belong to calling UID " + callingUid); 7901 } 7902 } catch (RemoteException e) { 7903 throw new SecurityException("Failed to verify package name ownership"); 7904 } 7905 7906 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7907 synchronized (this) { 7908 if (incoming) { 7909 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7910 callingUid); 7911 if (perms == null) { 7912 Slog.w(TAG, "No permission grants found for " + packageName); 7913 } else { 7914 for (UriPermission perm : perms.values()) { 7915 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7916 result.add(perm.buildPersistedPublicApiObject()); 7917 } 7918 } 7919 } 7920 } else { 7921 final int size = mGrantedUriPermissions.size(); 7922 for (int i = 0; i < size; i++) { 7923 final ArrayMap<GrantUri, UriPermission> perms = 7924 mGrantedUriPermissions.valueAt(i); 7925 for (UriPermission perm : perms.values()) { 7926 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7927 result.add(perm.buildPersistedPublicApiObject()); 7928 } 7929 } 7930 } 7931 } 7932 } 7933 return new ParceledListSlice<android.content.UriPermission>(result); 7934 } 7935 7936 @Override 7937 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7938 synchronized (this) { 7939 ProcessRecord app = 7940 who != null ? getRecordForAppLocked(who) : null; 7941 if (app == null) return; 7942 7943 Message msg = Message.obtain(); 7944 msg.what = WAIT_FOR_DEBUGGER_MSG; 7945 msg.obj = app; 7946 msg.arg1 = waiting ? 1 : 0; 7947 mHandler.sendMessage(msg); 7948 } 7949 } 7950 7951 @Override 7952 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7953 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7954 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7955 outInfo.availMem = Process.getFreeMemory(); 7956 outInfo.totalMem = Process.getTotalMemory(); 7957 outInfo.threshold = homeAppMem; 7958 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7959 outInfo.hiddenAppThreshold = cachedAppMem; 7960 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7961 ProcessList.SERVICE_ADJ); 7962 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7963 ProcessList.VISIBLE_APP_ADJ); 7964 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7965 ProcessList.FOREGROUND_APP_ADJ); 7966 } 7967 7968 // ========================================================= 7969 // TASK MANAGEMENT 7970 // ========================================================= 7971 7972 @Override 7973 public List<IAppTask> getAppTasks(String callingPackage) { 7974 int callingUid = Binder.getCallingUid(); 7975 long ident = Binder.clearCallingIdentity(); 7976 7977 synchronized(this) { 7978 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7979 try { 7980 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7981 7982 final int N = mRecentTasks.size(); 7983 for (int i = 0; i < N; i++) { 7984 TaskRecord tr = mRecentTasks.get(i); 7985 // Skip tasks that do not match the caller. We don't need to verify 7986 // callingPackage, because we are also limiting to callingUid and know 7987 // that will limit to the correct security sandbox. 7988 if (tr.effectiveUid != callingUid) { 7989 continue; 7990 } 7991 Intent intent = tr.getBaseIntent(); 7992 if (intent == null || 7993 !callingPackage.equals(intent.getComponent().getPackageName())) { 7994 continue; 7995 } 7996 ActivityManager.RecentTaskInfo taskInfo = 7997 createRecentTaskInfoFromTaskRecord(tr); 7998 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7999 list.add(taskImpl); 8000 } 8001 } finally { 8002 Binder.restoreCallingIdentity(ident); 8003 } 8004 return list; 8005 } 8006 } 8007 8008 @Override 8009 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8010 final int callingUid = Binder.getCallingUid(); 8011 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8012 8013 synchronized(this) { 8014 if (localLOGV) Slog.v( 8015 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8016 8017 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8018 callingUid); 8019 8020 // TODO: Improve with MRU list from all ActivityStacks. 8021 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8022 } 8023 8024 return list; 8025 } 8026 8027 /** 8028 * Creates a new RecentTaskInfo from a TaskRecord. 8029 */ 8030 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8031 // Update the task description to reflect any changes in the task stack 8032 tr.updateTaskDescription(); 8033 8034 // Compose the recent task info 8035 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8036 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8037 rti.persistentId = tr.taskId; 8038 rti.baseIntent = new Intent(tr.getBaseIntent()); 8039 rti.origActivity = tr.origActivity; 8040 rti.description = tr.lastDescription; 8041 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8042 rti.userId = tr.userId; 8043 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8044 rti.firstActiveTime = tr.firstActiveTime; 8045 rti.lastActiveTime = tr.lastActiveTime; 8046 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8047 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8048 return rti; 8049 } 8050 8051 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8052 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8053 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8054 if (!allowed) { 8055 if (checkPermission(android.Manifest.permission.GET_TASKS, 8056 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8057 // Temporary compatibility: some existing apps on the system image may 8058 // still be requesting the old permission and not switched to the new 8059 // one; if so, we'll still allow them full access. This means we need 8060 // to see if they are holding the old permission and are a system app. 8061 try { 8062 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8063 allowed = true; 8064 Slog.w(TAG, caller + ": caller " + callingUid 8065 + " is using old GET_TASKS but privileged; allowing"); 8066 } 8067 } catch (RemoteException e) { 8068 } 8069 } 8070 } 8071 if (!allowed) { 8072 Slog.w(TAG, caller + ": caller " + callingUid 8073 + " does not hold GET_TASKS; limiting output"); 8074 } 8075 return allowed; 8076 } 8077 8078 @Override 8079 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8080 final int callingUid = Binder.getCallingUid(); 8081 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8082 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8083 8084 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8085 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8086 synchronized (this) { 8087 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8088 callingUid); 8089 final boolean detailed = checkCallingPermission( 8090 android.Manifest.permission.GET_DETAILED_TASKS) 8091 == PackageManager.PERMISSION_GRANTED; 8092 8093 final int N = mRecentTasks.size(); 8094 ArrayList<ActivityManager.RecentTaskInfo> res 8095 = new ArrayList<ActivityManager.RecentTaskInfo>( 8096 maxNum < N ? maxNum : N); 8097 8098 final Set<Integer> includedUsers; 8099 if (includeProfiles) { 8100 includedUsers = getProfileIdsLocked(userId); 8101 } else { 8102 includedUsers = new HashSet<Integer>(); 8103 } 8104 includedUsers.add(Integer.valueOf(userId)); 8105 8106 for (int i=0; i<N && maxNum > 0; i++) { 8107 TaskRecord tr = mRecentTasks.get(i); 8108 // Only add calling user or related users recent tasks 8109 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8110 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8111 continue; 8112 } 8113 8114 // Return the entry if desired by the caller. We always return 8115 // the first entry, because callers always expect this to be the 8116 // foreground app. We may filter others if the caller has 8117 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8118 // we should exclude the entry. 8119 8120 if (i == 0 8121 || withExcluded 8122 || (tr.intent == null) 8123 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8124 == 0)) { 8125 if (!allowed) { 8126 // If the caller doesn't have the GET_TASKS permission, then only 8127 // allow them to see a small subset of tasks -- their own and home. 8128 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8129 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8130 continue; 8131 } 8132 } 8133 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8134 if (tr.stack != null && tr.stack.isHomeStack()) { 8135 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8136 continue; 8137 } 8138 } 8139 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8140 // Don't include auto remove tasks that are finished or finishing. 8141 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8142 + tr); 8143 continue; 8144 } 8145 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8146 && !tr.isAvailable) { 8147 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8148 continue; 8149 } 8150 8151 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8152 if (!detailed) { 8153 rti.baseIntent.replaceExtras((Bundle)null); 8154 } 8155 8156 res.add(rti); 8157 maxNum--; 8158 } 8159 } 8160 return res; 8161 } 8162 } 8163 8164 private TaskRecord taskForIdLocked(int id) { 8165 final TaskRecord task = recentTaskForIdLocked(id); 8166 if (task != null) { 8167 return task; 8168 } 8169 8170 // Don't give up. Sometimes it just hasn't made it to recents yet. 8171 return mStackSupervisor.anyTaskForIdLocked(id); 8172 } 8173 8174 private TaskRecord recentTaskForIdLocked(int id) { 8175 final int N = mRecentTasks.size(); 8176 for (int i=0; i<N; i++) { 8177 TaskRecord tr = mRecentTasks.get(i); 8178 if (tr.taskId == id) { 8179 return tr; 8180 } 8181 } 8182 return null; 8183 } 8184 8185 @Override 8186 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8187 synchronized (this) { 8188 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8189 "getTaskThumbnail()"); 8190 TaskRecord tr = recentTaskForIdLocked(id); 8191 if (tr != null) { 8192 return tr.getTaskThumbnailLocked(); 8193 } 8194 } 8195 return null; 8196 } 8197 8198 @Override 8199 public int addAppTask(IBinder activityToken, Intent intent, 8200 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8201 final int callingUid = Binder.getCallingUid(); 8202 final long callingIdent = Binder.clearCallingIdentity(); 8203 8204 try { 8205 synchronized (this) { 8206 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8207 if (r == null) { 8208 throw new IllegalArgumentException("Activity does not exist; token=" 8209 + activityToken); 8210 } 8211 ComponentName comp = intent.getComponent(); 8212 if (comp == null) { 8213 throw new IllegalArgumentException("Intent " + intent 8214 + " must specify explicit component"); 8215 } 8216 if (thumbnail.getWidth() != mThumbnailWidth 8217 || thumbnail.getHeight() != mThumbnailHeight) { 8218 throw new IllegalArgumentException("Bad thumbnail size: got " 8219 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8220 + mThumbnailWidth + "x" + mThumbnailHeight); 8221 } 8222 if (intent.getSelector() != null) { 8223 intent.setSelector(null); 8224 } 8225 if (intent.getSourceBounds() != null) { 8226 intent.setSourceBounds(null); 8227 } 8228 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8229 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8230 // The caller has added this as an auto-remove task... that makes no 8231 // sense, so turn off auto-remove. 8232 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8233 } 8234 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8235 // Must be a new task. 8236 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8237 } 8238 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8239 mLastAddedTaskActivity = null; 8240 } 8241 ActivityInfo ainfo = mLastAddedTaskActivity; 8242 if (ainfo == null) { 8243 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8244 comp, 0, UserHandle.getUserId(callingUid)); 8245 if (ainfo.applicationInfo.uid != callingUid) { 8246 throw new SecurityException( 8247 "Can't add task for another application: target uid=" 8248 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8249 } 8250 } 8251 8252 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8253 intent, description); 8254 8255 int trimIdx = trimRecentsForTaskLocked(task, false); 8256 if (trimIdx >= 0) { 8257 // If this would have caused a trim, then we'll abort because that 8258 // means it would be added at the end of the list but then just removed. 8259 return -1; 8260 } 8261 8262 final int N = mRecentTasks.size(); 8263 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8264 final TaskRecord tr = mRecentTasks.remove(N - 1); 8265 tr.removedFromRecents(); 8266 } 8267 8268 task.inRecents = true; 8269 mRecentTasks.add(task); 8270 r.task.stack.addTask(task, false, false); 8271 8272 task.setLastThumbnail(thumbnail); 8273 task.freeLastThumbnail(); 8274 8275 return task.taskId; 8276 } 8277 } finally { 8278 Binder.restoreCallingIdentity(callingIdent); 8279 } 8280 } 8281 8282 @Override 8283 public Point getAppTaskThumbnailSize() { 8284 synchronized (this) { 8285 return new Point(mThumbnailWidth, mThumbnailHeight); 8286 } 8287 } 8288 8289 @Override 8290 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8291 synchronized (this) { 8292 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8293 if (r != null) { 8294 r.setTaskDescription(td); 8295 r.task.updateTaskDescription(); 8296 } 8297 } 8298 } 8299 8300 @Override 8301 public Bitmap getTaskDescriptionIcon(String filename) { 8302 if (!FileUtils.isValidExtFilename(filename) 8303 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8304 throw new IllegalArgumentException("Bad filename: " + filename); 8305 } 8306 return mTaskPersister.getTaskDescriptionIcon(filename); 8307 } 8308 8309 @Override 8310 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8311 throws RemoteException { 8312 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8313 opts.getCustomInPlaceResId() == 0) { 8314 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8315 "with valid animation"); 8316 } 8317 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8318 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8319 opts.getCustomInPlaceResId()); 8320 mWindowManager.executeAppTransition(); 8321 } 8322 8323 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8324 mRecentTasks.remove(tr); 8325 tr.removedFromRecents(); 8326 ComponentName component = tr.getBaseIntent().getComponent(); 8327 if (component == null) { 8328 Slog.w(TAG, "No component for base intent of task: " + tr); 8329 return; 8330 } 8331 8332 if (!killProcess) { 8333 return; 8334 } 8335 8336 // Determine if the process(es) for this task should be killed. 8337 final String pkg = component.getPackageName(); 8338 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8339 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8340 for (int i = 0; i < pmap.size(); i++) { 8341 8342 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8343 for (int j = 0; j < uids.size(); j++) { 8344 ProcessRecord proc = uids.valueAt(j); 8345 if (proc.userId != tr.userId) { 8346 // Don't kill process for a different user. 8347 continue; 8348 } 8349 if (proc == mHomeProcess) { 8350 // Don't kill the home process along with tasks from the same package. 8351 continue; 8352 } 8353 if (!proc.pkgList.containsKey(pkg)) { 8354 // Don't kill process that is not associated with this task. 8355 continue; 8356 } 8357 8358 for (int k = 0; k < proc.activities.size(); k++) { 8359 TaskRecord otherTask = proc.activities.get(k).task; 8360 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8361 // Don't kill process(es) that has an activity in a different task that is 8362 // also in recents. 8363 return; 8364 } 8365 } 8366 8367 // Add process to kill list. 8368 procsToKill.add(proc); 8369 } 8370 } 8371 8372 // Find any running services associated with this app and stop if needed. 8373 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8374 8375 // Kill the running processes. 8376 for (int i = 0; i < procsToKill.size(); i++) { 8377 ProcessRecord pr = procsToKill.get(i); 8378 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8379 pr.kill("remove task", true); 8380 } else { 8381 pr.waitingToKill = "remove task"; 8382 } 8383 } 8384 } 8385 8386 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8387 // Remove all tasks with activities in the specified package from the list of recent tasks 8388 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8389 TaskRecord tr = mRecentTasks.get(i); 8390 if (tr.userId != userId) continue; 8391 8392 ComponentName cn = tr.intent.getComponent(); 8393 if (cn != null && cn.getPackageName().equals(packageName)) { 8394 // If the package name matches, remove the task. 8395 removeTaskByIdLocked(tr.taskId, true); 8396 } 8397 } 8398 } 8399 8400 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8401 final IPackageManager pm = AppGlobals.getPackageManager(); 8402 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8403 8404 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8405 TaskRecord tr = mRecentTasks.get(i); 8406 if (tr.userId != userId) continue; 8407 8408 ComponentName cn = tr.intent.getComponent(); 8409 if (cn != null && cn.getPackageName().equals(packageName)) { 8410 // Skip if component still exists in the package. 8411 if (componentsKnownToExist.contains(cn)) continue; 8412 8413 try { 8414 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8415 if (info != null) { 8416 componentsKnownToExist.add(cn); 8417 } else { 8418 removeTaskByIdLocked(tr.taskId, false); 8419 } 8420 } catch (RemoteException e) { 8421 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8422 } 8423 } 8424 } 8425 } 8426 8427 /** 8428 * Removes the task with the specified task id. 8429 * 8430 * @param taskId Identifier of the task to be removed. 8431 * @param killProcess Kill any process associated with the task if possible. 8432 * @return Returns true if the given task was found and removed. 8433 */ 8434 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8435 TaskRecord tr = taskForIdLocked(taskId); 8436 if (tr != null) { 8437 tr.removeTaskActivitiesLocked(); 8438 cleanUpRemovedTaskLocked(tr, killProcess); 8439 if (tr.isPersistable) { 8440 notifyTaskPersisterLocked(null, true); 8441 } 8442 return true; 8443 } 8444 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8445 return false; 8446 } 8447 8448 @Override 8449 public boolean removeTask(int taskId) { 8450 synchronized (this) { 8451 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8452 "removeTask()"); 8453 long ident = Binder.clearCallingIdentity(); 8454 try { 8455 return removeTaskByIdLocked(taskId, true); 8456 } finally { 8457 Binder.restoreCallingIdentity(ident); 8458 } 8459 } 8460 } 8461 8462 /** 8463 * TODO: Add mController hook 8464 */ 8465 @Override 8466 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8467 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8468 "moveTaskToFront()"); 8469 8470 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8471 synchronized(this) { 8472 moveTaskToFrontLocked(taskId, flags, options); 8473 } 8474 } 8475 8476 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8477 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8478 Binder.getCallingUid(), -1, -1, "Task to front")) { 8479 ActivityOptions.abort(options); 8480 return; 8481 } 8482 final long origId = Binder.clearCallingIdentity(); 8483 try { 8484 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8485 if (task == null) { 8486 Slog.d(TAG, "Could not find task for id: "+ taskId); 8487 return; 8488 } 8489 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8490 mStackSupervisor.showLockTaskToast(); 8491 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8492 return; 8493 } 8494 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8495 if (prev != null && prev.isRecentsActivity()) { 8496 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8497 } 8498 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8499 } finally { 8500 Binder.restoreCallingIdentity(origId); 8501 } 8502 ActivityOptions.abort(options); 8503 } 8504 8505 @Override 8506 public void moveTaskToBack(int taskId) { 8507 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8508 "moveTaskToBack()"); 8509 8510 synchronized(this) { 8511 TaskRecord tr = taskForIdLocked(taskId); 8512 if (tr != null) { 8513 if (tr == mStackSupervisor.mLockTaskModeTask) { 8514 mStackSupervisor.showLockTaskToast(); 8515 return; 8516 } 8517 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8518 ActivityStack stack = tr.stack; 8519 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8520 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8521 Binder.getCallingUid(), -1, -1, "Task to back")) { 8522 return; 8523 } 8524 } 8525 final long origId = Binder.clearCallingIdentity(); 8526 try { 8527 stack.moveTaskToBackLocked(taskId, null); 8528 } finally { 8529 Binder.restoreCallingIdentity(origId); 8530 } 8531 } 8532 } 8533 } 8534 8535 /** 8536 * Moves an activity, and all of the other activities within the same task, to the bottom 8537 * of the history stack. The activity's order within the task is unchanged. 8538 * 8539 * @param token A reference to the activity we wish to move 8540 * @param nonRoot If false then this only works if the activity is the root 8541 * of a task; if true it will work for any activity in a task. 8542 * @return Returns true if the move completed, false if not. 8543 */ 8544 @Override 8545 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8546 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8547 synchronized(this) { 8548 final long origId = Binder.clearCallingIdentity(); 8549 try { 8550 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8551 if (taskId >= 0) { 8552 if ((mStackSupervisor.mLockTaskModeTask != null) 8553 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8554 mStackSupervisor.showLockTaskToast(); 8555 return false; 8556 } 8557 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8558 } 8559 } finally { 8560 Binder.restoreCallingIdentity(origId); 8561 } 8562 } 8563 return false; 8564 } 8565 8566 @Override 8567 public void moveTaskBackwards(int task) { 8568 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8569 "moveTaskBackwards()"); 8570 8571 synchronized(this) { 8572 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8573 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8574 return; 8575 } 8576 final long origId = Binder.clearCallingIdentity(); 8577 moveTaskBackwardsLocked(task); 8578 Binder.restoreCallingIdentity(origId); 8579 } 8580 } 8581 8582 private final void moveTaskBackwardsLocked(int task) { 8583 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8584 } 8585 8586 @Override 8587 public IBinder getHomeActivityToken() throws RemoteException { 8588 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8589 "getHomeActivityToken()"); 8590 synchronized (this) { 8591 return mStackSupervisor.getHomeActivityToken(); 8592 } 8593 } 8594 8595 @Override 8596 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8597 IActivityContainerCallback callback) throws RemoteException { 8598 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8599 "createActivityContainer()"); 8600 synchronized (this) { 8601 if (parentActivityToken == null) { 8602 throw new IllegalArgumentException("parent token must not be null"); 8603 } 8604 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8605 if (r == null) { 8606 return null; 8607 } 8608 if (callback == null) { 8609 throw new IllegalArgumentException("callback must not be null"); 8610 } 8611 return mStackSupervisor.createActivityContainer(r, callback); 8612 } 8613 } 8614 8615 @Override 8616 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8617 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8618 "deleteActivityContainer()"); 8619 synchronized (this) { 8620 mStackSupervisor.deleteActivityContainer(container); 8621 } 8622 } 8623 8624 @Override 8625 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8626 throws RemoteException { 8627 synchronized (this) { 8628 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8629 if (stack != null) { 8630 return stack.mActivityContainer; 8631 } 8632 return null; 8633 } 8634 } 8635 8636 @Override 8637 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8638 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8639 "moveTaskToStack()"); 8640 if (stackId == HOME_STACK_ID) { 8641 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8642 new RuntimeException("here").fillInStackTrace()); 8643 } 8644 synchronized (this) { 8645 long ident = Binder.clearCallingIdentity(); 8646 try { 8647 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8648 + stackId + " toTop=" + toTop); 8649 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8650 } finally { 8651 Binder.restoreCallingIdentity(ident); 8652 } 8653 } 8654 } 8655 8656 @Override 8657 public void resizeStack(int stackBoxId, Rect bounds) { 8658 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8659 "resizeStackBox()"); 8660 long ident = Binder.clearCallingIdentity(); 8661 try { 8662 mWindowManager.resizeStack(stackBoxId, bounds); 8663 } finally { 8664 Binder.restoreCallingIdentity(ident); 8665 } 8666 } 8667 8668 @Override 8669 public List<StackInfo> getAllStackInfos() { 8670 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8671 "getAllStackInfos()"); 8672 long ident = Binder.clearCallingIdentity(); 8673 try { 8674 synchronized (this) { 8675 return mStackSupervisor.getAllStackInfosLocked(); 8676 } 8677 } finally { 8678 Binder.restoreCallingIdentity(ident); 8679 } 8680 } 8681 8682 @Override 8683 public StackInfo getStackInfo(int stackId) { 8684 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8685 "getStackInfo()"); 8686 long ident = Binder.clearCallingIdentity(); 8687 try { 8688 synchronized (this) { 8689 return mStackSupervisor.getStackInfoLocked(stackId); 8690 } 8691 } finally { 8692 Binder.restoreCallingIdentity(ident); 8693 } 8694 } 8695 8696 @Override 8697 public boolean isInHomeStack(int taskId) { 8698 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8699 "getStackInfo()"); 8700 long ident = Binder.clearCallingIdentity(); 8701 try { 8702 synchronized (this) { 8703 TaskRecord tr = taskForIdLocked(taskId); 8704 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8705 } 8706 } finally { 8707 Binder.restoreCallingIdentity(ident); 8708 } 8709 } 8710 8711 @Override 8712 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8713 synchronized(this) { 8714 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8715 } 8716 } 8717 8718 private boolean isLockTaskAuthorized(String pkg) { 8719 final DevicePolicyManager dpm = (DevicePolicyManager) 8720 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8721 try { 8722 int uid = mContext.getPackageManager().getPackageUid(pkg, 8723 Binder.getCallingUserHandle().getIdentifier()); 8724 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8725 } catch (NameNotFoundException e) { 8726 return false; 8727 } 8728 } 8729 8730 void startLockTaskMode(TaskRecord task) { 8731 final String pkg; 8732 synchronized (this) { 8733 pkg = task.intent.getComponent().getPackageName(); 8734 } 8735 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8736 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8737 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8738 StatusBarManagerInternal.class); 8739 if (statusBarManager != null) { 8740 statusBarManager.showScreenPinningRequest(); 8741 } 8742 return; 8743 } 8744 long ident = Binder.clearCallingIdentity(); 8745 try { 8746 synchronized (this) { 8747 // Since we lost lock on task, make sure it is still there. 8748 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8749 if (task != null) { 8750 if (!isSystemInitiated 8751 && ((mStackSupervisor.getFocusedStack() == null) 8752 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8753 throw new IllegalArgumentException("Invalid task, not in foreground"); 8754 } 8755 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8756 } 8757 } 8758 } finally { 8759 Binder.restoreCallingIdentity(ident); 8760 } 8761 } 8762 8763 @Override 8764 public void startLockTaskMode(int taskId) { 8765 final TaskRecord task; 8766 long ident = Binder.clearCallingIdentity(); 8767 try { 8768 synchronized (this) { 8769 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8770 } 8771 } finally { 8772 Binder.restoreCallingIdentity(ident); 8773 } 8774 if (task != null) { 8775 startLockTaskMode(task); 8776 } 8777 } 8778 8779 @Override 8780 public void startLockTaskMode(IBinder token) { 8781 final TaskRecord task; 8782 long ident = Binder.clearCallingIdentity(); 8783 try { 8784 synchronized (this) { 8785 final ActivityRecord r = ActivityRecord.forToken(token); 8786 if (r == null) { 8787 return; 8788 } 8789 task = r.task; 8790 } 8791 } finally { 8792 Binder.restoreCallingIdentity(ident); 8793 } 8794 if (task != null) { 8795 startLockTaskMode(task); 8796 } 8797 } 8798 8799 @Override 8800 public void startLockTaskModeOnCurrent() throws RemoteException { 8801 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8802 "startLockTaskModeOnCurrent"); 8803 long ident = Binder.clearCallingIdentity(); 8804 try { 8805 ActivityRecord r = null; 8806 synchronized (this) { 8807 r = mStackSupervisor.topRunningActivityLocked(); 8808 } 8809 startLockTaskMode(r.task); 8810 } finally { 8811 Binder.restoreCallingIdentity(ident); 8812 } 8813 } 8814 8815 @Override 8816 public void stopLockTaskMode() { 8817 // Verify that the user matches the package of the intent for the TaskRecord 8818 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8819 // and stopLockTaskMode. 8820 final int callingUid = Binder.getCallingUid(); 8821 if (callingUid != Process.SYSTEM_UID) { 8822 try { 8823 String pkg = 8824 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8825 int uid = mContext.getPackageManager().getPackageUid(pkg, 8826 Binder.getCallingUserHandle().getIdentifier()); 8827 if (uid != callingUid) { 8828 throw new SecurityException("Invalid uid, expected " + uid); 8829 } 8830 } catch (NameNotFoundException e) { 8831 Log.d(TAG, "stopLockTaskMode " + e); 8832 return; 8833 } 8834 } 8835 long ident = Binder.clearCallingIdentity(); 8836 try { 8837 Log.d(TAG, "stopLockTaskMode"); 8838 // Stop lock task 8839 synchronized (this) { 8840 mStackSupervisor.setLockTaskModeLocked(null, false); 8841 } 8842 } finally { 8843 Binder.restoreCallingIdentity(ident); 8844 } 8845 } 8846 8847 @Override 8848 public void stopLockTaskModeOnCurrent() throws RemoteException { 8849 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8850 "stopLockTaskModeOnCurrent"); 8851 long ident = Binder.clearCallingIdentity(); 8852 try { 8853 stopLockTaskMode(); 8854 } finally { 8855 Binder.restoreCallingIdentity(ident); 8856 } 8857 } 8858 8859 @Override 8860 public boolean isInLockTaskMode() { 8861 synchronized (this) { 8862 return mStackSupervisor.isInLockTaskMode(); 8863 } 8864 } 8865 8866 // ========================================================= 8867 // CONTENT PROVIDERS 8868 // ========================================================= 8869 8870 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8871 List<ProviderInfo> providers = null; 8872 try { 8873 providers = AppGlobals.getPackageManager(). 8874 queryContentProviders(app.processName, app.uid, 8875 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8876 } catch (RemoteException ex) { 8877 } 8878 if (DEBUG_MU) 8879 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8880 int userId = app.userId; 8881 if (providers != null) { 8882 int N = providers.size(); 8883 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8884 for (int i=0; i<N; i++) { 8885 ProviderInfo cpi = 8886 (ProviderInfo)providers.get(i); 8887 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8888 cpi.name, cpi.flags); 8889 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8890 // This is a singleton provider, but a user besides the 8891 // default user is asking to initialize a process it runs 8892 // in... well, no, it doesn't actually run in this process, 8893 // it runs in the process of the default user. Get rid of it. 8894 providers.remove(i); 8895 N--; 8896 i--; 8897 continue; 8898 } 8899 8900 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8901 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8902 if (cpr == null) { 8903 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8904 mProviderMap.putProviderByClass(comp, cpr); 8905 } 8906 if (DEBUG_MU) 8907 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8908 app.pubProviders.put(cpi.name, cpr); 8909 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8910 // Don't add this if it is a platform component that is marked 8911 // to run in multiple processes, because this is actually 8912 // part of the framework so doesn't make sense to track as a 8913 // separate apk in the process. 8914 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8915 mProcessStats); 8916 } 8917 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8918 } 8919 } 8920 return providers; 8921 } 8922 8923 /** 8924 * Check if {@link ProcessRecord} has a possible chance at accessing the 8925 * given {@link ProviderInfo}. Final permission checking is always done 8926 * in {@link ContentProvider}. 8927 */ 8928 private final String checkContentProviderPermissionLocked( 8929 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8930 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8931 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8932 boolean checkedGrants = false; 8933 if (checkUser) { 8934 // Looking for cross-user grants before enforcing the typical cross-users permissions 8935 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8936 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8937 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8938 return null; 8939 } 8940 checkedGrants = true; 8941 } 8942 userId = handleIncomingUser(callingPid, callingUid, userId, 8943 false, ALLOW_NON_FULL, 8944 "checkContentProviderPermissionLocked " + cpi.authority, null); 8945 if (userId != tmpTargetUserId) { 8946 // When we actually went to determine the final targer user ID, this ended 8947 // up different than our initial check for the authority. This is because 8948 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8949 // SELF. So we need to re-check the grants again. 8950 checkedGrants = false; 8951 } 8952 } 8953 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8954 cpi.applicationInfo.uid, cpi.exported) 8955 == PackageManager.PERMISSION_GRANTED) { 8956 return null; 8957 } 8958 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8959 cpi.applicationInfo.uid, cpi.exported) 8960 == PackageManager.PERMISSION_GRANTED) { 8961 return null; 8962 } 8963 8964 PathPermission[] pps = cpi.pathPermissions; 8965 if (pps != null) { 8966 int i = pps.length; 8967 while (i > 0) { 8968 i--; 8969 PathPermission pp = pps[i]; 8970 String pprperm = pp.getReadPermission(); 8971 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8972 cpi.applicationInfo.uid, cpi.exported) 8973 == PackageManager.PERMISSION_GRANTED) { 8974 return null; 8975 } 8976 String ppwperm = pp.getWritePermission(); 8977 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8978 cpi.applicationInfo.uid, cpi.exported) 8979 == PackageManager.PERMISSION_GRANTED) { 8980 return null; 8981 } 8982 } 8983 } 8984 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8985 return null; 8986 } 8987 8988 String msg; 8989 if (!cpi.exported) { 8990 msg = "Permission Denial: opening provider " + cpi.name 8991 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8992 + ", uid=" + callingUid + ") that is not exported from uid " 8993 + cpi.applicationInfo.uid; 8994 } else { 8995 msg = "Permission Denial: opening provider " + cpi.name 8996 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8997 + ", uid=" + callingUid + ") requires " 8998 + cpi.readPermission + " or " + cpi.writePermission; 8999 } 9000 Slog.w(TAG, msg); 9001 return msg; 9002 } 9003 9004 /** 9005 * Returns if the ContentProvider has granted a uri to callingUid 9006 */ 9007 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9008 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9009 if (perms != null) { 9010 for (int i=perms.size()-1; i>=0; i--) { 9011 GrantUri grantUri = perms.keyAt(i); 9012 if (grantUri.sourceUserId == userId || !checkUser) { 9013 if (matchesProvider(grantUri.uri, cpi)) { 9014 return true; 9015 } 9016 } 9017 } 9018 } 9019 return false; 9020 } 9021 9022 /** 9023 * Returns true if the uri authority is one of the authorities specified in the provider. 9024 */ 9025 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9026 String uriAuth = uri.getAuthority(); 9027 String cpiAuth = cpi.authority; 9028 if (cpiAuth.indexOf(';') == -1) { 9029 return cpiAuth.equals(uriAuth); 9030 } 9031 String[] cpiAuths = cpiAuth.split(";"); 9032 int length = cpiAuths.length; 9033 for (int i = 0; i < length; i++) { 9034 if (cpiAuths[i].equals(uriAuth)) return true; 9035 } 9036 return false; 9037 } 9038 9039 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9040 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9041 if (r != null) { 9042 for (int i=0; i<r.conProviders.size(); i++) { 9043 ContentProviderConnection conn = r.conProviders.get(i); 9044 if (conn.provider == cpr) { 9045 if (DEBUG_PROVIDER) Slog.v(TAG, 9046 "Adding provider requested by " 9047 + r.processName + " from process " 9048 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9049 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9050 if (stable) { 9051 conn.stableCount++; 9052 conn.numStableIncs++; 9053 } else { 9054 conn.unstableCount++; 9055 conn.numUnstableIncs++; 9056 } 9057 return conn; 9058 } 9059 } 9060 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9061 if (stable) { 9062 conn.stableCount = 1; 9063 conn.numStableIncs = 1; 9064 } else { 9065 conn.unstableCount = 1; 9066 conn.numUnstableIncs = 1; 9067 } 9068 cpr.connections.add(conn); 9069 r.conProviders.add(conn); 9070 return conn; 9071 } 9072 cpr.addExternalProcessHandleLocked(externalProcessToken); 9073 return null; 9074 } 9075 9076 boolean decProviderCountLocked(ContentProviderConnection conn, 9077 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9078 if (conn != null) { 9079 cpr = conn.provider; 9080 if (DEBUG_PROVIDER) Slog.v(TAG, 9081 "Removing provider requested by " 9082 + conn.client.processName + " from process " 9083 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9084 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9085 if (stable) { 9086 conn.stableCount--; 9087 } else { 9088 conn.unstableCount--; 9089 } 9090 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9091 cpr.connections.remove(conn); 9092 conn.client.conProviders.remove(conn); 9093 return true; 9094 } 9095 return false; 9096 } 9097 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9098 return false; 9099 } 9100 9101 private void checkTime(long startTime, String where) { 9102 long now = SystemClock.elapsedRealtime(); 9103 if ((now-startTime) > 1000) { 9104 // If we are taking more than a second, log about it. 9105 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9106 } 9107 } 9108 9109 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9110 String name, IBinder token, boolean stable, int userId) { 9111 ContentProviderRecord cpr; 9112 ContentProviderConnection conn = null; 9113 ProviderInfo cpi = null; 9114 9115 synchronized(this) { 9116 long startTime = SystemClock.elapsedRealtime(); 9117 9118 ProcessRecord r = null; 9119 if (caller != null) { 9120 r = getRecordForAppLocked(caller); 9121 if (r == null) { 9122 throw new SecurityException( 9123 "Unable to find app for caller " + caller 9124 + " (pid=" + Binder.getCallingPid() 9125 + ") when getting content provider " + name); 9126 } 9127 } 9128 9129 boolean checkCrossUser = true; 9130 9131 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9132 9133 // First check if this content provider has been published... 9134 cpr = mProviderMap.getProviderByName(name, userId); 9135 // If that didn't work, check if it exists for user 0 and then 9136 // verify that it's a singleton provider before using it. 9137 if (cpr == null && userId != UserHandle.USER_OWNER) { 9138 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9139 if (cpr != null) { 9140 cpi = cpr.info; 9141 if (isSingleton(cpi.processName, cpi.applicationInfo, 9142 cpi.name, cpi.flags) 9143 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9144 userId = UserHandle.USER_OWNER; 9145 checkCrossUser = false; 9146 } else { 9147 cpr = null; 9148 cpi = null; 9149 } 9150 } 9151 } 9152 9153 boolean providerRunning = cpr != null; 9154 if (providerRunning) { 9155 cpi = cpr.info; 9156 String msg; 9157 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9158 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9159 != null) { 9160 throw new SecurityException(msg); 9161 } 9162 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9163 9164 if (r != null && cpr.canRunHere(r)) { 9165 // This provider has been published or is in the process 9166 // of being published... but it is also allowed to run 9167 // in the caller's process, so don't make a connection 9168 // and just let the caller instantiate its own instance. 9169 ContentProviderHolder holder = cpr.newHolder(null); 9170 // don't give caller the provider object, it needs 9171 // to make its own. 9172 holder.provider = null; 9173 return holder; 9174 } 9175 9176 final long origId = Binder.clearCallingIdentity(); 9177 9178 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9179 9180 // In this case the provider instance already exists, so we can 9181 // return it right away. 9182 conn = incProviderCountLocked(r, cpr, token, stable); 9183 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9184 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9185 // If this is a perceptible app accessing the provider, 9186 // make sure to count it as being accessed and thus 9187 // back up on the LRU list. This is good because 9188 // content providers are often expensive to start. 9189 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9190 updateLruProcessLocked(cpr.proc, false, null); 9191 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9192 } 9193 } 9194 9195 if (cpr.proc != null) { 9196 if (false) { 9197 if (cpr.name.flattenToShortString().equals( 9198 "com.android.providers.calendar/.CalendarProvider2")) { 9199 Slog.v(TAG, "****************** KILLING " 9200 + cpr.name.flattenToShortString()); 9201 Process.killProcess(cpr.proc.pid); 9202 } 9203 } 9204 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9205 boolean success = updateOomAdjLocked(cpr.proc); 9206 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9207 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9208 // NOTE: there is still a race here where a signal could be 9209 // pending on the process even though we managed to update its 9210 // adj level. Not sure what to do about this, but at least 9211 // the race is now smaller. 9212 if (!success) { 9213 // Uh oh... it looks like the provider's process 9214 // has been killed on us. We need to wait for a new 9215 // process to be started, and make sure its death 9216 // doesn't kill our process. 9217 Slog.i(TAG, 9218 "Existing provider " + cpr.name.flattenToShortString() 9219 + " is crashing; detaching " + r); 9220 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9221 checkTime(startTime, "getContentProviderImpl: before appDied"); 9222 appDiedLocked(cpr.proc); 9223 checkTime(startTime, "getContentProviderImpl: after appDied"); 9224 if (!lastRef) { 9225 // This wasn't the last ref our process had on 9226 // the provider... we have now been killed, bail. 9227 return null; 9228 } 9229 providerRunning = false; 9230 conn = null; 9231 } 9232 } 9233 9234 Binder.restoreCallingIdentity(origId); 9235 } 9236 9237 boolean singleton; 9238 if (!providerRunning) { 9239 try { 9240 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9241 cpi = AppGlobals.getPackageManager(). 9242 resolveContentProvider(name, 9243 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9244 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9245 } catch (RemoteException ex) { 9246 } 9247 if (cpi == null) { 9248 return null; 9249 } 9250 // If the provider is a singleton AND 9251 // (it's a call within the same user || the provider is a 9252 // privileged app) 9253 // Then allow connecting to the singleton provider 9254 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9255 cpi.name, cpi.flags) 9256 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9257 if (singleton) { 9258 userId = UserHandle.USER_OWNER; 9259 } 9260 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9261 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9262 9263 String msg; 9264 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9265 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9266 != null) { 9267 throw new SecurityException(msg); 9268 } 9269 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9270 9271 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9272 && !cpi.processName.equals("system")) { 9273 // If this content provider does not run in the system 9274 // process, and the system is not yet ready to run other 9275 // processes, then fail fast instead of hanging. 9276 throw new IllegalArgumentException( 9277 "Attempt to launch content provider before system ready"); 9278 } 9279 9280 // Make sure that the user who owns this provider is started. If not, 9281 // we don't want to allow it to run. 9282 if (mStartedUsers.get(userId) == null) { 9283 Slog.w(TAG, "Unable to launch app " 9284 + cpi.applicationInfo.packageName + "/" 9285 + cpi.applicationInfo.uid + " for provider " 9286 + name + ": user " + userId + " is stopped"); 9287 return null; 9288 } 9289 9290 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9291 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9292 cpr = mProviderMap.getProviderByClass(comp, userId); 9293 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9294 final boolean firstClass = cpr == null; 9295 if (firstClass) { 9296 final long ident = Binder.clearCallingIdentity(); 9297 try { 9298 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9299 ApplicationInfo ai = 9300 AppGlobals.getPackageManager(). 9301 getApplicationInfo( 9302 cpi.applicationInfo.packageName, 9303 STOCK_PM_FLAGS, userId); 9304 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9305 if (ai == null) { 9306 Slog.w(TAG, "No package info for content provider " 9307 + cpi.name); 9308 return null; 9309 } 9310 ai = getAppInfoForUser(ai, userId); 9311 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9312 } catch (RemoteException ex) { 9313 // pm is in same process, this will never happen. 9314 } finally { 9315 Binder.restoreCallingIdentity(ident); 9316 } 9317 } 9318 9319 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9320 9321 if (r != null && cpr.canRunHere(r)) { 9322 // If this is a multiprocess provider, then just return its 9323 // info and allow the caller to instantiate it. Only do 9324 // this if the provider is the same user as the caller's 9325 // process, or can run as root (so can be in any process). 9326 return cpr.newHolder(null); 9327 } 9328 9329 if (DEBUG_PROVIDER) { 9330 RuntimeException e = new RuntimeException("here"); 9331 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9332 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9333 } 9334 9335 // This is single process, and our app is now connecting to it. 9336 // See if we are already in the process of launching this 9337 // provider. 9338 final int N = mLaunchingProviders.size(); 9339 int i; 9340 for (i=0; i<N; i++) { 9341 if (mLaunchingProviders.get(i) == cpr) { 9342 break; 9343 } 9344 } 9345 9346 // If the provider is not already being launched, then get it 9347 // started. 9348 if (i >= N) { 9349 final long origId = Binder.clearCallingIdentity(); 9350 9351 try { 9352 // Content provider is now in use, its package can't be stopped. 9353 try { 9354 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9355 AppGlobals.getPackageManager().setPackageStoppedState( 9356 cpr.appInfo.packageName, false, userId); 9357 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9358 } catch (RemoteException e) { 9359 } catch (IllegalArgumentException e) { 9360 Slog.w(TAG, "Failed trying to unstop package " 9361 + cpr.appInfo.packageName + ": " + e); 9362 } 9363 9364 // Use existing process if already started 9365 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9366 ProcessRecord proc = getProcessRecordLocked( 9367 cpi.processName, cpr.appInfo.uid, false); 9368 if (proc != null && proc.thread != null) { 9369 if (DEBUG_PROVIDER) { 9370 Slog.d(TAG, "Installing in existing process " + proc); 9371 } 9372 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9373 proc.pubProviders.put(cpi.name, cpr); 9374 try { 9375 proc.thread.scheduleInstallProvider(cpi); 9376 } catch (RemoteException e) { 9377 } 9378 } else { 9379 checkTime(startTime, "getContentProviderImpl: before start process"); 9380 proc = startProcessLocked(cpi.processName, 9381 cpr.appInfo, false, 0, "content provider", 9382 new ComponentName(cpi.applicationInfo.packageName, 9383 cpi.name), false, false, false); 9384 checkTime(startTime, "getContentProviderImpl: after start process"); 9385 if (proc == null) { 9386 Slog.w(TAG, "Unable to launch app " 9387 + cpi.applicationInfo.packageName + "/" 9388 + cpi.applicationInfo.uid + " for provider " 9389 + name + ": process is bad"); 9390 return null; 9391 } 9392 } 9393 cpr.launchingApp = proc; 9394 mLaunchingProviders.add(cpr); 9395 } finally { 9396 Binder.restoreCallingIdentity(origId); 9397 } 9398 } 9399 9400 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9401 9402 // Make sure the provider is published (the same provider class 9403 // may be published under multiple names). 9404 if (firstClass) { 9405 mProviderMap.putProviderByClass(comp, cpr); 9406 } 9407 9408 mProviderMap.putProviderByName(name, cpr); 9409 conn = incProviderCountLocked(r, cpr, token, stable); 9410 if (conn != null) { 9411 conn.waiting = true; 9412 } 9413 } 9414 checkTime(startTime, "getContentProviderImpl: done!"); 9415 } 9416 9417 // Wait for the provider to be published... 9418 synchronized (cpr) { 9419 while (cpr.provider == null) { 9420 if (cpr.launchingApp == null) { 9421 Slog.w(TAG, "Unable to launch app " 9422 + cpi.applicationInfo.packageName + "/" 9423 + cpi.applicationInfo.uid + " for provider " 9424 + name + ": launching app became null"); 9425 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9426 UserHandle.getUserId(cpi.applicationInfo.uid), 9427 cpi.applicationInfo.packageName, 9428 cpi.applicationInfo.uid, name); 9429 return null; 9430 } 9431 try { 9432 if (DEBUG_MU) { 9433 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9434 + cpr.launchingApp); 9435 } 9436 if (conn != null) { 9437 conn.waiting = true; 9438 } 9439 cpr.wait(); 9440 } catch (InterruptedException ex) { 9441 } finally { 9442 if (conn != null) { 9443 conn.waiting = false; 9444 } 9445 } 9446 } 9447 } 9448 return cpr != null ? cpr.newHolder(conn) : null; 9449 } 9450 9451 @Override 9452 public final ContentProviderHolder getContentProvider( 9453 IApplicationThread caller, String name, int userId, boolean stable) { 9454 enforceNotIsolatedCaller("getContentProvider"); 9455 if (caller == null) { 9456 String msg = "null IApplicationThread when getting content provider " 9457 + name; 9458 Slog.w(TAG, msg); 9459 throw new SecurityException(msg); 9460 } 9461 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9462 // with cross-user grant. 9463 return getContentProviderImpl(caller, name, null, stable, userId); 9464 } 9465 9466 public ContentProviderHolder getContentProviderExternal( 9467 String name, int userId, IBinder token) { 9468 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9469 "Do not have permission in call getContentProviderExternal()"); 9470 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9471 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9472 return getContentProviderExternalUnchecked(name, token, userId); 9473 } 9474 9475 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9476 IBinder token, int userId) { 9477 return getContentProviderImpl(null, name, token, true, userId); 9478 } 9479 9480 /** 9481 * Drop a content provider from a ProcessRecord's bookkeeping 9482 */ 9483 public void removeContentProvider(IBinder connection, boolean stable) { 9484 enforceNotIsolatedCaller("removeContentProvider"); 9485 long ident = Binder.clearCallingIdentity(); 9486 try { 9487 synchronized (this) { 9488 ContentProviderConnection conn; 9489 try { 9490 conn = (ContentProviderConnection)connection; 9491 } catch (ClassCastException e) { 9492 String msg ="removeContentProvider: " + connection 9493 + " not a ContentProviderConnection"; 9494 Slog.w(TAG, msg); 9495 throw new IllegalArgumentException(msg); 9496 } 9497 if (conn == null) { 9498 throw new NullPointerException("connection is null"); 9499 } 9500 if (decProviderCountLocked(conn, null, null, stable)) { 9501 updateOomAdjLocked(); 9502 } 9503 } 9504 } finally { 9505 Binder.restoreCallingIdentity(ident); 9506 } 9507 } 9508 9509 public void removeContentProviderExternal(String name, IBinder token) { 9510 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9511 "Do not have permission in call removeContentProviderExternal()"); 9512 int userId = UserHandle.getCallingUserId(); 9513 long ident = Binder.clearCallingIdentity(); 9514 try { 9515 removeContentProviderExternalUnchecked(name, token, userId); 9516 } finally { 9517 Binder.restoreCallingIdentity(ident); 9518 } 9519 } 9520 9521 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9522 synchronized (this) { 9523 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9524 if(cpr == null) { 9525 //remove from mProvidersByClass 9526 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9527 return; 9528 } 9529 9530 //update content provider record entry info 9531 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9532 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9533 if (localCpr.hasExternalProcessHandles()) { 9534 if (localCpr.removeExternalProcessHandleLocked(token)) { 9535 updateOomAdjLocked(); 9536 } else { 9537 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9538 + " with no external reference for token: " 9539 + token + "."); 9540 } 9541 } else { 9542 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9543 + " with no external references."); 9544 } 9545 } 9546 } 9547 9548 public final void publishContentProviders(IApplicationThread caller, 9549 List<ContentProviderHolder> providers) { 9550 if (providers == null) { 9551 return; 9552 } 9553 9554 enforceNotIsolatedCaller("publishContentProviders"); 9555 synchronized (this) { 9556 final ProcessRecord r = getRecordForAppLocked(caller); 9557 if (DEBUG_MU) 9558 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9559 if (r == null) { 9560 throw new SecurityException( 9561 "Unable to find app for caller " + caller 9562 + " (pid=" + Binder.getCallingPid() 9563 + ") when publishing content providers"); 9564 } 9565 9566 final long origId = Binder.clearCallingIdentity(); 9567 9568 final int N = providers.size(); 9569 for (int i=0; i<N; i++) { 9570 ContentProviderHolder src = providers.get(i); 9571 if (src == null || src.info == null || src.provider == null) { 9572 continue; 9573 } 9574 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9575 if (DEBUG_MU) 9576 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9577 if (dst != null) { 9578 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9579 mProviderMap.putProviderByClass(comp, dst); 9580 String names[] = dst.info.authority.split(";"); 9581 for (int j = 0; j < names.length; j++) { 9582 mProviderMap.putProviderByName(names[j], dst); 9583 } 9584 9585 int NL = mLaunchingProviders.size(); 9586 int j; 9587 for (j=0; j<NL; j++) { 9588 if (mLaunchingProviders.get(j) == dst) { 9589 mLaunchingProviders.remove(j); 9590 j--; 9591 NL--; 9592 } 9593 } 9594 synchronized (dst) { 9595 dst.provider = src.provider; 9596 dst.proc = r; 9597 dst.notifyAll(); 9598 } 9599 updateOomAdjLocked(r); 9600 } 9601 } 9602 9603 Binder.restoreCallingIdentity(origId); 9604 } 9605 } 9606 9607 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9608 ContentProviderConnection conn; 9609 try { 9610 conn = (ContentProviderConnection)connection; 9611 } catch (ClassCastException e) { 9612 String msg ="refContentProvider: " + connection 9613 + " not a ContentProviderConnection"; 9614 Slog.w(TAG, msg); 9615 throw new IllegalArgumentException(msg); 9616 } 9617 if (conn == null) { 9618 throw new NullPointerException("connection is null"); 9619 } 9620 9621 synchronized (this) { 9622 if (stable > 0) { 9623 conn.numStableIncs += stable; 9624 } 9625 stable = conn.stableCount + stable; 9626 if (stable < 0) { 9627 throw new IllegalStateException("stableCount < 0: " + stable); 9628 } 9629 9630 if (unstable > 0) { 9631 conn.numUnstableIncs += unstable; 9632 } 9633 unstable = conn.unstableCount + unstable; 9634 if (unstable < 0) { 9635 throw new IllegalStateException("unstableCount < 0: " + unstable); 9636 } 9637 9638 if ((stable+unstable) <= 0) { 9639 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9640 + stable + " unstable=" + unstable); 9641 } 9642 conn.stableCount = stable; 9643 conn.unstableCount = unstable; 9644 return !conn.dead; 9645 } 9646 } 9647 9648 public void unstableProviderDied(IBinder connection) { 9649 ContentProviderConnection conn; 9650 try { 9651 conn = (ContentProviderConnection)connection; 9652 } catch (ClassCastException e) { 9653 String msg ="refContentProvider: " + connection 9654 + " not a ContentProviderConnection"; 9655 Slog.w(TAG, msg); 9656 throw new IllegalArgumentException(msg); 9657 } 9658 if (conn == null) { 9659 throw new NullPointerException("connection is null"); 9660 } 9661 9662 // Safely retrieve the content provider associated with the connection. 9663 IContentProvider provider; 9664 synchronized (this) { 9665 provider = conn.provider.provider; 9666 } 9667 9668 if (provider == null) { 9669 // Um, yeah, we're way ahead of you. 9670 return; 9671 } 9672 9673 // Make sure the caller is being honest with us. 9674 if (provider.asBinder().pingBinder()) { 9675 // Er, no, still looks good to us. 9676 synchronized (this) { 9677 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9678 + " says " + conn + " died, but we don't agree"); 9679 return; 9680 } 9681 } 9682 9683 // Well look at that! It's dead! 9684 synchronized (this) { 9685 if (conn.provider.provider != provider) { 9686 // But something changed... good enough. 9687 return; 9688 } 9689 9690 ProcessRecord proc = conn.provider.proc; 9691 if (proc == null || proc.thread == null) { 9692 // Seems like the process is already cleaned up. 9693 return; 9694 } 9695 9696 // As far as we're concerned, this is just like receiving a 9697 // death notification... just a bit prematurely. 9698 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9699 + ") early provider death"); 9700 final long ident = Binder.clearCallingIdentity(); 9701 try { 9702 appDiedLocked(proc); 9703 } finally { 9704 Binder.restoreCallingIdentity(ident); 9705 } 9706 } 9707 } 9708 9709 @Override 9710 public void appNotRespondingViaProvider(IBinder connection) { 9711 enforceCallingPermission( 9712 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9713 9714 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9715 if (conn == null) { 9716 Slog.w(TAG, "ContentProviderConnection is null"); 9717 return; 9718 } 9719 9720 final ProcessRecord host = conn.provider.proc; 9721 if (host == null) { 9722 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9723 return; 9724 } 9725 9726 final long token = Binder.clearCallingIdentity(); 9727 try { 9728 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9729 } finally { 9730 Binder.restoreCallingIdentity(token); 9731 } 9732 } 9733 9734 public final void installSystemProviders() { 9735 List<ProviderInfo> providers; 9736 synchronized (this) { 9737 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9738 providers = generateApplicationProvidersLocked(app); 9739 if (providers != null) { 9740 for (int i=providers.size()-1; i>=0; i--) { 9741 ProviderInfo pi = (ProviderInfo)providers.get(i); 9742 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9743 Slog.w(TAG, "Not installing system proc provider " + pi.name 9744 + ": not system .apk"); 9745 providers.remove(i); 9746 } 9747 } 9748 } 9749 } 9750 if (providers != null) { 9751 mSystemThread.installSystemProviders(providers); 9752 } 9753 9754 mCoreSettingsObserver = new CoreSettingsObserver(this); 9755 9756 //mUsageStatsService.monitorPackages(); 9757 } 9758 9759 /** 9760 * Allows apps to retrieve the MIME type of a URI. 9761 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9762 * users, then it does not need permission to access the ContentProvider. 9763 * Either, it needs cross-user uri grants. 9764 * 9765 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9766 * 9767 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9768 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9769 */ 9770 public String getProviderMimeType(Uri uri, int userId) { 9771 enforceNotIsolatedCaller("getProviderMimeType"); 9772 final String name = uri.getAuthority(); 9773 int callingUid = Binder.getCallingUid(); 9774 int callingPid = Binder.getCallingPid(); 9775 long ident = 0; 9776 boolean clearedIdentity = false; 9777 userId = unsafeConvertIncomingUser(userId); 9778 if (canClearIdentity(callingPid, callingUid, userId)) { 9779 clearedIdentity = true; 9780 ident = Binder.clearCallingIdentity(); 9781 } 9782 ContentProviderHolder holder = null; 9783 try { 9784 holder = getContentProviderExternalUnchecked(name, null, userId); 9785 if (holder != null) { 9786 return holder.provider.getType(uri); 9787 } 9788 } catch (RemoteException e) { 9789 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9790 return null; 9791 } finally { 9792 // We need to clear the identity to call removeContentProviderExternalUnchecked 9793 if (!clearedIdentity) { 9794 ident = Binder.clearCallingIdentity(); 9795 } 9796 try { 9797 if (holder != null) { 9798 removeContentProviderExternalUnchecked(name, null, userId); 9799 } 9800 } finally { 9801 Binder.restoreCallingIdentity(ident); 9802 } 9803 } 9804 9805 return null; 9806 } 9807 9808 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9809 if (UserHandle.getUserId(callingUid) == userId) { 9810 return true; 9811 } 9812 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9813 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9814 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9815 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9816 return true; 9817 } 9818 return false; 9819 } 9820 9821 // ========================================================= 9822 // GLOBAL MANAGEMENT 9823 // ========================================================= 9824 9825 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9826 boolean isolated, int isolatedUid) { 9827 String proc = customProcess != null ? customProcess : info.processName; 9828 BatteryStatsImpl.Uid.Proc ps = null; 9829 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9830 int uid = info.uid; 9831 if (isolated) { 9832 if (isolatedUid == 0) { 9833 int userId = UserHandle.getUserId(uid); 9834 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9835 while (true) { 9836 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9837 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9838 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9839 } 9840 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9841 mNextIsolatedProcessUid++; 9842 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9843 // No process for this uid, use it. 9844 break; 9845 } 9846 stepsLeft--; 9847 if (stepsLeft <= 0) { 9848 return null; 9849 } 9850 } 9851 } else { 9852 // Special case for startIsolatedProcess (internal only), where 9853 // the uid of the isolated process is specified by the caller. 9854 uid = isolatedUid; 9855 } 9856 } 9857 return new ProcessRecord(stats, info, proc, uid); 9858 } 9859 9860 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9861 String abiOverride) { 9862 ProcessRecord app; 9863 if (!isolated) { 9864 app = getProcessRecordLocked(info.processName, info.uid, true); 9865 } else { 9866 app = null; 9867 } 9868 9869 if (app == null) { 9870 app = newProcessRecordLocked(info, null, isolated, 0); 9871 mProcessNames.put(info.processName, app.uid, app); 9872 if (isolated) { 9873 mIsolatedProcesses.put(app.uid, app); 9874 } 9875 updateLruProcessLocked(app, false, null); 9876 updateOomAdjLocked(); 9877 } 9878 9879 // This package really, really can not be stopped. 9880 try { 9881 AppGlobals.getPackageManager().setPackageStoppedState( 9882 info.packageName, false, UserHandle.getUserId(app.uid)); 9883 } catch (RemoteException e) { 9884 } catch (IllegalArgumentException e) { 9885 Slog.w(TAG, "Failed trying to unstop package " 9886 + info.packageName + ": " + e); 9887 } 9888 9889 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9890 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9891 app.persistent = true; 9892 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9893 } 9894 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9895 mPersistentStartingProcesses.add(app); 9896 startProcessLocked(app, "added application", app.processName, abiOverride, 9897 null /* entryPoint */, null /* entryPointArgs */); 9898 } 9899 9900 return app; 9901 } 9902 9903 public void unhandledBack() { 9904 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9905 "unhandledBack()"); 9906 9907 synchronized(this) { 9908 final long origId = Binder.clearCallingIdentity(); 9909 try { 9910 getFocusedStack().unhandledBackLocked(); 9911 } finally { 9912 Binder.restoreCallingIdentity(origId); 9913 } 9914 } 9915 } 9916 9917 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9918 enforceNotIsolatedCaller("openContentUri"); 9919 final int userId = UserHandle.getCallingUserId(); 9920 String name = uri.getAuthority(); 9921 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9922 ParcelFileDescriptor pfd = null; 9923 if (cph != null) { 9924 // We record the binder invoker's uid in thread-local storage before 9925 // going to the content provider to open the file. Later, in the code 9926 // that handles all permissions checks, we look for this uid and use 9927 // that rather than the Activity Manager's own uid. The effect is that 9928 // we do the check against the caller's permissions even though it looks 9929 // to the content provider like the Activity Manager itself is making 9930 // the request. 9931 Binder token = new Binder(); 9932 sCallerIdentity.set(new Identity( 9933 token, Binder.getCallingPid(), Binder.getCallingUid())); 9934 try { 9935 pfd = cph.provider.openFile(null, uri, "r", null, token); 9936 } catch (FileNotFoundException e) { 9937 // do nothing; pfd will be returned null 9938 } finally { 9939 // Ensure that whatever happens, we clean up the identity state 9940 sCallerIdentity.remove(); 9941 } 9942 9943 // We've got the fd now, so we're done with the provider. 9944 removeContentProviderExternalUnchecked(name, null, userId); 9945 } else { 9946 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9947 } 9948 return pfd; 9949 } 9950 9951 // Actually is sleeping or shutting down or whatever else in the future 9952 // is an inactive state. 9953 public boolean isSleepingOrShuttingDown() { 9954 return isSleeping() || mShuttingDown; 9955 } 9956 9957 public boolean isSleeping() { 9958 return mSleeping; 9959 } 9960 9961 void onWakefulnessChanged(int wakefulness) { 9962 synchronized(this) { 9963 mWakefulness = wakefulness; 9964 updateSleepIfNeededLocked(); 9965 } 9966 } 9967 9968 void finishRunningVoiceLocked() { 9969 if (mRunningVoice) { 9970 mRunningVoice = false; 9971 updateSleepIfNeededLocked(); 9972 } 9973 } 9974 9975 void updateSleepIfNeededLocked() { 9976 if (mSleeping && !shouldSleepLocked()) { 9977 mSleeping = false; 9978 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9979 } else if (!mSleeping && shouldSleepLocked()) { 9980 mSleeping = true; 9981 mStackSupervisor.goingToSleepLocked(); 9982 9983 // Initialize the wake times of all processes. 9984 checkExcessivePowerUsageLocked(false); 9985 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9986 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9987 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9988 } 9989 } 9990 9991 private boolean shouldSleepLocked() { 9992 // Resume applications while running a voice interactor. 9993 if (mRunningVoice) { 9994 return false; 9995 } 9996 9997 switch (mWakefulness) { 9998 case PowerManagerInternal.WAKEFULNESS_AWAKE: 9999 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10000 // If we're interactive but applications are already paused then defer 10001 // resuming them until the lock screen is hidden. 10002 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10003 case PowerManagerInternal.WAKEFULNESS_DOZING: 10004 // If we're dozing then pause applications whenever the lock screen is shown. 10005 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10006 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10007 default: 10008 // If we're asleep then pause applications unconditionally. 10009 return true; 10010 } 10011 } 10012 10013 /** Pokes the task persister. */ 10014 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10015 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10016 // Never persist the home stack. 10017 return; 10018 } 10019 mTaskPersister.wakeup(task, flush); 10020 } 10021 10022 /** Notifies all listeners when the task stack has changed. */ 10023 void notifyTaskStackChangedLocked() { 10024 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10025 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10026 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10027 } 10028 10029 @Override 10030 public boolean shutdown(int timeout) { 10031 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10032 != PackageManager.PERMISSION_GRANTED) { 10033 throw new SecurityException("Requires permission " 10034 + android.Manifest.permission.SHUTDOWN); 10035 } 10036 10037 boolean timedout = false; 10038 10039 synchronized(this) { 10040 mShuttingDown = true; 10041 updateEventDispatchingLocked(); 10042 timedout = mStackSupervisor.shutdownLocked(timeout); 10043 } 10044 10045 mAppOpsService.shutdown(); 10046 if (mUsageStatsService != null) { 10047 mUsageStatsService.prepareShutdown(); 10048 } 10049 mBatteryStatsService.shutdown(); 10050 synchronized (this) { 10051 mProcessStats.shutdownLocked(); 10052 notifyTaskPersisterLocked(null, true); 10053 } 10054 10055 return timedout; 10056 } 10057 10058 public final void activitySlept(IBinder token) { 10059 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10060 10061 final long origId = Binder.clearCallingIdentity(); 10062 10063 synchronized (this) { 10064 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10065 if (r != null) { 10066 mStackSupervisor.activitySleptLocked(r); 10067 } 10068 } 10069 10070 Binder.restoreCallingIdentity(origId); 10071 } 10072 10073 private String lockScreenShownToString() { 10074 switch (mLockScreenShown) { 10075 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10076 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10077 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10078 default: return "Unknown=" + mLockScreenShown; 10079 } 10080 } 10081 10082 void logLockScreen(String msg) { 10083 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10084 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10085 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10086 + " mSleeping=" + mSleeping); 10087 } 10088 10089 void startRunningVoiceLocked() { 10090 if (!mRunningVoice) { 10091 mRunningVoice = true; 10092 updateSleepIfNeededLocked(); 10093 } 10094 } 10095 10096 private void updateEventDispatchingLocked() { 10097 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10098 } 10099 10100 public void setLockScreenShown(boolean shown) { 10101 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10102 != PackageManager.PERMISSION_GRANTED) { 10103 throw new SecurityException("Requires permission " 10104 + android.Manifest.permission.DEVICE_POWER); 10105 } 10106 10107 synchronized(this) { 10108 long ident = Binder.clearCallingIdentity(); 10109 try { 10110 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10111 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10112 updateSleepIfNeededLocked(); 10113 } finally { 10114 Binder.restoreCallingIdentity(ident); 10115 } 10116 } 10117 } 10118 10119 @Override 10120 public void stopAppSwitches() { 10121 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10122 != PackageManager.PERMISSION_GRANTED) { 10123 throw new SecurityException("Requires permission " 10124 + android.Manifest.permission.STOP_APP_SWITCHES); 10125 } 10126 10127 synchronized(this) { 10128 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10129 + APP_SWITCH_DELAY_TIME; 10130 mDidAppSwitch = false; 10131 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10132 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10133 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10134 } 10135 } 10136 10137 public void resumeAppSwitches() { 10138 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10139 != PackageManager.PERMISSION_GRANTED) { 10140 throw new SecurityException("Requires permission " 10141 + android.Manifest.permission.STOP_APP_SWITCHES); 10142 } 10143 10144 synchronized(this) { 10145 // Note that we don't execute any pending app switches... we will 10146 // let those wait until either the timeout, or the next start 10147 // activity request. 10148 mAppSwitchesAllowedTime = 0; 10149 } 10150 } 10151 10152 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10153 int callingPid, int callingUid, String name) { 10154 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10155 return true; 10156 } 10157 10158 int perm = checkComponentPermission( 10159 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10160 sourceUid, -1, true); 10161 if (perm == PackageManager.PERMISSION_GRANTED) { 10162 return true; 10163 } 10164 10165 // If the actual IPC caller is different from the logical source, then 10166 // also see if they are allowed to control app switches. 10167 if (callingUid != -1 && callingUid != sourceUid) { 10168 perm = checkComponentPermission( 10169 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10170 callingUid, -1, true); 10171 if (perm == PackageManager.PERMISSION_GRANTED) { 10172 return true; 10173 } 10174 } 10175 10176 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10177 return false; 10178 } 10179 10180 public void setDebugApp(String packageName, boolean waitForDebugger, 10181 boolean persistent) { 10182 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10183 "setDebugApp()"); 10184 10185 long ident = Binder.clearCallingIdentity(); 10186 try { 10187 // Note that this is not really thread safe if there are multiple 10188 // callers into it at the same time, but that's not a situation we 10189 // care about. 10190 if (persistent) { 10191 final ContentResolver resolver = mContext.getContentResolver(); 10192 Settings.Global.putString( 10193 resolver, Settings.Global.DEBUG_APP, 10194 packageName); 10195 Settings.Global.putInt( 10196 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10197 waitForDebugger ? 1 : 0); 10198 } 10199 10200 synchronized (this) { 10201 if (!persistent) { 10202 mOrigDebugApp = mDebugApp; 10203 mOrigWaitForDebugger = mWaitForDebugger; 10204 } 10205 mDebugApp = packageName; 10206 mWaitForDebugger = waitForDebugger; 10207 mDebugTransient = !persistent; 10208 if (packageName != null) { 10209 forceStopPackageLocked(packageName, -1, false, false, true, true, 10210 false, UserHandle.USER_ALL, "set debug app"); 10211 } 10212 } 10213 } finally { 10214 Binder.restoreCallingIdentity(ident); 10215 } 10216 } 10217 10218 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10219 synchronized (this) { 10220 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10221 if (!isDebuggable) { 10222 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10223 throw new SecurityException("Process not debuggable: " + app.packageName); 10224 } 10225 } 10226 10227 mOpenGlTraceApp = processName; 10228 } 10229 } 10230 10231 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10232 synchronized (this) { 10233 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10234 if (!isDebuggable) { 10235 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10236 throw new SecurityException("Process not debuggable: " + app.packageName); 10237 } 10238 } 10239 mProfileApp = processName; 10240 mProfileFile = profilerInfo.profileFile; 10241 if (mProfileFd != null) { 10242 try { 10243 mProfileFd.close(); 10244 } catch (IOException e) { 10245 } 10246 mProfileFd = null; 10247 } 10248 mProfileFd = profilerInfo.profileFd; 10249 mSamplingInterval = profilerInfo.samplingInterval; 10250 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10251 mProfileType = 0; 10252 } 10253 } 10254 10255 @Override 10256 public void setAlwaysFinish(boolean enabled) { 10257 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10258 "setAlwaysFinish()"); 10259 10260 Settings.Global.putInt( 10261 mContext.getContentResolver(), 10262 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10263 10264 synchronized (this) { 10265 mAlwaysFinishActivities = enabled; 10266 } 10267 } 10268 10269 @Override 10270 public void setActivityController(IActivityController controller) { 10271 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10272 "setActivityController()"); 10273 synchronized (this) { 10274 mController = controller; 10275 Watchdog.getInstance().setActivityController(controller); 10276 } 10277 } 10278 10279 @Override 10280 public void setUserIsMonkey(boolean userIsMonkey) { 10281 synchronized (this) { 10282 synchronized (mPidsSelfLocked) { 10283 final int callingPid = Binder.getCallingPid(); 10284 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10285 if (precessRecord == null) { 10286 throw new SecurityException("Unknown process: " + callingPid); 10287 } 10288 if (precessRecord.instrumentationUiAutomationConnection == null) { 10289 throw new SecurityException("Only an instrumentation process " 10290 + "with a UiAutomation can call setUserIsMonkey"); 10291 } 10292 } 10293 mUserIsMonkey = userIsMonkey; 10294 } 10295 } 10296 10297 @Override 10298 public boolean isUserAMonkey() { 10299 synchronized (this) { 10300 // If there is a controller also implies the user is a monkey. 10301 return (mUserIsMonkey || mController != null); 10302 } 10303 } 10304 10305 public void requestBugReport() { 10306 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10307 SystemProperties.set("ctl.start", "bugreport"); 10308 } 10309 10310 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10311 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10312 } 10313 10314 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10315 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10316 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10317 } 10318 return KEY_DISPATCHING_TIMEOUT; 10319 } 10320 10321 @Override 10322 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10323 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10324 != PackageManager.PERMISSION_GRANTED) { 10325 throw new SecurityException("Requires permission " 10326 + android.Manifest.permission.FILTER_EVENTS); 10327 } 10328 ProcessRecord proc; 10329 long timeout; 10330 synchronized (this) { 10331 synchronized (mPidsSelfLocked) { 10332 proc = mPidsSelfLocked.get(pid); 10333 } 10334 timeout = getInputDispatchingTimeoutLocked(proc); 10335 } 10336 10337 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10338 return -1; 10339 } 10340 10341 return timeout; 10342 } 10343 10344 /** 10345 * Handle input dispatching timeouts. 10346 * Returns whether input dispatching should be aborted or not. 10347 */ 10348 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10349 final ActivityRecord activity, final ActivityRecord parent, 10350 final boolean aboveSystem, String reason) { 10351 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10352 != PackageManager.PERMISSION_GRANTED) { 10353 throw new SecurityException("Requires permission " 10354 + android.Manifest.permission.FILTER_EVENTS); 10355 } 10356 10357 final String annotation; 10358 if (reason == null) { 10359 annotation = "Input dispatching timed out"; 10360 } else { 10361 annotation = "Input dispatching timed out (" + reason + ")"; 10362 } 10363 10364 if (proc != null) { 10365 synchronized (this) { 10366 if (proc.debugging) { 10367 return false; 10368 } 10369 10370 if (mDidDexOpt) { 10371 // Give more time since we were dexopting. 10372 mDidDexOpt = false; 10373 return false; 10374 } 10375 10376 if (proc.instrumentationClass != null) { 10377 Bundle info = new Bundle(); 10378 info.putString("shortMsg", "keyDispatchingTimedOut"); 10379 info.putString("longMsg", annotation); 10380 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10381 return true; 10382 } 10383 } 10384 mHandler.post(new Runnable() { 10385 @Override 10386 public void run() { 10387 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10388 } 10389 }); 10390 } 10391 10392 return true; 10393 } 10394 10395 public Bundle getAssistContextExtras(int requestType) { 10396 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10397 UserHandle.getCallingUserId()); 10398 if (pae == null) { 10399 return null; 10400 } 10401 synchronized (pae) { 10402 while (!pae.haveResult) { 10403 try { 10404 pae.wait(); 10405 } catch (InterruptedException e) { 10406 } 10407 } 10408 if (pae.result != null) { 10409 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10410 } 10411 } 10412 synchronized (this) { 10413 mPendingAssistExtras.remove(pae); 10414 mHandler.removeCallbacks(pae); 10415 } 10416 return pae.extras; 10417 } 10418 10419 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10420 int userHandle) { 10421 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10422 "getAssistContextExtras()"); 10423 PendingAssistExtras pae; 10424 Bundle extras = new Bundle(); 10425 synchronized (this) { 10426 ActivityRecord activity = getFocusedStack().mResumedActivity; 10427 if (activity == null) { 10428 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10429 return null; 10430 } 10431 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10432 if (activity.app == null || activity.app.thread == null) { 10433 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10434 return null; 10435 } 10436 if (activity.app.pid == Binder.getCallingPid()) { 10437 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10438 return null; 10439 } 10440 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10441 try { 10442 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10443 requestType); 10444 mPendingAssistExtras.add(pae); 10445 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10446 } catch (RemoteException e) { 10447 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10448 return null; 10449 } 10450 return pae; 10451 } 10452 } 10453 10454 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10455 PendingAssistExtras pae = (PendingAssistExtras)token; 10456 synchronized (pae) { 10457 pae.result = extras; 10458 pae.haveResult = true; 10459 pae.notifyAll(); 10460 if (pae.intent == null) { 10461 // Caller is just waiting for the result. 10462 return; 10463 } 10464 } 10465 10466 // We are now ready to launch the assist activity. 10467 synchronized (this) { 10468 boolean exists = mPendingAssistExtras.remove(pae); 10469 mHandler.removeCallbacks(pae); 10470 if (!exists) { 10471 // Timed out. 10472 return; 10473 } 10474 } 10475 pae.intent.replaceExtras(extras); 10476 if (pae.hint != null) { 10477 pae.intent.putExtra(pae.hint, true); 10478 } 10479 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10480 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10481 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10482 closeSystemDialogs("assist"); 10483 try { 10484 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10485 } catch (ActivityNotFoundException e) { 10486 Slog.w(TAG, "No activity to handle assist action.", e); 10487 } 10488 } 10489 10490 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10491 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10492 } 10493 10494 public void registerProcessObserver(IProcessObserver observer) { 10495 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10496 "registerProcessObserver()"); 10497 synchronized (this) { 10498 mProcessObservers.register(observer); 10499 } 10500 } 10501 10502 @Override 10503 public void unregisterProcessObserver(IProcessObserver observer) { 10504 synchronized (this) { 10505 mProcessObservers.unregister(observer); 10506 } 10507 } 10508 10509 @Override 10510 public boolean convertFromTranslucent(IBinder token) { 10511 final long origId = Binder.clearCallingIdentity(); 10512 try { 10513 synchronized (this) { 10514 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10515 if (r == null) { 10516 return false; 10517 } 10518 final boolean translucentChanged = r.changeWindowTranslucency(true); 10519 if (translucentChanged) { 10520 r.task.stack.releaseBackgroundResources(); 10521 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10522 } 10523 mWindowManager.setAppFullscreen(token, true); 10524 return translucentChanged; 10525 } 10526 } finally { 10527 Binder.restoreCallingIdentity(origId); 10528 } 10529 } 10530 10531 @Override 10532 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10533 final long origId = Binder.clearCallingIdentity(); 10534 try { 10535 synchronized (this) { 10536 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10537 if (r == null) { 10538 return false; 10539 } 10540 int index = r.task.mActivities.lastIndexOf(r); 10541 if (index > 0) { 10542 ActivityRecord under = r.task.mActivities.get(index - 1); 10543 under.returningOptions = options; 10544 } 10545 final boolean translucentChanged = r.changeWindowTranslucency(false); 10546 if (translucentChanged) { 10547 r.task.stack.convertToTranslucent(r); 10548 } 10549 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10550 mWindowManager.setAppFullscreen(token, false); 10551 return translucentChanged; 10552 } 10553 } finally { 10554 Binder.restoreCallingIdentity(origId); 10555 } 10556 } 10557 10558 @Override 10559 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10560 final long origId = Binder.clearCallingIdentity(); 10561 try { 10562 synchronized (this) { 10563 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10564 if (r != null) { 10565 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10566 } 10567 } 10568 return false; 10569 } finally { 10570 Binder.restoreCallingIdentity(origId); 10571 } 10572 } 10573 10574 @Override 10575 public boolean isBackgroundVisibleBehind(IBinder token) { 10576 final long origId = Binder.clearCallingIdentity(); 10577 try { 10578 synchronized (this) { 10579 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10580 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10581 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10582 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10583 return visible; 10584 } 10585 } finally { 10586 Binder.restoreCallingIdentity(origId); 10587 } 10588 } 10589 10590 @Override 10591 public ActivityOptions getActivityOptions(IBinder token) { 10592 final long origId = Binder.clearCallingIdentity(); 10593 try { 10594 synchronized (this) { 10595 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10596 if (r != null) { 10597 final ActivityOptions activityOptions = r.pendingOptions; 10598 r.pendingOptions = null; 10599 return activityOptions; 10600 } 10601 return null; 10602 } 10603 } finally { 10604 Binder.restoreCallingIdentity(origId); 10605 } 10606 } 10607 10608 @Override 10609 public void setImmersive(IBinder token, boolean immersive) { 10610 synchronized(this) { 10611 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10612 if (r == null) { 10613 throw new IllegalArgumentException(); 10614 } 10615 r.immersive = immersive; 10616 10617 // update associated state if we're frontmost 10618 if (r == mFocusedActivity) { 10619 if (DEBUG_IMMERSIVE) { 10620 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10621 } 10622 applyUpdateLockStateLocked(r); 10623 } 10624 } 10625 } 10626 10627 @Override 10628 public boolean isImmersive(IBinder token) { 10629 synchronized (this) { 10630 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10631 if (r == null) { 10632 throw new IllegalArgumentException(); 10633 } 10634 return r.immersive; 10635 } 10636 } 10637 10638 public boolean isTopActivityImmersive() { 10639 enforceNotIsolatedCaller("startActivity"); 10640 synchronized (this) { 10641 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10642 return (r != null) ? r.immersive : false; 10643 } 10644 } 10645 10646 @Override 10647 public boolean isTopOfTask(IBinder token) { 10648 synchronized (this) { 10649 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10650 if (r == null) { 10651 throw new IllegalArgumentException(); 10652 } 10653 return r.task.getTopActivity() == r; 10654 } 10655 } 10656 10657 public final void enterSafeMode() { 10658 synchronized(this) { 10659 // It only makes sense to do this before the system is ready 10660 // and started launching other packages. 10661 if (!mSystemReady) { 10662 try { 10663 AppGlobals.getPackageManager().enterSafeMode(); 10664 } catch (RemoteException e) { 10665 } 10666 } 10667 10668 mSafeMode = true; 10669 } 10670 } 10671 10672 public final void showSafeModeOverlay() { 10673 View v = LayoutInflater.from(mContext).inflate( 10674 com.android.internal.R.layout.safe_mode, null); 10675 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10676 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10677 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10678 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10679 lp.gravity = Gravity.BOTTOM | Gravity.START; 10680 lp.format = v.getBackground().getOpacity(); 10681 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10682 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10683 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10684 ((WindowManager)mContext.getSystemService( 10685 Context.WINDOW_SERVICE)).addView(v, lp); 10686 } 10687 10688 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10689 if (!(sender instanceof PendingIntentRecord)) { 10690 return; 10691 } 10692 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10693 synchronized (stats) { 10694 if (mBatteryStatsService.isOnBattery()) { 10695 mBatteryStatsService.enforceCallingPermission(); 10696 PendingIntentRecord rec = (PendingIntentRecord)sender; 10697 int MY_UID = Binder.getCallingUid(); 10698 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10699 BatteryStatsImpl.Uid.Pkg pkg = 10700 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10701 sourcePkg != null ? sourcePkg : rec.key.packageName); 10702 pkg.incWakeupsLocked(); 10703 } 10704 } 10705 } 10706 10707 public boolean killPids(int[] pids, String pReason, boolean secure) { 10708 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10709 throw new SecurityException("killPids only available to the system"); 10710 } 10711 String reason = (pReason == null) ? "Unknown" : pReason; 10712 // XXX Note: don't acquire main activity lock here, because the window 10713 // manager calls in with its locks held. 10714 10715 boolean killed = false; 10716 synchronized (mPidsSelfLocked) { 10717 int[] types = new int[pids.length]; 10718 int worstType = 0; 10719 for (int i=0; i<pids.length; i++) { 10720 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10721 if (proc != null) { 10722 int type = proc.setAdj; 10723 types[i] = type; 10724 if (type > worstType) { 10725 worstType = type; 10726 } 10727 } 10728 } 10729 10730 // If the worst oom_adj is somewhere in the cached proc LRU range, 10731 // then constrain it so we will kill all cached procs. 10732 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10733 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10734 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10735 } 10736 10737 // If this is not a secure call, don't let it kill processes that 10738 // are important. 10739 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10740 worstType = ProcessList.SERVICE_ADJ; 10741 } 10742 10743 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10744 for (int i=0; i<pids.length; i++) { 10745 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10746 if (proc == null) { 10747 continue; 10748 } 10749 int adj = proc.setAdj; 10750 if (adj >= worstType && !proc.killedByAm) { 10751 proc.kill(reason, true); 10752 killed = true; 10753 } 10754 } 10755 } 10756 return killed; 10757 } 10758 10759 @Override 10760 public void killUid(int uid, String reason) { 10761 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10762 throw new SecurityException("killUid only available to the system"); 10763 } 10764 synchronized (this) { 10765 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10766 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10767 reason != null ? reason : "kill uid"); 10768 } 10769 } 10770 10771 @Override 10772 public boolean killProcessesBelowForeground(String reason) { 10773 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10774 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10775 } 10776 10777 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10778 } 10779 10780 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10781 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10782 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10783 } 10784 10785 boolean killed = false; 10786 synchronized (mPidsSelfLocked) { 10787 final int size = mPidsSelfLocked.size(); 10788 for (int i = 0; i < size; i++) { 10789 final int pid = mPidsSelfLocked.keyAt(i); 10790 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10791 if (proc == null) continue; 10792 10793 final int adj = proc.setAdj; 10794 if (adj > belowAdj && !proc.killedByAm) { 10795 proc.kill(reason, true); 10796 killed = true; 10797 } 10798 } 10799 } 10800 return killed; 10801 } 10802 10803 @Override 10804 public void hang(final IBinder who, boolean allowRestart) { 10805 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10806 != PackageManager.PERMISSION_GRANTED) { 10807 throw new SecurityException("Requires permission " 10808 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10809 } 10810 10811 final IBinder.DeathRecipient death = new DeathRecipient() { 10812 @Override 10813 public void binderDied() { 10814 synchronized (this) { 10815 notifyAll(); 10816 } 10817 } 10818 }; 10819 10820 try { 10821 who.linkToDeath(death, 0); 10822 } catch (RemoteException e) { 10823 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10824 return; 10825 } 10826 10827 synchronized (this) { 10828 Watchdog.getInstance().setAllowRestart(allowRestart); 10829 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10830 synchronized (death) { 10831 while (who.isBinderAlive()) { 10832 try { 10833 death.wait(); 10834 } catch (InterruptedException e) { 10835 } 10836 } 10837 } 10838 Watchdog.getInstance().setAllowRestart(true); 10839 } 10840 } 10841 10842 @Override 10843 public void restart() { 10844 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10845 != PackageManager.PERMISSION_GRANTED) { 10846 throw new SecurityException("Requires permission " 10847 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10848 } 10849 10850 Log.i(TAG, "Sending shutdown broadcast..."); 10851 10852 BroadcastReceiver br = new BroadcastReceiver() { 10853 @Override public void onReceive(Context context, Intent intent) { 10854 // Now the broadcast is done, finish up the low-level shutdown. 10855 Log.i(TAG, "Shutting down activity manager..."); 10856 shutdown(10000); 10857 Log.i(TAG, "Shutdown complete, restarting!"); 10858 Process.killProcess(Process.myPid()); 10859 System.exit(10); 10860 } 10861 }; 10862 10863 // First send the high-level shut down broadcast. 10864 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10865 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10866 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10867 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10868 mContext.sendOrderedBroadcastAsUser(intent, 10869 UserHandle.ALL, null, br, mHandler, 0, null, null); 10870 */ 10871 br.onReceive(mContext, intent); 10872 } 10873 10874 private long getLowRamTimeSinceIdle(long now) { 10875 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10876 } 10877 10878 @Override 10879 public void performIdleMaintenance() { 10880 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10881 != PackageManager.PERMISSION_GRANTED) { 10882 throw new SecurityException("Requires permission " 10883 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10884 } 10885 10886 synchronized (this) { 10887 final long now = SystemClock.uptimeMillis(); 10888 final long timeSinceLastIdle = now - mLastIdleTime; 10889 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10890 mLastIdleTime = now; 10891 mLowRamTimeSinceLastIdle = 0; 10892 if (mLowRamStartTime != 0) { 10893 mLowRamStartTime = now; 10894 } 10895 10896 StringBuilder sb = new StringBuilder(128); 10897 sb.append("Idle maintenance over "); 10898 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10899 sb.append(" low RAM for "); 10900 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10901 Slog.i(TAG, sb.toString()); 10902 10903 // If at least 1/3 of our time since the last idle period has been spent 10904 // with RAM low, then we want to kill processes. 10905 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10906 10907 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10908 ProcessRecord proc = mLruProcesses.get(i); 10909 if (proc.notCachedSinceIdle) { 10910 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10911 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10912 if (doKilling && proc.initialIdlePss != 0 10913 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10914 proc.kill("idle maint (pss " + proc.lastPss 10915 + " from " + proc.initialIdlePss + ")", true); 10916 } 10917 } 10918 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10919 proc.notCachedSinceIdle = true; 10920 proc.initialIdlePss = 0; 10921 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10922 isSleeping(), now); 10923 } 10924 } 10925 10926 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10927 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10928 } 10929 } 10930 10931 private void retrieveSettings() { 10932 final ContentResolver resolver = mContext.getContentResolver(); 10933 String debugApp = Settings.Global.getString( 10934 resolver, Settings.Global.DEBUG_APP); 10935 boolean waitForDebugger = Settings.Global.getInt( 10936 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10937 boolean alwaysFinishActivities = Settings.Global.getInt( 10938 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10939 boolean forceRtl = Settings.Global.getInt( 10940 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10941 // Transfer any global setting for forcing RTL layout, into a System Property 10942 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10943 10944 Configuration configuration = new Configuration(); 10945 Settings.System.getConfiguration(resolver, configuration); 10946 if (forceRtl) { 10947 // This will take care of setting the correct layout direction flags 10948 configuration.setLayoutDirection(configuration.locale); 10949 } 10950 10951 synchronized (this) { 10952 mDebugApp = mOrigDebugApp = debugApp; 10953 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10954 mAlwaysFinishActivities = alwaysFinishActivities; 10955 // This happens before any activities are started, so we can 10956 // change mConfiguration in-place. 10957 updateConfigurationLocked(configuration, null, false, true); 10958 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10959 } 10960 } 10961 10962 /** Loads resources after the current configuration has been set. */ 10963 private void loadResourcesOnSystemReady() { 10964 final Resources res = mContext.getResources(); 10965 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10966 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10967 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10968 } 10969 10970 public boolean testIsSystemReady() { 10971 // no need to synchronize(this) just to read & return the value 10972 return mSystemReady; 10973 } 10974 10975 private static File getCalledPreBootReceiversFile() { 10976 File dataDir = Environment.getDataDirectory(); 10977 File systemDir = new File(dataDir, "system"); 10978 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10979 return fname; 10980 } 10981 10982 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10983 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10984 File file = getCalledPreBootReceiversFile(); 10985 FileInputStream fis = null; 10986 try { 10987 fis = new FileInputStream(file); 10988 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10989 int fvers = dis.readInt(); 10990 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10991 String vers = dis.readUTF(); 10992 String codename = dis.readUTF(); 10993 String build = dis.readUTF(); 10994 if (android.os.Build.VERSION.RELEASE.equals(vers) 10995 && android.os.Build.VERSION.CODENAME.equals(codename) 10996 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10997 int num = dis.readInt(); 10998 while (num > 0) { 10999 num--; 11000 String pkg = dis.readUTF(); 11001 String cls = dis.readUTF(); 11002 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11003 } 11004 } 11005 } 11006 } catch (FileNotFoundException e) { 11007 } catch (IOException e) { 11008 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11009 } finally { 11010 if (fis != null) { 11011 try { 11012 fis.close(); 11013 } catch (IOException e) { 11014 } 11015 } 11016 } 11017 return lastDoneReceivers; 11018 } 11019 11020 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11021 File file = getCalledPreBootReceiversFile(); 11022 FileOutputStream fos = null; 11023 DataOutputStream dos = null; 11024 try { 11025 fos = new FileOutputStream(file); 11026 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11027 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11028 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11029 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11030 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11031 dos.writeInt(list.size()); 11032 for (int i=0; i<list.size(); i++) { 11033 dos.writeUTF(list.get(i).getPackageName()); 11034 dos.writeUTF(list.get(i).getClassName()); 11035 } 11036 } catch (IOException e) { 11037 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11038 file.delete(); 11039 } finally { 11040 FileUtils.sync(fos); 11041 if (dos != null) { 11042 try { 11043 dos.close(); 11044 } catch (IOException e) { 11045 // TODO Auto-generated catch block 11046 e.printStackTrace(); 11047 } 11048 } 11049 } 11050 } 11051 11052 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11053 ArrayList<ComponentName> doneReceivers, int userId) { 11054 boolean waitingUpdate = false; 11055 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11056 List<ResolveInfo> ris = null; 11057 try { 11058 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11059 intent, null, 0, userId); 11060 } catch (RemoteException e) { 11061 } 11062 if (ris != null) { 11063 for (int i=ris.size()-1; i>=0; i--) { 11064 if ((ris.get(i).activityInfo.applicationInfo.flags 11065 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11066 ris.remove(i); 11067 } 11068 } 11069 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11070 11071 // For User 0, load the version number. When delivering to a new user, deliver 11072 // to all receivers. 11073 if (userId == UserHandle.USER_OWNER) { 11074 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11075 for (int i=0; i<ris.size(); i++) { 11076 ActivityInfo ai = ris.get(i).activityInfo; 11077 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11078 if (lastDoneReceivers.contains(comp)) { 11079 // We already did the pre boot receiver for this app with the current 11080 // platform version, so don't do it again... 11081 ris.remove(i); 11082 i--; 11083 // ...however, do keep it as one that has been done, so we don't 11084 // forget about it when rewriting the file of last done receivers. 11085 doneReceivers.add(comp); 11086 } 11087 } 11088 } 11089 11090 // If primary user, send broadcast to all available users, else just to userId 11091 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11092 : new int[] { userId }; 11093 for (int i = 0; i < ris.size(); i++) { 11094 ActivityInfo ai = ris.get(i).activityInfo; 11095 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11096 doneReceivers.add(comp); 11097 intent.setComponent(comp); 11098 for (int j=0; j<users.length; j++) { 11099 IIntentReceiver finisher = null; 11100 // On last receiver and user, set up a completion callback 11101 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11102 finisher = new IIntentReceiver.Stub() { 11103 public void performReceive(Intent intent, int resultCode, 11104 String data, Bundle extras, boolean ordered, 11105 boolean sticky, int sendingUser) { 11106 // The raw IIntentReceiver interface is called 11107 // with the AM lock held, so redispatch to 11108 // execute our code without the lock. 11109 mHandler.post(onFinishCallback); 11110 } 11111 }; 11112 } 11113 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11114 + " for user " + users[j]); 11115 broadcastIntentLocked(null, null, intent, null, finisher, 11116 0, null, null, null, AppOpsManager.OP_NONE, 11117 true, false, MY_PID, Process.SYSTEM_UID, 11118 users[j]); 11119 if (finisher != null) { 11120 waitingUpdate = true; 11121 } 11122 } 11123 } 11124 } 11125 11126 return waitingUpdate; 11127 } 11128 11129 public void systemReady(final Runnable goingCallback) { 11130 synchronized(this) { 11131 if (mSystemReady) { 11132 // If we're done calling all the receivers, run the next "boot phase" passed in 11133 // by the SystemServer 11134 if (goingCallback != null) { 11135 goingCallback.run(); 11136 } 11137 return; 11138 } 11139 11140 // Make sure we have the current profile info, since it is needed for 11141 // security checks. 11142 updateCurrentProfileIdsLocked(); 11143 11144 if (mRecentTasks == null) { 11145 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11146 if (!mRecentTasks.isEmpty()) { 11147 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11148 } 11149 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11150 mTaskPersister.startPersisting(); 11151 } 11152 11153 // Check to see if there are any update receivers to run. 11154 if (!mDidUpdate) { 11155 if (mWaitingUpdate) { 11156 return; 11157 } 11158 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11159 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11160 public void run() { 11161 synchronized (ActivityManagerService.this) { 11162 mDidUpdate = true; 11163 } 11164 writeLastDonePreBootReceivers(doneReceivers); 11165 showBootMessage(mContext.getText( 11166 R.string.android_upgrading_complete), 11167 false); 11168 systemReady(goingCallback); 11169 } 11170 }, doneReceivers, UserHandle.USER_OWNER); 11171 11172 if (mWaitingUpdate) { 11173 return; 11174 } 11175 mDidUpdate = true; 11176 } 11177 11178 mAppOpsService.systemReady(); 11179 mSystemReady = true; 11180 } 11181 11182 ArrayList<ProcessRecord> procsToKill = null; 11183 synchronized(mPidsSelfLocked) { 11184 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11185 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11186 if (!isAllowedWhileBooting(proc.info)){ 11187 if (procsToKill == null) { 11188 procsToKill = new ArrayList<ProcessRecord>(); 11189 } 11190 procsToKill.add(proc); 11191 } 11192 } 11193 } 11194 11195 synchronized(this) { 11196 if (procsToKill != null) { 11197 for (int i=procsToKill.size()-1; i>=0; i--) { 11198 ProcessRecord proc = procsToKill.get(i); 11199 Slog.i(TAG, "Removing system update proc: " + proc); 11200 removeProcessLocked(proc, true, false, "system update done"); 11201 } 11202 } 11203 11204 // Now that we have cleaned up any update processes, we 11205 // are ready to start launching real processes and know that 11206 // we won't trample on them any more. 11207 mProcessesReady = true; 11208 } 11209 11210 Slog.i(TAG, "System now ready"); 11211 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11212 SystemClock.uptimeMillis()); 11213 11214 synchronized(this) { 11215 // Make sure we have no pre-ready processes sitting around. 11216 11217 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11218 ResolveInfo ri = mContext.getPackageManager() 11219 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11220 STOCK_PM_FLAGS); 11221 CharSequence errorMsg = null; 11222 if (ri != null) { 11223 ActivityInfo ai = ri.activityInfo; 11224 ApplicationInfo app = ai.applicationInfo; 11225 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11226 mTopAction = Intent.ACTION_FACTORY_TEST; 11227 mTopData = null; 11228 mTopComponent = new ComponentName(app.packageName, 11229 ai.name); 11230 } else { 11231 errorMsg = mContext.getResources().getText( 11232 com.android.internal.R.string.factorytest_not_system); 11233 } 11234 } else { 11235 errorMsg = mContext.getResources().getText( 11236 com.android.internal.R.string.factorytest_no_action); 11237 } 11238 if (errorMsg != null) { 11239 mTopAction = null; 11240 mTopData = null; 11241 mTopComponent = null; 11242 Message msg = Message.obtain(); 11243 msg.what = SHOW_FACTORY_ERROR_MSG; 11244 msg.getData().putCharSequence("msg", errorMsg); 11245 mHandler.sendMessage(msg); 11246 } 11247 } 11248 } 11249 11250 retrieveSettings(); 11251 loadResourcesOnSystemReady(); 11252 11253 synchronized (this) { 11254 readGrantedUriPermissionsLocked(); 11255 } 11256 11257 if (goingCallback != null) goingCallback.run(); 11258 11259 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11260 Integer.toString(mCurrentUserId), mCurrentUserId); 11261 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11262 Integer.toString(mCurrentUserId), mCurrentUserId); 11263 mSystemServiceManager.startUser(mCurrentUserId); 11264 11265 synchronized (this) { 11266 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11267 try { 11268 List apps = AppGlobals.getPackageManager(). 11269 getPersistentApplications(STOCK_PM_FLAGS); 11270 if (apps != null) { 11271 int N = apps.size(); 11272 int i; 11273 for (i=0; i<N; i++) { 11274 ApplicationInfo info 11275 = (ApplicationInfo)apps.get(i); 11276 if (info != null && 11277 !info.packageName.equals("android")) { 11278 addAppLocked(info, false, null /* ABI override */); 11279 } 11280 } 11281 } 11282 } catch (RemoteException ex) { 11283 // pm is in same process, this will never happen. 11284 } 11285 } 11286 11287 // Start up initial activity. 11288 mBooting = true; 11289 startHomeActivityLocked(mCurrentUserId); 11290 11291 try { 11292 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11293 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11294 + " data partition or your device will be unstable."); 11295 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11296 } 11297 } catch (RemoteException e) { 11298 } 11299 11300 if (!Build.isFingerprintConsistent()) { 11301 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11302 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11303 } 11304 11305 long ident = Binder.clearCallingIdentity(); 11306 try { 11307 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11308 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11309 | Intent.FLAG_RECEIVER_FOREGROUND); 11310 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11311 broadcastIntentLocked(null, null, intent, 11312 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11313 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11314 intent = new Intent(Intent.ACTION_USER_STARTING); 11315 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11316 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11317 broadcastIntentLocked(null, null, intent, 11318 null, new IIntentReceiver.Stub() { 11319 @Override 11320 public void performReceive(Intent intent, int resultCode, String data, 11321 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11322 throws RemoteException { 11323 } 11324 }, 0, null, null, 11325 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11326 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11327 } catch (Throwable t) { 11328 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11329 } finally { 11330 Binder.restoreCallingIdentity(ident); 11331 } 11332 mStackSupervisor.resumeTopActivitiesLocked(); 11333 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11334 } 11335 } 11336 11337 private boolean makeAppCrashingLocked(ProcessRecord app, 11338 String shortMsg, String longMsg, String stackTrace) { 11339 app.crashing = true; 11340 app.crashingReport = generateProcessError(app, 11341 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11342 startAppProblemLocked(app); 11343 app.stopFreezingAllLocked(); 11344 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11345 } 11346 11347 private void makeAppNotRespondingLocked(ProcessRecord app, 11348 String activity, String shortMsg, String longMsg) { 11349 app.notResponding = true; 11350 app.notRespondingReport = generateProcessError(app, 11351 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11352 activity, shortMsg, longMsg, null); 11353 startAppProblemLocked(app); 11354 app.stopFreezingAllLocked(); 11355 } 11356 11357 /** 11358 * Generate a process error record, suitable for attachment to a ProcessRecord. 11359 * 11360 * @param app The ProcessRecord in which the error occurred. 11361 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11362 * ActivityManager.AppErrorStateInfo 11363 * @param activity The activity associated with the crash, if known. 11364 * @param shortMsg Short message describing the crash. 11365 * @param longMsg Long message describing the crash. 11366 * @param stackTrace Full crash stack trace, may be null. 11367 * 11368 * @return Returns a fully-formed AppErrorStateInfo record. 11369 */ 11370 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11371 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11372 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11373 11374 report.condition = condition; 11375 report.processName = app.processName; 11376 report.pid = app.pid; 11377 report.uid = app.info.uid; 11378 report.tag = activity; 11379 report.shortMsg = shortMsg; 11380 report.longMsg = longMsg; 11381 report.stackTrace = stackTrace; 11382 11383 return report; 11384 } 11385 11386 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11387 synchronized (this) { 11388 app.crashing = false; 11389 app.crashingReport = null; 11390 app.notResponding = false; 11391 app.notRespondingReport = null; 11392 if (app.anrDialog == fromDialog) { 11393 app.anrDialog = null; 11394 } 11395 if (app.waitDialog == fromDialog) { 11396 app.waitDialog = null; 11397 } 11398 if (app.pid > 0 && app.pid != MY_PID) { 11399 handleAppCrashLocked(app, null, null, null); 11400 app.kill("user request after error", true); 11401 } 11402 } 11403 } 11404 11405 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11406 String stackTrace) { 11407 long now = SystemClock.uptimeMillis(); 11408 11409 Long crashTime; 11410 if (!app.isolated) { 11411 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11412 } else { 11413 crashTime = null; 11414 } 11415 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11416 // This process loses! 11417 Slog.w(TAG, "Process " + app.info.processName 11418 + " has crashed too many times: killing!"); 11419 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11420 app.userId, app.info.processName, app.uid); 11421 mStackSupervisor.handleAppCrashLocked(app); 11422 if (!app.persistent) { 11423 // We don't want to start this process again until the user 11424 // explicitly does so... but for persistent process, we really 11425 // need to keep it running. If a persistent process is actually 11426 // repeatedly crashing, then badness for everyone. 11427 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11428 app.info.processName); 11429 if (!app.isolated) { 11430 // XXX We don't have a way to mark isolated processes 11431 // as bad, since they don't have a peristent identity. 11432 mBadProcesses.put(app.info.processName, app.uid, 11433 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11434 mProcessCrashTimes.remove(app.info.processName, app.uid); 11435 } 11436 app.bad = true; 11437 app.removed = true; 11438 // Don't let services in this process be restarted and potentially 11439 // annoy the user repeatedly. Unless it is persistent, since those 11440 // processes run critical code. 11441 removeProcessLocked(app, false, false, "crash"); 11442 mStackSupervisor.resumeTopActivitiesLocked(); 11443 return false; 11444 } 11445 mStackSupervisor.resumeTopActivitiesLocked(); 11446 } else { 11447 mStackSupervisor.finishTopRunningActivityLocked(app); 11448 } 11449 11450 // Bump up the crash count of any services currently running in the proc. 11451 for (int i=app.services.size()-1; i>=0; i--) { 11452 // Any services running in the application need to be placed 11453 // back in the pending list. 11454 ServiceRecord sr = app.services.valueAt(i); 11455 sr.crashCount++; 11456 } 11457 11458 // If the crashing process is what we consider to be the "home process" and it has been 11459 // replaced by a third-party app, clear the package preferred activities from packages 11460 // with a home activity running in the process to prevent a repeatedly crashing app 11461 // from blocking the user to manually clear the list. 11462 final ArrayList<ActivityRecord> activities = app.activities; 11463 if (app == mHomeProcess && activities.size() > 0 11464 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11465 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11466 final ActivityRecord r = activities.get(activityNdx); 11467 if (r.isHomeActivity()) { 11468 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11469 try { 11470 ActivityThread.getPackageManager() 11471 .clearPackagePreferredActivities(r.packageName); 11472 } catch (RemoteException c) { 11473 // pm is in same process, this will never happen. 11474 } 11475 } 11476 } 11477 } 11478 11479 if (!app.isolated) { 11480 // XXX Can't keep track of crash times for isolated processes, 11481 // because they don't have a perisistent identity. 11482 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11483 } 11484 11485 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11486 return true; 11487 } 11488 11489 void startAppProblemLocked(ProcessRecord app) { 11490 // If this app is not running under the current user, then we 11491 // can't give it a report button because that would require 11492 // launching the report UI under a different user. 11493 app.errorReportReceiver = null; 11494 11495 for (int userId : mCurrentProfileIds) { 11496 if (app.userId == userId) { 11497 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11498 mContext, app.info.packageName, app.info.flags); 11499 } 11500 } 11501 skipCurrentReceiverLocked(app); 11502 } 11503 11504 void skipCurrentReceiverLocked(ProcessRecord app) { 11505 for (BroadcastQueue queue : mBroadcastQueues) { 11506 queue.skipCurrentReceiverLocked(app); 11507 } 11508 } 11509 11510 /** 11511 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11512 * The application process will exit immediately after this call returns. 11513 * @param app object of the crashing app, null for the system server 11514 * @param crashInfo describing the exception 11515 */ 11516 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11517 ProcessRecord r = findAppProcess(app, "Crash"); 11518 final String processName = app == null ? "system_server" 11519 : (r == null ? "unknown" : r.processName); 11520 11521 handleApplicationCrashInner("crash", r, processName, crashInfo); 11522 } 11523 11524 /* Native crash reporting uses this inner version because it needs to be somewhat 11525 * decoupled from the AM-managed cleanup lifecycle 11526 */ 11527 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11528 ApplicationErrorReport.CrashInfo crashInfo) { 11529 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11530 UserHandle.getUserId(Binder.getCallingUid()), processName, 11531 r == null ? -1 : r.info.flags, 11532 crashInfo.exceptionClassName, 11533 crashInfo.exceptionMessage, 11534 crashInfo.throwFileName, 11535 crashInfo.throwLineNumber); 11536 11537 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11538 11539 crashApplication(r, crashInfo); 11540 } 11541 11542 public void handleApplicationStrictModeViolation( 11543 IBinder app, 11544 int violationMask, 11545 StrictMode.ViolationInfo info) { 11546 ProcessRecord r = findAppProcess(app, "StrictMode"); 11547 if (r == null) { 11548 return; 11549 } 11550 11551 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11552 Integer stackFingerprint = info.hashCode(); 11553 boolean logIt = true; 11554 synchronized (mAlreadyLoggedViolatedStacks) { 11555 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11556 logIt = false; 11557 // TODO: sub-sample into EventLog for these, with 11558 // the info.durationMillis? Then we'd get 11559 // the relative pain numbers, without logging all 11560 // the stack traces repeatedly. We'd want to do 11561 // likewise in the client code, which also does 11562 // dup suppression, before the Binder call. 11563 } else { 11564 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11565 mAlreadyLoggedViolatedStacks.clear(); 11566 } 11567 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11568 } 11569 } 11570 if (logIt) { 11571 logStrictModeViolationToDropBox(r, info); 11572 } 11573 } 11574 11575 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11576 AppErrorResult result = new AppErrorResult(); 11577 synchronized (this) { 11578 final long origId = Binder.clearCallingIdentity(); 11579 11580 Message msg = Message.obtain(); 11581 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11582 HashMap<String, Object> data = new HashMap<String, Object>(); 11583 data.put("result", result); 11584 data.put("app", r); 11585 data.put("violationMask", violationMask); 11586 data.put("info", info); 11587 msg.obj = data; 11588 mHandler.sendMessage(msg); 11589 11590 Binder.restoreCallingIdentity(origId); 11591 } 11592 int res = result.get(); 11593 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11594 } 11595 } 11596 11597 // Depending on the policy in effect, there could be a bunch of 11598 // these in quick succession so we try to batch these together to 11599 // minimize disk writes, number of dropbox entries, and maximize 11600 // compression, by having more fewer, larger records. 11601 private void logStrictModeViolationToDropBox( 11602 ProcessRecord process, 11603 StrictMode.ViolationInfo info) { 11604 if (info == null) { 11605 return; 11606 } 11607 final boolean isSystemApp = process == null || 11608 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11609 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11610 final String processName = process == null ? "unknown" : process.processName; 11611 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11612 final DropBoxManager dbox = (DropBoxManager) 11613 mContext.getSystemService(Context.DROPBOX_SERVICE); 11614 11615 // Exit early if the dropbox isn't configured to accept this report type. 11616 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11617 11618 boolean bufferWasEmpty; 11619 boolean needsFlush; 11620 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11621 synchronized (sb) { 11622 bufferWasEmpty = sb.length() == 0; 11623 appendDropBoxProcessHeaders(process, processName, sb); 11624 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11625 sb.append("System-App: ").append(isSystemApp).append("\n"); 11626 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11627 if (info.violationNumThisLoop != 0) { 11628 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11629 } 11630 if (info.numAnimationsRunning != 0) { 11631 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11632 } 11633 if (info.broadcastIntentAction != null) { 11634 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11635 } 11636 if (info.durationMillis != -1) { 11637 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11638 } 11639 if (info.numInstances != -1) { 11640 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11641 } 11642 if (info.tags != null) { 11643 for (String tag : info.tags) { 11644 sb.append("Span-Tag: ").append(tag).append("\n"); 11645 } 11646 } 11647 sb.append("\n"); 11648 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11649 sb.append(info.crashInfo.stackTrace); 11650 } 11651 sb.append("\n"); 11652 11653 // Only buffer up to ~64k. Various logging bits truncate 11654 // things at 128k. 11655 needsFlush = (sb.length() > 64 * 1024); 11656 } 11657 11658 // Flush immediately if the buffer's grown too large, or this 11659 // is a non-system app. Non-system apps are isolated with a 11660 // different tag & policy and not batched. 11661 // 11662 // Batching is useful during internal testing with 11663 // StrictMode settings turned up high. Without batching, 11664 // thousands of separate files could be created on boot. 11665 if (!isSystemApp || needsFlush) { 11666 new Thread("Error dump: " + dropboxTag) { 11667 @Override 11668 public void run() { 11669 String report; 11670 synchronized (sb) { 11671 report = sb.toString(); 11672 sb.delete(0, sb.length()); 11673 sb.trimToSize(); 11674 } 11675 if (report.length() != 0) { 11676 dbox.addText(dropboxTag, report); 11677 } 11678 } 11679 }.start(); 11680 return; 11681 } 11682 11683 // System app batching: 11684 if (!bufferWasEmpty) { 11685 // An existing dropbox-writing thread is outstanding, so 11686 // we don't need to start it up. The existing thread will 11687 // catch the buffer appends we just did. 11688 return; 11689 } 11690 11691 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11692 // (After this point, we shouldn't access AMS internal data structures.) 11693 new Thread("Error dump: " + dropboxTag) { 11694 @Override 11695 public void run() { 11696 // 5 second sleep to let stacks arrive and be batched together 11697 try { 11698 Thread.sleep(5000); // 5 seconds 11699 } catch (InterruptedException e) {} 11700 11701 String errorReport; 11702 synchronized (mStrictModeBuffer) { 11703 errorReport = mStrictModeBuffer.toString(); 11704 if (errorReport.length() == 0) { 11705 return; 11706 } 11707 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11708 mStrictModeBuffer.trimToSize(); 11709 } 11710 dbox.addText(dropboxTag, errorReport); 11711 } 11712 }.start(); 11713 } 11714 11715 /** 11716 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11717 * @param app object of the crashing app, null for the system server 11718 * @param tag reported by the caller 11719 * @param system whether this wtf is coming from the system 11720 * @param crashInfo describing the context of the error 11721 * @return true if the process should exit immediately (WTF is fatal) 11722 */ 11723 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11724 final ApplicationErrorReport.CrashInfo crashInfo) { 11725 final int callingUid = Binder.getCallingUid(); 11726 final int callingPid = Binder.getCallingPid(); 11727 11728 if (system) { 11729 // If this is coming from the system, we could very well have low-level 11730 // system locks held, so we want to do this all asynchronously. And we 11731 // never want this to become fatal, so there is that too. 11732 mHandler.post(new Runnable() { 11733 @Override public void run() { 11734 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11735 } 11736 }); 11737 return false; 11738 } 11739 11740 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11741 crashInfo); 11742 11743 if (r != null && r.pid != Process.myPid() && 11744 Settings.Global.getInt(mContext.getContentResolver(), 11745 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11746 crashApplication(r, crashInfo); 11747 return true; 11748 } else { 11749 return false; 11750 } 11751 } 11752 11753 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11754 final ApplicationErrorReport.CrashInfo crashInfo) { 11755 final ProcessRecord r = findAppProcess(app, "WTF"); 11756 final String processName = app == null ? "system_server" 11757 : (r == null ? "unknown" : r.processName); 11758 11759 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11760 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11761 11762 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11763 11764 return r; 11765 } 11766 11767 /** 11768 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11769 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11770 */ 11771 private ProcessRecord findAppProcess(IBinder app, String reason) { 11772 if (app == null) { 11773 return null; 11774 } 11775 11776 synchronized (this) { 11777 final int NP = mProcessNames.getMap().size(); 11778 for (int ip=0; ip<NP; ip++) { 11779 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11780 final int NA = apps.size(); 11781 for (int ia=0; ia<NA; ia++) { 11782 ProcessRecord p = apps.valueAt(ia); 11783 if (p.thread != null && p.thread.asBinder() == app) { 11784 return p; 11785 } 11786 } 11787 } 11788 11789 Slog.w(TAG, "Can't find mystery application for " + reason 11790 + " from pid=" + Binder.getCallingPid() 11791 + " uid=" + Binder.getCallingUid() + ": " + app); 11792 return null; 11793 } 11794 } 11795 11796 /** 11797 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11798 * to append various headers to the dropbox log text. 11799 */ 11800 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11801 StringBuilder sb) { 11802 // Watchdog thread ends up invoking this function (with 11803 // a null ProcessRecord) to add the stack file to dropbox. 11804 // Do not acquire a lock on this (am) in such cases, as it 11805 // could cause a potential deadlock, if and when watchdog 11806 // is invoked due to unavailability of lock on am and it 11807 // would prevent watchdog from killing system_server. 11808 if (process == null) { 11809 sb.append("Process: ").append(processName).append("\n"); 11810 return; 11811 } 11812 // Note: ProcessRecord 'process' is guarded by the service 11813 // instance. (notably process.pkgList, which could otherwise change 11814 // concurrently during execution of this method) 11815 synchronized (this) { 11816 sb.append("Process: ").append(processName).append("\n"); 11817 int flags = process.info.flags; 11818 IPackageManager pm = AppGlobals.getPackageManager(); 11819 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11820 for (int ip=0; ip<process.pkgList.size(); ip++) { 11821 String pkg = process.pkgList.keyAt(ip); 11822 sb.append("Package: ").append(pkg); 11823 try { 11824 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11825 if (pi != null) { 11826 sb.append(" v").append(pi.versionCode); 11827 if (pi.versionName != null) { 11828 sb.append(" (").append(pi.versionName).append(")"); 11829 } 11830 } 11831 } catch (RemoteException e) { 11832 Slog.e(TAG, "Error getting package info: " + pkg, e); 11833 } 11834 sb.append("\n"); 11835 } 11836 } 11837 } 11838 11839 private static String processClass(ProcessRecord process) { 11840 if (process == null || process.pid == MY_PID) { 11841 return "system_server"; 11842 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11843 return "system_app"; 11844 } else { 11845 return "data_app"; 11846 } 11847 } 11848 11849 /** 11850 * Write a description of an error (crash, WTF, ANR) to the drop box. 11851 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11852 * @param process which caused the error, null means the system server 11853 * @param activity which triggered the error, null if unknown 11854 * @param parent activity related to the error, null if unknown 11855 * @param subject line related to the error, null if absent 11856 * @param report in long form describing the error, null if absent 11857 * @param logFile to include in the report, null if none 11858 * @param crashInfo giving an application stack trace, null if absent 11859 */ 11860 public void addErrorToDropBox(String eventType, 11861 ProcessRecord process, String processName, ActivityRecord activity, 11862 ActivityRecord parent, String subject, 11863 final String report, final File logFile, 11864 final ApplicationErrorReport.CrashInfo crashInfo) { 11865 // NOTE -- this must never acquire the ActivityManagerService lock, 11866 // otherwise the watchdog may be prevented from resetting the system. 11867 11868 final String dropboxTag = processClass(process) + "_" + eventType; 11869 final DropBoxManager dbox = (DropBoxManager) 11870 mContext.getSystemService(Context.DROPBOX_SERVICE); 11871 11872 // Exit early if the dropbox isn't configured to accept this report type. 11873 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11874 11875 final StringBuilder sb = new StringBuilder(1024); 11876 appendDropBoxProcessHeaders(process, processName, sb); 11877 if (activity != null) { 11878 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11879 } 11880 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11881 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11882 } 11883 if (parent != null && parent != activity) { 11884 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11885 } 11886 if (subject != null) { 11887 sb.append("Subject: ").append(subject).append("\n"); 11888 } 11889 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11890 if (Debug.isDebuggerConnected()) { 11891 sb.append("Debugger: Connected\n"); 11892 } 11893 sb.append("\n"); 11894 11895 // Do the rest in a worker thread to avoid blocking the caller on I/O 11896 // (After this point, we shouldn't access AMS internal data structures.) 11897 Thread worker = new Thread("Error dump: " + dropboxTag) { 11898 @Override 11899 public void run() { 11900 if (report != null) { 11901 sb.append(report); 11902 } 11903 if (logFile != null) { 11904 try { 11905 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11906 "\n\n[[TRUNCATED]]")); 11907 } catch (IOException e) { 11908 Slog.e(TAG, "Error reading " + logFile, e); 11909 } 11910 } 11911 if (crashInfo != null && crashInfo.stackTrace != null) { 11912 sb.append(crashInfo.stackTrace); 11913 } 11914 11915 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11916 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11917 if (lines > 0) { 11918 sb.append("\n"); 11919 11920 // Merge several logcat streams, and take the last N lines 11921 InputStreamReader input = null; 11922 try { 11923 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11924 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11925 "-b", "crash", 11926 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11927 11928 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11929 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11930 input = new InputStreamReader(logcat.getInputStream()); 11931 11932 int num; 11933 char[] buf = new char[8192]; 11934 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11935 } catch (IOException e) { 11936 Slog.e(TAG, "Error running logcat", e); 11937 } finally { 11938 if (input != null) try { input.close(); } catch (IOException e) {} 11939 } 11940 } 11941 11942 dbox.addText(dropboxTag, sb.toString()); 11943 } 11944 }; 11945 11946 if (process == null) { 11947 // If process is null, we are being called from some internal code 11948 // and may be about to die -- run this synchronously. 11949 worker.run(); 11950 } else { 11951 worker.start(); 11952 } 11953 } 11954 11955 /** 11956 * Bring up the "unexpected error" dialog box for a crashing app. 11957 * Deal with edge cases (intercepts from instrumented applications, 11958 * ActivityController, error intent receivers, that sort of thing). 11959 * @param r the application crashing 11960 * @param crashInfo describing the failure 11961 */ 11962 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11963 long timeMillis = System.currentTimeMillis(); 11964 String shortMsg = crashInfo.exceptionClassName; 11965 String longMsg = crashInfo.exceptionMessage; 11966 String stackTrace = crashInfo.stackTrace; 11967 if (shortMsg != null && longMsg != null) { 11968 longMsg = shortMsg + ": " + longMsg; 11969 } else if (shortMsg != null) { 11970 longMsg = shortMsg; 11971 } 11972 11973 AppErrorResult result = new AppErrorResult(); 11974 synchronized (this) { 11975 if (mController != null) { 11976 try { 11977 String name = r != null ? r.processName : null; 11978 int pid = r != null ? r.pid : Binder.getCallingPid(); 11979 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11980 if (!mController.appCrashed(name, pid, 11981 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11982 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11983 && "Native crash".equals(crashInfo.exceptionClassName)) { 11984 Slog.w(TAG, "Skip killing native crashed app " + name 11985 + "(" + pid + ") during testing"); 11986 } else { 11987 Slog.w(TAG, "Force-killing crashed app " + name 11988 + " at watcher's request"); 11989 if (r != null) { 11990 r.kill("crash", true); 11991 } else { 11992 // Huh. 11993 Process.killProcess(pid); 11994 Process.killProcessGroup(uid, pid); 11995 } 11996 } 11997 return; 11998 } 11999 } catch (RemoteException e) { 12000 mController = null; 12001 Watchdog.getInstance().setActivityController(null); 12002 } 12003 } 12004 12005 final long origId = Binder.clearCallingIdentity(); 12006 12007 // If this process is running instrumentation, finish it. 12008 if (r != null && r.instrumentationClass != null) { 12009 Slog.w(TAG, "Error in app " + r.processName 12010 + " running instrumentation " + r.instrumentationClass + ":"); 12011 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12012 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12013 Bundle info = new Bundle(); 12014 info.putString("shortMsg", shortMsg); 12015 info.putString("longMsg", longMsg); 12016 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12017 Binder.restoreCallingIdentity(origId); 12018 return; 12019 } 12020 12021 // If we can't identify the process or it's already exceeded its crash quota, 12022 // quit right away without showing a crash dialog. 12023 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12024 Binder.restoreCallingIdentity(origId); 12025 return; 12026 } 12027 12028 Message msg = Message.obtain(); 12029 msg.what = SHOW_ERROR_MSG; 12030 HashMap data = new HashMap(); 12031 data.put("result", result); 12032 data.put("app", r); 12033 msg.obj = data; 12034 mHandler.sendMessage(msg); 12035 12036 Binder.restoreCallingIdentity(origId); 12037 } 12038 12039 int res = result.get(); 12040 12041 Intent appErrorIntent = null; 12042 synchronized (this) { 12043 if (r != null && !r.isolated) { 12044 // XXX Can't keep track of crash time for isolated processes, 12045 // since they don't have a persistent identity. 12046 mProcessCrashTimes.put(r.info.processName, r.uid, 12047 SystemClock.uptimeMillis()); 12048 } 12049 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12050 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12051 } 12052 } 12053 12054 if (appErrorIntent != null) { 12055 try { 12056 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12057 } catch (ActivityNotFoundException e) { 12058 Slog.w(TAG, "bug report receiver dissappeared", e); 12059 } 12060 } 12061 } 12062 12063 Intent createAppErrorIntentLocked(ProcessRecord r, 12064 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12065 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12066 if (report == null) { 12067 return null; 12068 } 12069 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12070 result.setComponent(r.errorReportReceiver); 12071 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12072 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12073 return result; 12074 } 12075 12076 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12077 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12078 if (r.errorReportReceiver == null) { 12079 return null; 12080 } 12081 12082 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12083 return null; 12084 } 12085 12086 ApplicationErrorReport report = new ApplicationErrorReport(); 12087 report.packageName = r.info.packageName; 12088 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12089 report.processName = r.processName; 12090 report.time = timeMillis; 12091 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12092 12093 if (r.crashing || r.forceCrashReport) { 12094 report.type = ApplicationErrorReport.TYPE_CRASH; 12095 report.crashInfo = crashInfo; 12096 } else if (r.notResponding) { 12097 report.type = ApplicationErrorReport.TYPE_ANR; 12098 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12099 12100 report.anrInfo.activity = r.notRespondingReport.tag; 12101 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12102 report.anrInfo.info = r.notRespondingReport.longMsg; 12103 } 12104 12105 return report; 12106 } 12107 12108 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12109 enforceNotIsolatedCaller("getProcessesInErrorState"); 12110 // assume our apps are happy - lazy create the list 12111 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12112 12113 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12114 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12115 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12116 12117 synchronized (this) { 12118 12119 // iterate across all processes 12120 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12121 ProcessRecord app = mLruProcesses.get(i); 12122 if (!allUsers && app.userId != userId) { 12123 continue; 12124 } 12125 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12126 // This one's in trouble, so we'll generate a report for it 12127 // crashes are higher priority (in case there's a crash *and* an anr) 12128 ActivityManager.ProcessErrorStateInfo report = null; 12129 if (app.crashing) { 12130 report = app.crashingReport; 12131 } else if (app.notResponding) { 12132 report = app.notRespondingReport; 12133 } 12134 12135 if (report != null) { 12136 if (errList == null) { 12137 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12138 } 12139 errList.add(report); 12140 } else { 12141 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12142 " crashing = " + app.crashing + 12143 " notResponding = " + app.notResponding); 12144 } 12145 } 12146 } 12147 } 12148 12149 return errList; 12150 } 12151 12152 static int procStateToImportance(int procState, int memAdj, 12153 ActivityManager.RunningAppProcessInfo currApp) { 12154 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12155 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12156 currApp.lru = memAdj; 12157 } else { 12158 currApp.lru = 0; 12159 } 12160 return imp; 12161 } 12162 12163 private void fillInProcMemInfo(ProcessRecord app, 12164 ActivityManager.RunningAppProcessInfo outInfo) { 12165 outInfo.pid = app.pid; 12166 outInfo.uid = app.info.uid; 12167 if (mHeavyWeightProcess == app) { 12168 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12169 } 12170 if (app.persistent) { 12171 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12172 } 12173 if (app.activities.size() > 0) { 12174 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12175 } 12176 outInfo.lastTrimLevel = app.trimMemoryLevel; 12177 int adj = app.curAdj; 12178 int procState = app.curProcState; 12179 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12180 outInfo.importanceReasonCode = app.adjTypeCode; 12181 outInfo.processState = app.curProcState; 12182 } 12183 12184 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12185 enforceNotIsolatedCaller("getRunningAppProcesses"); 12186 // Lazy instantiation of list 12187 List<ActivityManager.RunningAppProcessInfo> runList = null; 12188 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12189 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12190 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12191 synchronized (this) { 12192 // Iterate across all processes 12193 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12194 ProcessRecord app = mLruProcesses.get(i); 12195 if (!allUsers && app.userId != userId) { 12196 continue; 12197 } 12198 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12199 // Generate process state info for running application 12200 ActivityManager.RunningAppProcessInfo currApp = 12201 new ActivityManager.RunningAppProcessInfo(app.processName, 12202 app.pid, app.getPackageList()); 12203 fillInProcMemInfo(app, currApp); 12204 if (app.adjSource instanceof ProcessRecord) { 12205 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12206 currApp.importanceReasonImportance = 12207 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12208 app.adjSourceProcState); 12209 } else if (app.adjSource instanceof ActivityRecord) { 12210 ActivityRecord r = (ActivityRecord)app.adjSource; 12211 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12212 } 12213 if (app.adjTarget instanceof ComponentName) { 12214 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12215 } 12216 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12217 // + " lru=" + currApp.lru); 12218 if (runList == null) { 12219 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12220 } 12221 runList.add(currApp); 12222 } 12223 } 12224 } 12225 return runList; 12226 } 12227 12228 public List<ApplicationInfo> getRunningExternalApplications() { 12229 enforceNotIsolatedCaller("getRunningExternalApplications"); 12230 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12231 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12232 if (runningApps != null && runningApps.size() > 0) { 12233 Set<String> extList = new HashSet<String>(); 12234 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12235 if (app.pkgList != null) { 12236 for (String pkg : app.pkgList) { 12237 extList.add(pkg); 12238 } 12239 } 12240 } 12241 IPackageManager pm = AppGlobals.getPackageManager(); 12242 for (String pkg : extList) { 12243 try { 12244 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12245 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12246 retList.add(info); 12247 } 12248 } catch (RemoteException e) { 12249 } 12250 } 12251 } 12252 return retList; 12253 } 12254 12255 @Override 12256 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12257 enforceNotIsolatedCaller("getMyMemoryState"); 12258 synchronized (this) { 12259 ProcessRecord proc; 12260 synchronized (mPidsSelfLocked) { 12261 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12262 } 12263 fillInProcMemInfo(proc, outInfo); 12264 } 12265 } 12266 12267 @Override 12268 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12269 if (checkCallingPermission(android.Manifest.permission.DUMP) 12270 != PackageManager.PERMISSION_GRANTED) { 12271 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12272 + Binder.getCallingPid() 12273 + ", uid=" + Binder.getCallingUid() 12274 + " without permission " 12275 + android.Manifest.permission.DUMP); 12276 return; 12277 } 12278 12279 boolean dumpAll = false; 12280 boolean dumpClient = false; 12281 String dumpPackage = null; 12282 12283 int opti = 0; 12284 while (opti < args.length) { 12285 String opt = args[opti]; 12286 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12287 break; 12288 } 12289 opti++; 12290 if ("-a".equals(opt)) { 12291 dumpAll = true; 12292 } else if ("-c".equals(opt)) { 12293 dumpClient = true; 12294 } else if ("-h".equals(opt)) { 12295 pw.println("Activity manager dump options:"); 12296 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12297 pw.println(" cmd may be one of:"); 12298 pw.println(" a[ctivities]: activity stack state"); 12299 pw.println(" r[recents]: recent activities state"); 12300 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12301 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12302 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12303 pw.println(" o[om]: out of memory management"); 12304 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12305 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12306 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12307 pw.println(" service [COMP_SPEC]: service client-side state"); 12308 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12309 pw.println(" all: dump all activities"); 12310 pw.println(" top: dump the top activity"); 12311 pw.println(" write: write all pending state to storage"); 12312 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12313 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12314 pw.println(" a partial substring in a component name, a"); 12315 pw.println(" hex object identifier."); 12316 pw.println(" -a: include all available server state."); 12317 pw.println(" -c: include client state."); 12318 return; 12319 } else { 12320 pw.println("Unknown argument: " + opt + "; use -h for help"); 12321 } 12322 } 12323 12324 long origId = Binder.clearCallingIdentity(); 12325 boolean more = false; 12326 // Is the caller requesting to dump a particular piece of data? 12327 if (opti < args.length) { 12328 String cmd = args[opti]; 12329 opti++; 12330 if ("activities".equals(cmd) || "a".equals(cmd)) { 12331 synchronized (this) { 12332 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12333 } 12334 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12335 synchronized (this) { 12336 dumpRecentsLocked(fd, pw, args, opti, true, null); 12337 } 12338 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12339 String[] newArgs; 12340 String name; 12341 if (opti >= args.length) { 12342 name = null; 12343 newArgs = EMPTY_STRING_ARRAY; 12344 } else { 12345 name = args[opti]; 12346 opti++; 12347 newArgs = new String[args.length - opti]; 12348 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12349 args.length - opti); 12350 } 12351 synchronized (this) { 12352 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12353 } 12354 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12355 String[] newArgs; 12356 String name; 12357 if (opti >= args.length) { 12358 name = null; 12359 newArgs = EMPTY_STRING_ARRAY; 12360 } else { 12361 name = args[opti]; 12362 opti++; 12363 newArgs = new String[args.length - opti]; 12364 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12365 args.length - opti); 12366 } 12367 synchronized (this) { 12368 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12369 } 12370 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12371 String[] newArgs; 12372 String name; 12373 if (opti >= args.length) { 12374 name = null; 12375 newArgs = EMPTY_STRING_ARRAY; 12376 } else { 12377 name = args[opti]; 12378 opti++; 12379 newArgs = new String[args.length - opti]; 12380 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12381 args.length - opti); 12382 } 12383 synchronized (this) { 12384 dumpProcessesLocked(fd, pw, args, opti, true, name); 12385 } 12386 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12387 synchronized (this) { 12388 dumpOomLocked(fd, pw, args, opti, true); 12389 } 12390 } else if ("provider".equals(cmd)) { 12391 String[] newArgs; 12392 String name; 12393 if (opti >= args.length) { 12394 name = null; 12395 newArgs = EMPTY_STRING_ARRAY; 12396 } else { 12397 name = args[opti]; 12398 opti++; 12399 newArgs = new String[args.length - opti]; 12400 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12401 } 12402 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12403 pw.println("No providers match: " + name); 12404 pw.println("Use -h for help."); 12405 } 12406 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12407 synchronized (this) { 12408 dumpProvidersLocked(fd, pw, args, opti, true, null); 12409 } 12410 } else if ("service".equals(cmd)) { 12411 String[] newArgs; 12412 String name; 12413 if (opti >= args.length) { 12414 name = null; 12415 newArgs = EMPTY_STRING_ARRAY; 12416 } else { 12417 name = args[opti]; 12418 opti++; 12419 newArgs = new String[args.length - opti]; 12420 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12421 args.length - opti); 12422 } 12423 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12424 pw.println("No services match: " + name); 12425 pw.println("Use -h for help."); 12426 } 12427 } else if ("package".equals(cmd)) { 12428 String[] newArgs; 12429 if (opti >= args.length) { 12430 pw.println("package: no package name specified"); 12431 pw.println("Use -h for help."); 12432 } else { 12433 dumpPackage = args[opti]; 12434 opti++; 12435 newArgs = new String[args.length - opti]; 12436 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12437 args.length - opti); 12438 args = newArgs; 12439 opti = 0; 12440 more = true; 12441 } 12442 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12443 synchronized (this) { 12444 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12445 } 12446 } else if ("write".equals(cmd)) { 12447 mTaskPersister.flush(); 12448 pw.println("All tasks persisted."); 12449 return; 12450 } else { 12451 // Dumping a single activity? 12452 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12453 pw.println("Bad activity command, or no activities match: " + cmd); 12454 pw.println("Use -h for help."); 12455 } 12456 } 12457 if (!more) { 12458 Binder.restoreCallingIdentity(origId); 12459 return; 12460 } 12461 } 12462 12463 // No piece of data specified, dump everything. 12464 synchronized (this) { 12465 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12466 pw.println(); 12467 if (dumpAll) { 12468 pw.println("-------------------------------------------------------------------------------"); 12469 } 12470 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12471 pw.println(); 12472 if (dumpAll) { 12473 pw.println("-------------------------------------------------------------------------------"); 12474 } 12475 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12476 pw.println(); 12477 if (dumpAll) { 12478 pw.println("-------------------------------------------------------------------------------"); 12479 } 12480 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12481 pw.println(); 12482 if (dumpAll) { 12483 pw.println("-------------------------------------------------------------------------------"); 12484 } 12485 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12486 pw.println(); 12487 if (dumpAll) { 12488 pw.println("-------------------------------------------------------------------------------"); 12489 } 12490 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12491 pw.println(); 12492 if (dumpAll) { 12493 pw.println("-------------------------------------------------------------------------------"); 12494 } 12495 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12496 } 12497 Binder.restoreCallingIdentity(origId); 12498 } 12499 12500 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12501 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12502 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12503 12504 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12505 dumpPackage); 12506 boolean needSep = printedAnything; 12507 12508 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12509 dumpPackage, needSep, " mFocusedActivity: "); 12510 if (printed) { 12511 printedAnything = true; 12512 needSep = false; 12513 } 12514 12515 if (dumpPackage == null) { 12516 if (needSep) { 12517 pw.println(); 12518 } 12519 needSep = true; 12520 printedAnything = true; 12521 mStackSupervisor.dump(pw, " "); 12522 } 12523 12524 if (!printedAnything) { 12525 pw.println(" (nothing)"); 12526 } 12527 } 12528 12529 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12530 int opti, boolean dumpAll, String dumpPackage) { 12531 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12532 12533 boolean printedAnything = false; 12534 12535 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12536 boolean printedHeader = false; 12537 12538 final int N = mRecentTasks.size(); 12539 for (int i=0; i<N; i++) { 12540 TaskRecord tr = mRecentTasks.get(i); 12541 if (dumpPackage != null) { 12542 if (tr.realActivity == null || 12543 !dumpPackage.equals(tr.realActivity)) { 12544 continue; 12545 } 12546 } 12547 if (!printedHeader) { 12548 pw.println(" Recent tasks:"); 12549 printedHeader = true; 12550 printedAnything = true; 12551 } 12552 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12553 pw.println(tr); 12554 if (dumpAll) { 12555 mRecentTasks.get(i).dump(pw, " "); 12556 } 12557 } 12558 } 12559 12560 if (!printedAnything) { 12561 pw.println(" (nothing)"); 12562 } 12563 } 12564 12565 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12566 int opti, boolean dumpAll, String dumpPackage) { 12567 boolean needSep = false; 12568 boolean printedAnything = false; 12569 int numPers = 0; 12570 12571 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12572 12573 if (dumpAll) { 12574 final int NP = mProcessNames.getMap().size(); 12575 for (int ip=0; ip<NP; ip++) { 12576 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12577 final int NA = procs.size(); 12578 for (int ia=0; ia<NA; ia++) { 12579 ProcessRecord r = procs.valueAt(ia); 12580 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12581 continue; 12582 } 12583 if (!needSep) { 12584 pw.println(" All known processes:"); 12585 needSep = true; 12586 printedAnything = true; 12587 } 12588 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12589 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12590 pw.print(" "); pw.println(r); 12591 r.dump(pw, " "); 12592 if (r.persistent) { 12593 numPers++; 12594 } 12595 } 12596 } 12597 } 12598 12599 if (mIsolatedProcesses.size() > 0) { 12600 boolean printed = false; 12601 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12602 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12603 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12604 continue; 12605 } 12606 if (!printed) { 12607 if (needSep) { 12608 pw.println(); 12609 } 12610 pw.println(" Isolated process list (sorted by uid):"); 12611 printedAnything = true; 12612 printed = true; 12613 needSep = true; 12614 } 12615 pw.println(String.format("%sIsolated #%2d: %s", 12616 " ", i, r.toString())); 12617 } 12618 } 12619 12620 if (mLruProcesses.size() > 0) { 12621 if (needSep) { 12622 pw.println(); 12623 } 12624 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12625 pw.print(" total, non-act at "); 12626 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12627 pw.print(", non-svc at "); 12628 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12629 pw.println("):"); 12630 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12631 needSep = true; 12632 printedAnything = true; 12633 } 12634 12635 if (dumpAll || dumpPackage != null) { 12636 synchronized (mPidsSelfLocked) { 12637 boolean printed = false; 12638 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12639 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12640 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12641 continue; 12642 } 12643 if (!printed) { 12644 if (needSep) pw.println(); 12645 needSep = true; 12646 pw.println(" PID mappings:"); 12647 printed = true; 12648 printedAnything = true; 12649 } 12650 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12651 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12652 } 12653 } 12654 } 12655 12656 if (mForegroundProcesses.size() > 0) { 12657 synchronized (mPidsSelfLocked) { 12658 boolean printed = false; 12659 for (int i=0; i<mForegroundProcesses.size(); i++) { 12660 ProcessRecord r = mPidsSelfLocked.get( 12661 mForegroundProcesses.valueAt(i).pid); 12662 if (dumpPackage != null && (r == null 12663 || !r.pkgList.containsKey(dumpPackage))) { 12664 continue; 12665 } 12666 if (!printed) { 12667 if (needSep) pw.println(); 12668 needSep = true; 12669 pw.println(" Foreground Processes:"); 12670 printed = true; 12671 printedAnything = true; 12672 } 12673 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12674 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12675 } 12676 } 12677 } 12678 12679 if (mPersistentStartingProcesses.size() > 0) { 12680 if (needSep) pw.println(); 12681 needSep = true; 12682 printedAnything = true; 12683 pw.println(" Persisent processes that are starting:"); 12684 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12685 "Starting Norm", "Restarting PERS", dumpPackage); 12686 } 12687 12688 if (mRemovedProcesses.size() > 0) { 12689 if (needSep) pw.println(); 12690 needSep = true; 12691 printedAnything = true; 12692 pw.println(" Processes that are being removed:"); 12693 dumpProcessList(pw, this, mRemovedProcesses, " ", 12694 "Removed Norm", "Removed PERS", dumpPackage); 12695 } 12696 12697 if (mProcessesOnHold.size() > 0) { 12698 if (needSep) pw.println(); 12699 needSep = true; 12700 printedAnything = true; 12701 pw.println(" Processes that are on old until the system is ready:"); 12702 dumpProcessList(pw, this, mProcessesOnHold, " ", 12703 "OnHold Norm", "OnHold PERS", dumpPackage); 12704 } 12705 12706 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12707 12708 if (mProcessCrashTimes.getMap().size() > 0) { 12709 boolean printed = false; 12710 long now = SystemClock.uptimeMillis(); 12711 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12712 final int NP = pmap.size(); 12713 for (int ip=0; ip<NP; ip++) { 12714 String pname = pmap.keyAt(ip); 12715 SparseArray<Long> uids = pmap.valueAt(ip); 12716 final int N = uids.size(); 12717 for (int i=0; i<N; i++) { 12718 int puid = uids.keyAt(i); 12719 ProcessRecord r = mProcessNames.get(pname, puid); 12720 if (dumpPackage != null && (r == null 12721 || !r.pkgList.containsKey(dumpPackage))) { 12722 continue; 12723 } 12724 if (!printed) { 12725 if (needSep) pw.println(); 12726 needSep = true; 12727 pw.println(" Time since processes crashed:"); 12728 printed = true; 12729 printedAnything = true; 12730 } 12731 pw.print(" Process "); pw.print(pname); 12732 pw.print(" uid "); pw.print(puid); 12733 pw.print(": last crashed "); 12734 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12735 pw.println(" ago"); 12736 } 12737 } 12738 } 12739 12740 if (mBadProcesses.getMap().size() > 0) { 12741 boolean printed = false; 12742 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12743 final int NP = pmap.size(); 12744 for (int ip=0; ip<NP; ip++) { 12745 String pname = pmap.keyAt(ip); 12746 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12747 final int N = uids.size(); 12748 for (int i=0; i<N; i++) { 12749 int puid = uids.keyAt(i); 12750 ProcessRecord r = mProcessNames.get(pname, puid); 12751 if (dumpPackage != null && (r == null 12752 || !r.pkgList.containsKey(dumpPackage))) { 12753 continue; 12754 } 12755 if (!printed) { 12756 if (needSep) pw.println(); 12757 needSep = true; 12758 pw.println(" Bad processes:"); 12759 printedAnything = true; 12760 } 12761 BadProcessInfo info = uids.valueAt(i); 12762 pw.print(" Bad process "); pw.print(pname); 12763 pw.print(" uid "); pw.print(puid); 12764 pw.print(": crashed at time "); pw.println(info.time); 12765 if (info.shortMsg != null) { 12766 pw.print(" Short msg: "); pw.println(info.shortMsg); 12767 } 12768 if (info.longMsg != null) { 12769 pw.print(" Long msg: "); pw.println(info.longMsg); 12770 } 12771 if (info.stack != null) { 12772 pw.println(" Stack:"); 12773 int lastPos = 0; 12774 for (int pos=0; pos<info.stack.length(); pos++) { 12775 if (info.stack.charAt(pos) == '\n') { 12776 pw.print(" "); 12777 pw.write(info.stack, lastPos, pos-lastPos); 12778 pw.println(); 12779 lastPos = pos+1; 12780 } 12781 } 12782 if (lastPos < info.stack.length()) { 12783 pw.print(" "); 12784 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12785 pw.println(); 12786 } 12787 } 12788 } 12789 } 12790 } 12791 12792 if (dumpPackage == null) { 12793 pw.println(); 12794 needSep = false; 12795 pw.println(" mStartedUsers:"); 12796 for (int i=0; i<mStartedUsers.size(); i++) { 12797 UserStartedState uss = mStartedUsers.valueAt(i); 12798 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12799 pw.print(": "); uss.dump("", pw); 12800 } 12801 pw.print(" mStartedUserArray: ["); 12802 for (int i=0; i<mStartedUserArray.length; i++) { 12803 if (i > 0) pw.print(", "); 12804 pw.print(mStartedUserArray[i]); 12805 } 12806 pw.println("]"); 12807 pw.print(" mUserLru: ["); 12808 for (int i=0; i<mUserLru.size(); i++) { 12809 if (i > 0) pw.print(", "); 12810 pw.print(mUserLru.get(i)); 12811 } 12812 pw.println("]"); 12813 if (dumpAll) { 12814 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12815 } 12816 synchronized (mUserProfileGroupIdsSelfLocked) { 12817 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12818 pw.println(" mUserProfileGroupIds:"); 12819 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12820 pw.print(" User #"); 12821 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12822 pw.print(" -> profile #"); 12823 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12824 } 12825 } 12826 } 12827 } 12828 if (mHomeProcess != null && (dumpPackage == null 12829 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12830 if (needSep) { 12831 pw.println(); 12832 needSep = false; 12833 } 12834 pw.println(" mHomeProcess: " + mHomeProcess); 12835 } 12836 if (mPreviousProcess != null && (dumpPackage == null 12837 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12838 if (needSep) { 12839 pw.println(); 12840 needSep = false; 12841 } 12842 pw.println(" mPreviousProcess: " + mPreviousProcess); 12843 } 12844 if (dumpAll) { 12845 StringBuilder sb = new StringBuilder(128); 12846 sb.append(" mPreviousProcessVisibleTime: "); 12847 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12848 pw.println(sb); 12849 } 12850 if (mHeavyWeightProcess != null && (dumpPackage == null 12851 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12852 if (needSep) { 12853 pw.println(); 12854 needSep = false; 12855 } 12856 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12857 } 12858 if (dumpPackage == null) { 12859 pw.println(" mConfiguration: " + mConfiguration); 12860 } 12861 if (dumpAll) { 12862 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12863 if (mCompatModePackages.getPackages().size() > 0) { 12864 boolean printed = false; 12865 for (Map.Entry<String, Integer> entry 12866 : mCompatModePackages.getPackages().entrySet()) { 12867 String pkg = entry.getKey(); 12868 int mode = entry.getValue(); 12869 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12870 continue; 12871 } 12872 if (!printed) { 12873 pw.println(" mScreenCompatPackages:"); 12874 printed = true; 12875 } 12876 pw.print(" "); pw.print(pkg); pw.print(": "); 12877 pw.print(mode); pw.println(); 12878 } 12879 } 12880 } 12881 if (dumpPackage == null) { 12882 pw.println(" mWakefulness=" 12883 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12884 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12885 + lockScreenShownToString()); 12886 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12887 } 12888 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12889 || mOrigWaitForDebugger) { 12890 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12891 || dumpPackage.equals(mOrigDebugApp)) { 12892 if (needSep) { 12893 pw.println(); 12894 needSep = false; 12895 } 12896 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12897 + " mDebugTransient=" + mDebugTransient 12898 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12899 } 12900 } 12901 if (mOpenGlTraceApp != null) { 12902 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12903 if (needSep) { 12904 pw.println(); 12905 needSep = false; 12906 } 12907 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12908 } 12909 } 12910 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12911 || mProfileFd != null) { 12912 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12913 if (needSep) { 12914 pw.println(); 12915 needSep = false; 12916 } 12917 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12918 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12919 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12920 + mAutoStopProfiler); 12921 pw.println(" mProfileType=" + mProfileType); 12922 } 12923 } 12924 if (dumpPackage == null) { 12925 if (mAlwaysFinishActivities || mController != null) { 12926 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12927 + " mController=" + mController); 12928 } 12929 if (dumpAll) { 12930 pw.println(" Total persistent processes: " + numPers); 12931 pw.println(" mProcessesReady=" + mProcessesReady 12932 + " mSystemReady=" + mSystemReady 12933 + " mBooted=" + mBooted 12934 + " mFactoryTest=" + mFactoryTest); 12935 pw.println(" mBooting=" + mBooting 12936 + " mCallFinishBooting=" + mCallFinishBooting 12937 + " mBootAnimationComplete=" + mBootAnimationComplete); 12938 pw.print(" mLastPowerCheckRealtime="); 12939 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12940 pw.println(""); 12941 pw.print(" mLastPowerCheckUptime="); 12942 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12943 pw.println(""); 12944 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12945 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12946 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12947 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12948 + " (" + mLruProcesses.size() + " total)" 12949 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12950 + " mNumServiceProcs=" + mNumServiceProcs 12951 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12952 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12953 + " mLastMemoryLevel" + mLastMemoryLevel 12954 + " mLastNumProcesses" + mLastNumProcesses); 12955 long now = SystemClock.uptimeMillis(); 12956 pw.print(" mLastIdleTime="); 12957 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12958 pw.print(" mLowRamSinceLastIdle="); 12959 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12960 pw.println(); 12961 } 12962 } 12963 12964 if (!printedAnything) { 12965 pw.println(" (nothing)"); 12966 } 12967 } 12968 12969 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12970 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12971 if (mProcessesToGc.size() > 0) { 12972 boolean printed = false; 12973 long now = SystemClock.uptimeMillis(); 12974 for (int i=0; i<mProcessesToGc.size(); i++) { 12975 ProcessRecord proc = mProcessesToGc.get(i); 12976 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12977 continue; 12978 } 12979 if (!printed) { 12980 if (needSep) pw.println(); 12981 needSep = true; 12982 pw.println(" Processes that are waiting to GC:"); 12983 printed = true; 12984 } 12985 pw.print(" Process "); pw.println(proc); 12986 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12987 pw.print(", last gced="); 12988 pw.print(now-proc.lastRequestedGc); 12989 pw.print(" ms ago, last lowMem="); 12990 pw.print(now-proc.lastLowMemory); 12991 pw.println(" ms ago"); 12992 12993 } 12994 } 12995 return needSep; 12996 } 12997 12998 void printOomLevel(PrintWriter pw, String name, int adj) { 12999 pw.print(" "); 13000 if (adj >= 0) { 13001 pw.print(' '); 13002 if (adj < 10) pw.print(' '); 13003 } else { 13004 if (adj > -10) pw.print(' '); 13005 } 13006 pw.print(adj); 13007 pw.print(": "); 13008 pw.print(name); 13009 pw.print(" ("); 13010 pw.print(mProcessList.getMemLevel(adj)/1024); 13011 pw.println(" kB)"); 13012 } 13013 13014 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13015 int opti, boolean dumpAll) { 13016 boolean needSep = false; 13017 13018 if (mLruProcesses.size() > 0) { 13019 if (needSep) pw.println(); 13020 needSep = true; 13021 pw.println(" OOM levels:"); 13022 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13023 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13024 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13025 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13026 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13027 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13028 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13029 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13030 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13031 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13032 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13033 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13034 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13035 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13036 13037 if (needSep) pw.println(); 13038 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13039 pw.print(" total, non-act at "); 13040 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13041 pw.print(", non-svc at "); 13042 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13043 pw.println("):"); 13044 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13045 needSep = true; 13046 } 13047 13048 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13049 13050 pw.println(); 13051 pw.println(" mHomeProcess: " + mHomeProcess); 13052 pw.println(" mPreviousProcess: " + mPreviousProcess); 13053 if (mHeavyWeightProcess != null) { 13054 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13055 } 13056 13057 return true; 13058 } 13059 13060 /** 13061 * There are three ways to call this: 13062 * - no provider specified: dump all the providers 13063 * - a flattened component name that matched an existing provider was specified as the 13064 * first arg: dump that one provider 13065 * - the first arg isn't the flattened component name of an existing provider: 13066 * dump all providers whose component contains the first arg as a substring 13067 */ 13068 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13069 int opti, boolean dumpAll) { 13070 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13071 } 13072 13073 static class ItemMatcher { 13074 ArrayList<ComponentName> components; 13075 ArrayList<String> strings; 13076 ArrayList<Integer> objects; 13077 boolean all; 13078 13079 ItemMatcher() { 13080 all = true; 13081 } 13082 13083 void build(String name) { 13084 ComponentName componentName = ComponentName.unflattenFromString(name); 13085 if (componentName != null) { 13086 if (components == null) { 13087 components = new ArrayList<ComponentName>(); 13088 } 13089 components.add(componentName); 13090 all = false; 13091 } else { 13092 int objectId = 0; 13093 // Not a '/' separated full component name; maybe an object ID? 13094 try { 13095 objectId = Integer.parseInt(name, 16); 13096 if (objects == null) { 13097 objects = new ArrayList<Integer>(); 13098 } 13099 objects.add(objectId); 13100 all = false; 13101 } catch (RuntimeException e) { 13102 // Not an integer; just do string match. 13103 if (strings == null) { 13104 strings = new ArrayList<String>(); 13105 } 13106 strings.add(name); 13107 all = false; 13108 } 13109 } 13110 } 13111 13112 int build(String[] args, int opti) { 13113 for (; opti<args.length; opti++) { 13114 String name = args[opti]; 13115 if ("--".equals(name)) { 13116 return opti+1; 13117 } 13118 build(name); 13119 } 13120 return opti; 13121 } 13122 13123 boolean match(Object object, ComponentName comp) { 13124 if (all) { 13125 return true; 13126 } 13127 if (components != null) { 13128 for (int i=0; i<components.size(); i++) { 13129 if (components.get(i).equals(comp)) { 13130 return true; 13131 } 13132 } 13133 } 13134 if (objects != null) { 13135 for (int i=0; i<objects.size(); i++) { 13136 if (System.identityHashCode(object) == objects.get(i)) { 13137 return true; 13138 } 13139 } 13140 } 13141 if (strings != null) { 13142 String flat = comp.flattenToString(); 13143 for (int i=0; i<strings.size(); i++) { 13144 if (flat.contains(strings.get(i))) { 13145 return true; 13146 } 13147 } 13148 } 13149 return false; 13150 } 13151 } 13152 13153 /** 13154 * There are three things that cmd can be: 13155 * - a flattened component name that matches an existing activity 13156 * - the cmd arg isn't the flattened component name of an existing activity: 13157 * dump all activity whose component contains the cmd as a substring 13158 * - A hex number of the ActivityRecord object instance. 13159 */ 13160 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13161 int opti, boolean dumpAll) { 13162 ArrayList<ActivityRecord> activities; 13163 13164 synchronized (this) { 13165 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13166 } 13167 13168 if (activities.size() <= 0) { 13169 return false; 13170 } 13171 13172 String[] newArgs = new String[args.length - opti]; 13173 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13174 13175 TaskRecord lastTask = null; 13176 boolean needSep = false; 13177 for (int i=activities.size()-1; i>=0; i--) { 13178 ActivityRecord r = activities.get(i); 13179 if (needSep) { 13180 pw.println(); 13181 } 13182 needSep = true; 13183 synchronized (this) { 13184 if (lastTask != r.task) { 13185 lastTask = r.task; 13186 pw.print("TASK "); pw.print(lastTask.affinity); 13187 pw.print(" id="); pw.println(lastTask.taskId); 13188 if (dumpAll) { 13189 lastTask.dump(pw, " "); 13190 } 13191 } 13192 } 13193 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13194 } 13195 return true; 13196 } 13197 13198 /** 13199 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13200 * there is a thread associated with the activity. 13201 */ 13202 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13203 final ActivityRecord r, String[] args, boolean dumpAll) { 13204 String innerPrefix = prefix + " "; 13205 synchronized (this) { 13206 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13207 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13208 pw.print(" pid="); 13209 if (r.app != null) pw.println(r.app.pid); 13210 else pw.println("(not running)"); 13211 if (dumpAll) { 13212 r.dump(pw, innerPrefix); 13213 } 13214 } 13215 if (r.app != null && r.app.thread != null) { 13216 // flush anything that is already in the PrintWriter since the thread is going 13217 // to write to the file descriptor directly 13218 pw.flush(); 13219 try { 13220 TransferPipe tp = new TransferPipe(); 13221 try { 13222 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13223 r.appToken, innerPrefix, args); 13224 tp.go(fd); 13225 } finally { 13226 tp.kill(); 13227 } 13228 } catch (IOException e) { 13229 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13230 } catch (RemoteException e) { 13231 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13232 } 13233 } 13234 } 13235 13236 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13237 int opti, boolean dumpAll, String dumpPackage) { 13238 boolean needSep = false; 13239 boolean onlyHistory = false; 13240 boolean printedAnything = false; 13241 13242 if ("history".equals(dumpPackage)) { 13243 if (opti < args.length && "-s".equals(args[opti])) { 13244 dumpAll = false; 13245 } 13246 onlyHistory = true; 13247 dumpPackage = null; 13248 } 13249 13250 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13251 if (!onlyHistory && dumpAll) { 13252 if (mRegisteredReceivers.size() > 0) { 13253 boolean printed = false; 13254 Iterator it = mRegisteredReceivers.values().iterator(); 13255 while (it.hasNext()) { 13256 ReceiverList r = (ReceiverList)it.next(); 13257 if (dumpPackage != null && (r.app == null || 13258 !dumpPackage.equals(r.app.info.packageName))) { 13259 continue; 13260 } 13261 if (!printed) { 13262 pw.println(" Registered Receivers:"); 13263 needSep = true; 13264 printed = true; 13265 printedAnything = true; 13266 } 13267 pw.print(" * "); pw.println(r); 13268 r.dump(pw, " "); 13269 } 13270 } 13271 13272 if (mReceiverResolver.dump(pw, needSep ? 13273 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13274 " ", dumpPackage, false, false)) { 13275 needSep = true; 13276 printedAnything = true; 13277 } 13278 } 13279 13280 for (BroadcastQueue q : mBroadcastQueues) { 13281 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13282 printedAnything |= needSep; 13283 } 13284 13285 needSep = true; 13286 13287 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13288 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13289 if (needSep) { 13290 pw.println(); 13291 } 13292 needSep = true; 13293 printedAnything = true; 13294 pw.print(" Sticky broadcasts for user "); 13295 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13296 StringBuilder sb = new StringBuilder(128); 13297 for (Map.Entry<String, ArrayList<Intent>> ent 13298 : mStickyBroadcasts.valueAt(user).entrySet()) { 13299 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13300 if (dumpAll) { 13301 pw.println(":"); 13302 ArrayList<Intent> intents = ent.getValue(); 13303 final int N = intents.size(); 13304 for (int i=0; i<N; i++) { 13305 sb.setLength(0); 13306 sb.append(" Intent: "); 13307 intents.get(i).toShortString(sb, false, true, false, false); 13308 pw.println(sb.toString()); 13309 Bundle bundle = intents.get(i).getExtras(); 13310 if (bundle != null) { 13311 pw.print(" "); 13312 pw.println(bundle.toString()); 13313 } 13314 } 13315 } else { 13316 pw.println(""); 13317 } 13318 } 13319 } 13320 } 13321 13322 if (!onlyHistory && dumpAll) { 13323 pw.println(); 13324 for (BroadcastQueue queue : mBroadcastQueues) { 13325 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13326 + queue.mBroadcastsScheduled); 13327 } 13328 pw.println(" mHandler:"); 13329 mHandler.dump(new PrintWriterPrinter(pw), " "); 13330 needSep = true; 13331 printedAnything = true; 13332 } 13333 13334 if (!printedAnything) { 13335 pw.println(" (nothing)"); 13336 } 13337 } 13338 13339 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13340 int opti, boolean dumpAll, String dumpPackage) { 13341 boolean needSep; 13342 boolean printedAnything = false; 13343 13344 ItemMatcher matcher = new ItemMatcher(); 13345 matcher.build(args, opti); 13346 13347 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13348 13349 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13350 printedAnything |= needSep; 13351 13352 if (mLaunchingProviders.size() > 0) { 13353 boolean printed = false; 13354 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13355 ContentProviderRecord r = mLaunchingProviders.get(i); 13356 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13357 continue; 13358 } 13359 if (!printed) { 13360 if (needSep) pw.println(); 13361 needSep = true; 13362 pw.println(" Launching content providers:"); 13363 printed = true; 13364 printedAnything = true; 13365 } 13366 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13367 pw.println(r); 13368 } 13369 } 13370 13371 if (mGrantedUriPermissions.size() > 0) { 13372 boolean printed = false; 13373 int dumpUid = -2; 13374 if (dumpPackage != null) { 13375 try { 13376 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13377 } catch (NameNotFoundException e) { 13378 dumpUid = -1; 13379 } 13380 } 13381 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13382 int uid = mGrantedUriPermissions.keyAt(i); 13383 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13384 continue; 13385 } 13386 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13387 if (!printed) { 13388 if (needSep) pw.println(); 13389 needSep = true; 13390 pw.println(" Granted Uri Permissions:"); 13391 printed = true; 13392 printedAnything = true; 13393 } 13394 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13395 for (UriPermission perm : perms.values()) { 13396 pw.print(" "); pw.println(perm); 13397 if (dumpAll) { 13398 perm.dump(pw, " "); 13399 } 13400 } 13401 } 13402 } 13403 13404 if (!printedAnything) { 13405 pw.println(" (nothing)"); 13406 } 13407 } 13408 13409 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13410 int opti, boolean dumpAll, String dumpPackage) { 13411 boolean printed = false; 13412 13413 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13414 13415 if (mIntentSenderRecords.size() > 0) { 13416 Iterator<WeakReference<PendingIntentRecord>> it 13417 = mIntentSenderRecords.values().iterator(); 13418 while (it.hasNext()) { 13419 WeakReference<PendingIntentRecord> ref = it.next(); 13420 PendingIntentRecord rec = ref != null ? ref.get(): null; 13421 if (dumpPackage != null && (rec == null 13422 || !dumpPackage.equals(rec.key.packageName))) { 13423 continue; 13424 } 13425 printed = true; 13426 if (rec != null) { 13427 pw.print(" * "); pw.println(rec); 13428 if (dumpAll) { 13429 rec.dump(pw, " "); 13430 } 13431 } else { 13432 pw.print(" * "); pw.println(ref); 13433 } 13434 } 13435 } 13436 13437 if (!printed) { 13438 pw.println(" (nothing)"); 13439 } 13440 } 13441 13442 private static final int dumpProcessList(PrintWriter pw, 13443 ActivityManagerService service, List list, 13444 String prefix, String normalLabel, String persistentLabel, 13445 String dumpPackage) { 13446 int numPers = 0; 13447 final int N = list.size()-1; 13448 for (int i=N; i>=0; i--) { 13449 ProcessRecord r = (ProcessRecord)list.get(i); 13450 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13451 continue; 13452 } 13453 pw.println(String.format("%s%s #%2d: %s", 13454 prefix, (r.persistent ? persistentLabel : normalLabel), 13455 i, r.toString())); 13456 if (r.persistent) { 13457 numPers++; 13458 } 13459 } 13460 return numPers; 13461 } 13462 13463 private static final boolean dumpProcessOomList(PrintWriter pw, 13464 ActivityManagerService service, List<ProcessRecord> origList, 13465 String prefix, String normalLabel, String persistentLabel, 13466 boolean inclDetails, String dumpPackage) { 13467 13468 ArrayList<Pair<ProcessRecord, Integer>> list 13469 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13470 for (int i=0; i<origList.size(); i++) { 13471 ProcessRecord r = origList.get(i); 13472 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13473 continue; 13474 } 13475 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13476 } 13477 13478 if (list.size() <= 0) { 13479 return false; 13480 } 13481 13482 Comparator<Pair<ProcessRecord, Integer>> comparator 13483 = new Comparator<Pair<ProcessRecord, Integer>>() { 13484 @Override 13485 public int compare(Pair<ProcessRecord, Integer> object1, 13486 Pair<ProcessRecord, Integer> object2) { 13487 if (object1.first.setAdj != object2.first.setAdj) { 13488 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13489 } 13490 if (object1.second.intValue() != object2.second.intValue()) { 13491 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13492 } 13493 return 0; 13494 } 13495 }; 13496 13497 Collections.sort(list, comparator); 13498 13499 final long curRealtime = SystemClock.elapsedRealtime(); 13500 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13501 final long curUptime = SystemClock.uptimeMillis(); 13502 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13503 13504 for (int i=list.size()-1; i>=0; i--) { 13505 ProcessRecord r = list.get(i).first; 13506 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13507 char schedGroup; 13508 switch (r.setSchedGroup) { 13509 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13510 schedGroup = 'B'; 13511 break; 13512 case Process.THREAD_GROUP_DEFAULT: 13513 schedGroup = 'F'; 13514 break; 13515 default: 13516 schedGroup = '?'; 13517 break; 13518 } 13519 char foreground; 13520 if (r.foregroundActivities) { 13521 foreground = 'A'; 13522 } else if (r.foregroundServices) { 13523 foreground = 'S'; 13524 } else { 13525 foreground = ' '; 13526 } 13527 String procState = ProcessList.makeProcStateString(r.curProcState); 13528 pw.print(prefix); 13529 pw.print(r.persistent ? persistentLabel : normalLabel); 13530 pw.print(" #"); 13531 int num = (origList.size()-1)-list.get(i).second; 13532 if (num < 10) pw.print(' '); 13533 pw.print(num); 13534 pw.print(": "); 13535 pw.print(oomAdj); 13536 pw.print(' '); 13537 pw.print(schedGroup); 13538 pw.print('/'); 13539 pw.print(foreground); 13540 pw.print('/'); 13541 pw.print(procState); 13542 pw.print(" trm:"); 13543 if (r.trimMemoryLevel < 10) pw.print(' '); 13544 pw.print(r.trimMemoryLevel); 13545 pw.print(' '); 13546 pw.print(r.toShortString()); 13547 pw.print(" ("); 13548 pw.print(r.adjType); 13549 pw.println(')'); 13550 if (r.adjSource != null || r.adjTarget != null) { 13551 pw.print(prefix); 13552 pw.print(" "); 13553 if (r.adjTarget instanceof ComponentName) { 13554 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13555 } else if (r.adjTarget != null) { 13556 pw.print(r.adjTarget.toString()); 13557 } else { 13558 pw.print("{null}"); 13559 } 13560 pw.print("<="); 13561 if (r.adjSource instanceof ProcessRecord) { 13562 pw.print("Proc{"); 13563 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13564 pw.println("}"); 13565 } else if (r.adjSource != null) { 13566 pw.println(r.adjSource.toString()); 13567 } else { 13568 pw.println("{null}"); 13569 } 13570 } 13571 if (inclDetails) { 13572 pw.print(prefix); 13573 pw.print(" "); 13574 pw.print("oom: max="); pw.print(r.maxAdj); 13575 pw.print(" curRaw="); pw.print(r.curRawAdj); 13576 pw.print(" setRaw="); pw.print(r.setRawAdj); 13577 pw.print(" cur="); pw.print(r.curAdj); 13578 pw.print(" set="); pw.println(r.setAdj); 13579 pw.print(prefix); 13580 pw.print(" "); 13581 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13582 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13583 pw.print(" lastPss="); pw.print(r.lastPss); 13584 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13585 pw.print(prefix); 13586 pw.print(" "); 13587 pw.print("cached="); pw.print(r.cached); 13588 pw.print(" empty="); pw.print(r.empty); 13589 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13590 13591 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13592 if (r.lastWakeTime != 0) { 13593 long wtime; 13594 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13595 synchronized (stats) { 13596 wtime = stats.getProcessWakeTime(r.info.uid, 13597 r.pid, curRealtime); 13598 } 13599 long timeUsed = wtime - r.lastWakeTime; 13600 pw.print(prefix); 13601 pw.print(" "); 13602 pw.print("keep awake over "); 13603 TimeUtils.formatDuration(realtimeSince, pw); 13604 pw.print(" used "); 13605 TimeUtils.formatDuration(timeUsed, pw); 13606 pw.print(" ("); 13607 pw.print((timeUsed*100)/realtimeSince); 13608 pw.println("%)"); 13609 } 13610 if (r.lastCpuTime != 0) { 13611 long timeUsed = r.curCpuTime - r.lastCpuTime; 13612 pw.print(prefix); 13613 pw.print(" "); 13614 pw.print("run cpu over "); 13615 TimeUtils.formatDuration(uptimeSince, pw); 13616 pw.print(" used "); 13617 TimeUtils.formatDuration(timeUsed, pw); 13618 pw.print(" ("); 13619 pw.print((timeUsed*100)/uptimeSince); 13620 pw.println("%)"); 13621 } 13622 } 13623 } 13624 } 13625 return true; 13626 } 13627 13628 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13629 String[] args) { 13630 ArrayList<ProcessRecord> procs; 13631 synchronized (this) { 13632 if (args != null && args.length > start 13633 && args[start].charAt(0) != '-') { 13634 procs = new ArrayList<ProcessRecord>(); 13635 int pid = -1; 13636 try { 13637 pid = Integer.parseInt(args[start]); 13638 } catch (NumberFormatException e) { 13639 } 13640 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13641 ProcessRecord proc = mLruProcesses.get(i); 13642 if (proc.pid == pid) { 13643 procs.add(proc); 13644 } else if (allPkgs && proc.pkgList != null 13645 && proc.pkgList.containsKey(args[start])) { 13646 procs.add(proc); 13647 } else if (proc.processName.equals(args[start])) { 13648 procs.add(proc); 13649 } 13650 } 13651 if (procs.size() <= 0) { 13652 return null; 13653 } 13654 } else { 13655 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13656 } 13657 } 13658 return procs; 13659 } 13660 13661 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13662 PrintWriter pw, String[] args) { 13663 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13664 if (procs == null) { 13665 pw.println("No process found for: " + args[0]); 13666 return; 13667 } 13668 13669 long uptime = SystemClock.uptimeMillis(); 13670 long realtime = SystemClock.elapsedRealtime(); 13671 pw.println("Applications Graphics Acceleration Info:"); 13672 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13673 13674 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13675 ProcessRecord r = procs.get(i); 13676 if (r.thread != null) { 13677 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13678 pw.flush(); 13679 try { 13680 TransferPipe tp = new TransferPipe(); 13681 try { 13682 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13683 tp.go(fd); 13684 } finally { 13685 tp.kill(); 13686 } 13687 } catch (IOException e) { 13688 pw.println("Failure while dumping the app: " + r); 13689 pw.flush(); 13690 } catch (RemoteException e) { 13691 pw.println("Got a RemoteException while dumping the app " + r); 13692 pw.flush(); 13693 } 13694 } 13695 } 13696 } 13697 13698 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13699 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13700 if (procs == null) { 13701 pw.println("No process found for: " + args[0]); 13702 return; 13703 } 13704 13705 pw.println("Applications Database Info:"); 13706 13707 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13708 ProcessRecord r = procs.get(i); 13709 if (r.thread != null) { 13710 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13711 pw.flush(); 13712 try { 13713 TransferPipe tp = new TransferPipe(); 13714 try { 13715 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13716 tp.go(fd); 13717 } finally { 13718 tp.kill(); 13719 } 13720 } catch (IOException e) { 13721 pw.println("Failure while dumping the app: " + r); 13722 pw.flush(); 13723 } catch (RemoteException e) { 13724 pw.println("Got a RemoteException while dumping the app " + r); 13725 pw.flush(); 13726 } 13727 } 13728 } 13729 } 13730 13731 final static class MemItem { 13732 final boolean isProc; 13733 final String label; 13734 final String shortLabel; 13735 final long pss; 13736 final int id; 13737 final boolean hasActivities; 13738 ArrayList<MemItem> subitems; 13739 13740 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13741 boolean _hasActivities) { 13742 isProc = true; 13743 label = _label; 13744 shortLabel = _shortLabel; 13745 pss = _pss; 13746 id = _id; 13747 hasActivities = _hasActivities; 13748 } 13749 13750 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13751 isProc = false; 13752 label = _label; 13753 shortLabel = _shortLabel; 13754 pss = _pss; 13755 id = _id; 13756 hasActivities = false; 13757 } 13758 } 13759 13760 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13761 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13762 if (sort && !isCompact) { 13763 Collections.sort(items, new Comparator<MemItem>() { 13764 @Override 13765 public int compare(MemItem lhs, MemItem rhs) { 13766 if (lhs.pss < rhs.pss) { 13767 return 1; 13768 } else if (lhs.pss > rhs.pss) { 13769 return -1; 13770 } 13771 return 0; 13772 } 13773 }); 13774 } 13775 13776 for (int i=0; i<items.size(); i++) { 13777 MemItem mi = items.get(i); 13778 if (!isCompact) { 13779 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13780 } else if (mi.isProc) { 13781 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13782 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13783 pw.println(mi.hasActivities ? ",a" : ",e"); 13784 } else { 13785 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13786 pw.println(mi.pss); 13787 } 13788 if (mi.subitems != null) { 13789 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13790 true, isCompact); 13791 } 13792 } 13793 } 13794 13795 // These are in KB. 13796 static final long[] DUMP_MEM_BUCKETS = new long[] { 13797 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13798 120*1024, 160*1024, 200*1024, 13799 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13800 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13801 }; 13802 13803 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13804 boolean stackLike) { 13805 int start = label.lastIndexOf('.'); 13806 if (start >= 0) start++; 13807 else start = 0; 13808 int end = label.length(); 13809 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13810 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13811 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13812 out.append(bucket); 13813 out.append(stackLike ? "MB." : "MB "); 13814 out.append(label, start, end); 13815 return; 13816 } 13817 } 13818 out.append(memKB/1024); 13819 out.append(stackLike ? "MB." : "MB "); 13820 out.append(label, start, end); 13821 } 13822 13823 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13824 ProcessList.NATIVE_ADJ, 13825 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13826 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13827 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13828 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13829 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13830 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13831 }; 13832 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13833 "Native", 13834 "System", "Persistent", "Persistent Service", "Foreground", 13835 "Visible", "Perceptible", 13836 "Heavy Weight", "Backup", 13837 "A Services", "Home", 13838 "Previous", "B Services", "Cached" 13839 }; 13840 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13841 "native", 13842 "sys", "pers", "persvc", "fore", 13843 "vis", "percept", 13844 "heavy", "backup", 13845 "servicea", "home", 13846 "prev", "serviceb", "cached" 13847 }; 13848 13849 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13850 long realtime, boolean isCheckinRequest, boolean isCompact) { 13851 if (isCheckinRequest || isCompact) { 13852 // short checkin version 13853 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13854 } else { 13855 pw.println("Applications Memory Usage (kB):"); 13856 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13857 } 13858 } 13859 13860 private static final int KSM_SHARED = 0; 13861 private static final int KSM_SHARING = 1; 13862 private static final int KSM_UNSHARED = 2; 13863 private static final int KSM_VOLATILE = 3; 13864 13865 private final long[] getKsmInfo() { 13866 long[] longOut = new long[4]; 13867 final int[] SINGLE_LONG_FORMAT = new int[] { 13868 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13869 }; 13870 long[] longTmp = new long[1]; 13871 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13872 SINGLE_LONG_FORMAT, null, longTmp, null); 13873 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13874 longTmp[0] = 0; 13875 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13876 SINGLE_LONG_FORMAT, null, longTmp, null); 13877 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13878 longTmp[0] = 0; 13879 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13880 SINGLE_LONG_FORMAT, null, longTmp, null); 13881 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13882 longTmp[0] = 0; 13883 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13884 SINGLE_LONG_FORMAT, null, longTmp, null); 13885 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13886 return longOut; 13887 } 13888 13889 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13890 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13891 boolean dumpDetails = false; 13892 boolean dumpFullDetails = false; 13893 boolean dumpDalvik = false; 13894 boolean oomOnly = false; 13895 boolean isCompact = false; 13896 boolean localOnly = false; 13897 boolean packages = false; 13898 13899 int opti = 0; 13900 while (opti < args.length) { 13901 String opt = args[opti]; 13902 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13903 break; 13904 } 13905 opti++; 13906 if ("-a".equals(opt)) { 13907 dumpDetails = true; 13908 dumpFullDetails = true; 13909 dumpDalvik = true; 13910 } else if ("-d".equals(opt)) { 13911 dumpDalvik = true; 13912 } else if ("-c".equals(opt)) { 13913 isCompact = true; 13914 } else if ("--oom".equals(opt)) { 13915 oomOnly = true; 13916 } else if ("--local".equals(opt)) { 13917 localOnly = true; 13918 } else if ("--package".equals(opt)) { 13919 packages = true; 13920 } else if ("-h".equals(opt)) { 13921 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13922 pw.println(" -a: include all available information for each process."); 13923 pw.println(" -d: include dalvik details when dumping process details."); 13924 pw.println(" -c: dump in a compact machine-parseable representation."); 13925 pw.println(" --oom: only show processes organized by oom adj."); 13926 pw.println(" --local: only collect details locally, don't call process."); 13927 pw.println(" --package: interpret process arg as package, dumping all"); 13928 pw.println(" processes that have loaded that package."); 13929 pw.println("If [process] is specified it can be the name or "); 13930 pw.println("pid of a specific process to dump."); 13931 return; 13932 } else { 13933 pw.println("Unknown argument: " + opt + "; use -h for help"); 13934 } 13935 } 13936 13937 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13938 long uptime = SystemClock.uptimeMillis(); 13939 long realtime = SystemClock.elapsedRealtime(); 13940 final long[] tmpLong = new long[1]; 13941 13942 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13943 if (procs == null) { 13944 // No Java processes. Maybe they want to print a native process. 13945 if (args != null && args.length > opti 13946 && args[opti].charAt(0) != '-') { 13947 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13948 = new ArrayList<ProcessCpuTracker.Stats>(); 13949 updateCpuStatsNow(); 13950 int findPid = -1; 13951 try { 13952 findPid = Integer.parseInt(args[opti]); 13953 } catch (NumberFormatException e) { 13954 } 13955 synchronized (mProcessCpuTracker) { 13956 final int N = mProcessCpuTracker.countStats(); 13957 for (int i=0; i<N; i++) { 13958 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13959 if (st.pid == findPid || (st.baseName != null 13960 && st.baseName.equals(args[opti]))) { 13961 nativeProcs.add(st); 13962 } 13963 } 13964 } 13965 if (nativeProcs.size() > 0) { 13966 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13967 isCompact); 13968 Debug.MemoryInfo mi = null; 13969 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13970 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13971 final int pid = r.pid; 13972 if (!isCheckinRequest && dumpDetails) { 13973 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13974 } 13975 if (mi == null) { 13976 mi = new Debug.MemoryInfo(); 13977 } 13978 if (dumpDetails || (!brief && !oomOnly)) { 13979 Debug.getMemoryInfo(pid, mi); 13980 } else { 13981 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13982 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13983 } 13984 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13985 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13986 if (isCheckinRequest) { 13987 pw.println(); 13988 } 13989 } 13990 return; 13991 } 13992 } 13993 pw.println("No process found for: " + args[opti]); 13994 return; 13995 } 13996 13997 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13998 dumpDetails = true; 13999 } 14000 14001 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14002 14003 String[] innerArgs = new String[args.length-opti]; 14004 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14005 14006 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14007 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14008 long nativePss = 0; 14009 long dalvikPss = 0; 14010 long otherPss = 0; 14011 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14012 14013 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14014 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14015 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14016 14017 long totalPss = 0; 14018 long cachedPss = 0; 14019 14020 Debug.MemoryInfo mi = null; 14021 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14022 final ProcessRecord r = procs.get(i); 14023 final IApplicationThread thread; 14024 final int pid; 14025 final int oomAdj; 14026 final boolean hasActivities; 14027 synchronized (this) { 14028 thread = r.thread; 14029 pid = r.pid; 14030 oomAdj = r.getSetAdjWithServices(); 14031 hasActivities = r.activities.size() > 0; 14032 } 14033 if (thread != null) { 14034 if (!isCheckinRequest && dumpDetails) { 14035 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14036 } 14037 if (mi == null) { 14038 mi = new Debug.MemoryInfo(); 14039 } 14040 if (dumpDetails || (!brief && !oomOnly)) { 14041 Debug.getMemoryInfo(pid, mi); 14042 } else { 14043 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14044 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14045 } 14046 if (dumpDetails) { 14047 if (localOnly) { 14048 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14049 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14050 if (isCheckinRequest) { 14051 pw.println(); 14052 } 14053 } else { 14054 try { 14055 pw.flush(); 14056 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14057 dumpDalvik, innerArgs); 14058 } catch (RemoteException e) { 14059 if (!isCheckinRequest) { 14060 pw.println("Got RemoteException!"); 14061 pw.flush(); 14062 } 14063 } 14064 } 14065 } 14066 14067 final long myTotalPss = mi.getTotalPss(); 14068 final long myTotalUss = mi.getTotalUss(); 14069 14070 synchronized (this) { 14071 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14072 // Record this for posterity if the process has been stable. 14073 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14074 } 14075 } 14076 14077 if (!isCheckinRequest && mi != null) { 14078 totalPss += myTotalPss; 14079 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14080 (hasActivities ? " / activities)" : ")"), 14081 r.processName, myTotalPss, pid, hasActivities); 14082 procMems.add(pssItem); 14083 procMemsMap.put(pid, pssItem); 14084 14085 nativePss += mi.nativePss; 14086 dalvikPss += mi.dalvikPss; 14087 otherPss += mi.otherPss; 14088 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14089 long mem = mi.getOtherPss(j); 14090 miscPss[j] += mem; 14091 otherPss -= mem; 14092 } 14093 14094 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14095 cachedPss += myTotalPss; 14096 } 14097 14098 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14099 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14100 || oomIndex == (oomPss.length-1)) { 14101 oomPss[oomIndex] += myTotalPss; 14102 if (oomProcs[oomIndex] == null) { 14103 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14104 } 14105 oomProcs[oomIndex].add(pssItem); 14106 break; 14107 } 14108 } 14109 } 14110 } 14111 } 14112 14113 long nativeProcTotalPss = 0; 14114 14115 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14116 // If we are showing aggregations, also look for native processes to 14117 // include so that our aggregations are more accurate. 14118 updateCpuStatsNow(); 14119 synchronized (mProcessCpuTracker) { 14120 final int N = mProcessCpuTracker.countStats(); 14121 for (int i=0; i<N; i++) { 14122 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14123 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14124 if (mi == null) { 14125 mi = new Debug.MemoryInfo(); 14126 } 14127 if (!brief && !oomOnly) { 14128 Debug.getMemoryInfo(st.pid, mi); 14129 } else { 14130 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14131 mi.nativePrivateDirty = (int)tmpLong[0]; 14132 } 14133 14134 final long myTotalPss = mi.getTotalPss(); 14135 totalPss += myTotalPss; 14136 nativeProcTotalPss += myTotalPss; 14137 14138 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14139 st.name, myTotalPss, st.pid, false); 14140 procMems.add(pssItem); 14141 14142 nativePss += mi.nativePss; 14143 dalvikPss += mi.dalvikPss; 14144 otherPss += mi.otherPss; 14145 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14146 long mem = mi.getOtherPss(j); 14147 miscPss[j] += mem; 14148 otherPss -= mem; 14149 } 14150 oomPss[0] += myTotalPss; 14151 if (oomProcs[0] == null) { 14152 oomProcs[0] = new ArrayList<MemItem>(); 14153 } 14154 oomProcs[0].add(pssItem); 14155 } 14156 } 14157 } 14158 14159 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14160 14161 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14162 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14163 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14164 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14165 String label = Debug.MemoryInfo.getOtherLabel(j); 14166 catMems.add(new MemItem(label, label, miscPss[j], j)); 14167 } 14168 14169 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14170 for (int j=0; j<oomPss.length; j++) { 14171 if (oomPss[j] != 0) { 14172 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14173 : DUMP_MEM_OOM_LABEL[j]; 14174 MemItem item = new MemItem(label, label, oomPss[j], 14175 DUMP_MEM_OOM_ADJ[j]); 14176 item.subitems = oomProcs[j]; 14177 oomMems.add(item); 14178 } 14179 } 14180 14181 if (!brief && !oomOnly && !isCompact) { 14182 pw.println(); 14183 pw.println("Total PSS by process:"); 14184 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14185 pw.println(); 14186 } 14187 if (!isCompact) { 14188 pw.println("Total PSS by OOM adjustment:"); 14189 } 14190 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14191 if (!brief && !oomOnly) { 14192 PrintWriter out = categoryPw != null ? categoryPw : pw; 14193 if (!isCompact) { 14194 out.println(); 14195 out.println("Total PSS by category:"); 14196 } 14197 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14198 } 14199 if (!isCompact) { 14200 pw.println(); 14201 } 14202 MemInfoReader memInfo = new MemInfoReader(); 14203 memInfo.readMemInfo(); 14204 if (nativeProcTotalPss > 0) { 14205 synchronized (this) { 14206 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14207 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14208 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14209 } 14210 } 14211 if (!brief) { 14212 if (!isCompact) { 14213 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14214 pw.print(" kB (status "); 14215 switch (mLastMemoryLevel) { 14216 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14217 pw.println("normal)"); 14218 break; 14219 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14220 pw.println("moderate)"); 14221 break; 14222 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14223 pw.println("low)"); 14224 break; 14225 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14226 pw.println("critical)"); 14227 break; 14228 default: 14229 pw.print(mLastMemoryLevel); 14230 pw.println(")"); 14231 break; 14232 } 14233 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14234 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14235 pw.print(cachedPss); pw.print(" cached pss + "); 14236 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14237 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14238 } else { 14239 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14240 pw.print(cachedPss + memInfo.getCachedSizeKb() 14241 + memInfo.getFreeSizeKb()); pw.print(","); 14242 pw.println(totalPss - cachedPss); 14243 } 14244 } 14245 if (!isCompact) { 14246 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14247 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14248 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14249 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14250 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14251 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14252 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14253 } 14254 if (!brief) { 14255 if (memInfo.getZramTotalSizeKb() != 0) { 14256 if (!isCompact) { 14257 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14258 pw.print(" kB physical used for "); 14259 pw.print(memInfo.getSwapTotalSizeKb() 14260 - memInfo.getSwapFreeSizeKb()); 14261 pw.print(" kB in swap ("); 14262 pw.print(memInfo.getSwapTotalSizeKb()); 14263 pw.println(" kB total swap)"); 14264 } else { 14265 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14266 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14267 pw.println(memInfo.getSwapFreeSizeKb()); 14268 } 14269 } 14270 final long[] ksm = getKsmInfo(); 14271 if (!isCompact) { 14272 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14273 || ksm[KSM_VOLATILE] != 0) { 14274 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14275 pw.print(" kB saved from shared "); 14276 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14277 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14278 pw.print(" kB unshared; "); 14279 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14280 } 14281 pw.print(" Tuning: "); 14282 pw.print(ActivityManager.staticGetMemoryClass()); 14283 pw.print(" (large "); 14284 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14285 pw.print("), oom "); 14286 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14287 pw.print(" kB"); 14288 pw.print(", restore limit "); 14289 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14290 pw.print(" kB"); 14291 if (ActivityManager.isLowRamDeviceStatic()) { 14292 pw.print(" (low-ram)"); 14293 } 14294 if (ActivityManager.isHighEndGfx()) { 14295 pw.print(" (high-end-gfx)"); 14296 } 14297 pw.println(); 14298 } else { 14299 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14300 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14301 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14302 pw.print("tuning,"); 14303 pw.print(ActivityManager.staticGetMemoryClass()); 14304 pw.print(','); 14305 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14306 pw.print(','); 14307 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14308 if (ActivityManager.isLowRamDeviceStatic()) { 14309 pw.print(",low-ram"); 14310 } 14311 if (ActivityManager.isHighEndGfx()) { 14312 pw.print(",high-end-gfx"); 14313 } 14314 pw.println(); 14315 } 14316 } 14317 } 14318 } 14319 14320 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14321 String name) { 14322 sb.append(" "); 14323 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14324 sb.append(' '); 14325 sb.append(ProcessList.makeProcStateString(procState)); 14326 sb.append(' '); 14327 ProcessList.appendRamKb(sb, pss); 14328 sb.append(" kB: "); 14329 sb.append(name); 14330 } 14331 14332 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14333 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14334 sb.append(" ("); 14335 sb.append(mi.pid); 14336 sb.append(") "); 14337 sb.append(mi.adjType); 14338 sb.append('\n'); 14339 if (mi.adjReason != null) { 14340 sb.append(" "); 14341 sb.append(mi.adjReason); 14342 sb.append('\n'); 14343 } 14344 } 14345 14346 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14347 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14348 for (int i=0, N=memInfos.size(); i<N; i++) { 14349 ProcessMemInfo mi = memInfos.get(i); 14350 infoMap.put(mi.pid, mi); 14351 } 14352 updateCpuStatsNow(); 14353 synchronized (mProcessCpuTracker) { 14354 final int N = mProcessCpuTracker.countStats(); 14355 for (int i=0; i<N; i++) { 14356 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14357 if (st.vsize > 0) { 14358 long pss = Debug.getPss(st.pid, null); 14359 if (pss > 0) { 14360 if (infoMap.indexOfKey(st.pid) < 0) { 14361 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14362 ProcessList.NATIVE_ADJ, -1, "native", null); 14363 mi.pss = pss; 14364 memInfos.add(mi); 14365 } 14366 } 14367 } 14368 } 14369 } 14370 14371 long totalPss = 0; 14372 for (int i=0, N=memInfos.size(); i<N; i++) { 14373 ProcessMemInfo mi = memInfos.get(i); 14374 if (mi.pss == 0) { 14375 mi.pss = Debug.getPss(mi.pid, null); 14376 } 14377 totalPss += mi.pss; 14378 } 14379 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14380 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14381 if (lhs.oomAdj != rhs.oomAdj) { 14382 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14383 } 14384 if (lhs.pss != rhs.pss) { 14385 return lhs.pss < rhs.pss ? 1 : -1; 14386 } 14387 return 0; 14388 } 14389 }); 14390 14391 StringBuilder tag = new StringBuilder(128); 14392 StringBuilder stack = new StringBuilder(128); 14393 tag.append("Low on memory -- "); 14394 appendMemBucket(tag, totalPss, "total", false); 14395 appendMemBucket(stack, totalPss, "total", true); 14396 14397 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14398 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14399 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14400 14401 boolean firstLine = true; 14402 int lastOomAdj = Integer.MIN_VALUE; 14403 long extraNativeRam = 0; 14404 long cachedPss = 0; 14405 for (int i=0, N=memInfos.size(); i<N; i++) { 14406 ProcessMemInfo mi = memInfos.get(i); 14407 14408 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14409 cachedPss += mi.pss; 14410 } 14411 14412 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14413 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14414 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14415 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14416 if (lastOomAdj != mi.oomAdj) { 14417 lastOomAdj = mi.oomAdj; 14418 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14419 tag.append(" / "); 14420 } 14421 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14422 if (firstLine) { 14423 stack.append(":"); 14424 firstLine = false; 14425 } 14426 stack.append("\n\t at "); 14427 } else { 14428 stack.append("$"); 14429 } 14430 } else { 14431 tag.append(" "); 14432 stack.append("$"); 14433 } 14434 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14435 appendMemBucket(tag, mi.pss, mi.name, false); 14436 } 14437 appendMemBucket(stack, mi.pss, mi.name, true); 14438 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14439 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14440 stack.append("("); 14441 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14442 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14443 stack.append(DUMP_MEM_OOM_LABEL[k]); 14444 stack.append(":"); 14445 stack.append(DUMP_MEM_OOM_ADJ[k]); 14446 } 14447 } 14448 stack.append(")"); 14449 } 14450 } 14451 14452 appendMemInfo(fullNativeBuilder, mi); 14453 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14454 // The short form only has native processes that are >= 1MB. 14455 if (mi.pss >= 1000) { 14456 appendMemInfo(shortNativeBuilder, mi); 14457 } else { 14458 extraNativeRam += mi.pss; 14459 } 14460 } else { 14461 // Short form has all other details, but if we have collected RAM 14462 // from smaller native processes let's dump a summary of that. 14463 if (extraNativeRam > 0) { 14464 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14465 -1, extraNativeRam, "(Other native)"); 14466 shortNativeBuilder.append('\n'); 14467 extraNativeRam = 0; 14468 } 14469 appendMemInfo(fullJavaBuilder, mi); 14470 } 14471 } 14472 14473 fullJavaBuilder.append(" "); 14474 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14475 fullJavaBuilder.append(" kB: TOTAL\n"); 14476 14477 MemInfoReader memInfo = new MemInfoReader(); 14478 memInfo.readMemInfo(); 14479 final long[] infos = memInfo.getRawInfo(); 14480 14481 StringBuilder memInfoBuilder = new StringBuilder(1024); 14482 Debug.getMemInfo(infos); 14483 memInfoBuilder.append(" MemInfo: "); 14484 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14485 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14486 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14487 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14488 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14489 memInfoBuilder.append(" "); 14490 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14491 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14492 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14493 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14494 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14495 memInfoBuilder.append(" ZRAM: "); 14496 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14497 memInfoBuilder.append(" kB RAM, "); 14498 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14499 memInfoBuilder.append(" kB swap total, "); 14500 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14501 memInfoBuilder.append(" kB swap free\n"); 14502 } 14503 final long[] ksm = getKsmInfo(); 14504 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14505 || ksm[KSM_VOLATILE] != 0) { 14506 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14507 memInfoBuilder.append(" kB saved from shared "); 14508 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14509 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14510 memInfoBuilder.append(" kB unshared; "); 14511 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14512 } 14513 memInfoBuilder.append(" Free RAM: "); 14514 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14515 + memInfo.getFreeSizeKb()); 14516 memInfoBuilder.append(" kB\n"); 14517 memInfoBuilder.append(" Used RAM: "); 14518 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14519 memInfoBuilder.append(" kB\n"); 14520 memInfoBuilder.append(" Lost RAM: "); 14521 memInfoBuilder.append(memInfo.getTotalSizeKb() 14522 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14523 - memInfo.getKernelUsedSizeKb()); 14524 memInfoBuilder.append(" kB\n"); 14525 Slog.i(TAG, "Low on memory:"); 14526 Slog.i(TAG, shortNativeBuilder.toString()); 14527 Slog.i(TAG, fullJavaBuilder.toString()); 14528 Slog.i(TAG, memInfoBuilder.toString()); 14529 14530 StringBuilder dropBuilder = new StringBuilder(1024); 14531 /* 14532 StringWriter oomSw = new StringWriter(); 14533 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14534 StringWriter catSw = new StringWriter(); 14535 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14536 String[] emptyArgs = new String[] { }; 14537 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14538 oomPw.flush(); 14539 String oomString = oomSw.toString(); 14540 */ 14541 dropBuilder.append("Low on memory:"); 14542 dropBuilder.append(stack); 14543 dropBuilder.append('\n'); 14544 dropBuilder.append(fullNativeBuilder); 14545 dropBuilder.append(fullJavaBuilder); 14546 dropBuilder.append('\n'); 14547 dropBuilder.append(memInfoBuilder); 14548 dropBuilder.append('\n'); 14549 /* 14550 dropBuilder.append(oomString); 14551 dropBuilder.append('\n'); 14552 */ 14553 StringWriter catSw = new StringWriter(); 14554 synchronized (ActivityManagerService.this) { 14555 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14556 String[] emptyArgs = new String[] { }; 14557 catPw.println(); 14558 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14559 catPw.println(); 14560 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14561 false, false, null); 14562 catPw.println(); 14563 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14564 catPw.flush(); 14565 } 14566 dropBuilder.append(catSw.toString()); 14567 addErrorToDropBox("lowmem", null, "system_server", null, 14568 null, tag.toString(), dropBuilder.toString(), null, null); 14569 //Slog.i(TAG, "Sent to dropbox:"); 14570 //Slog.i(TAG, dropBuilder.toString()); 14571 synchronized (ActivityManagerService.this) { 14572 long now = SystemClock.uptimeMillis(); 14573 if (mLastMemUsageReportTime < now) { 14574 mLastMemUsageReportTime = now; 14575 } 14576 } 14577 } 14578 14579 /** 14580 * Searches array of arguments for the specified string 14581 * @param args array of argument strings 14582 * @param value value to search for 14583 * @return true if the value is contained in the array 14584 */ 14585 private static boolean scanArgs(String[] args, String value) { 14586 if (args != null) { 14587 for (String arg : args) { 14588 if (value.equals(arg)) { 14589 return true; 14590 } 14591 } 14592 } 14593 return false; 14594 } 14595 14596 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14597 ContentProviderRecord cpr, boolean always) { 14598 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14599 14600 if (!inLaunching || always) { 14601 synchronized (cpr) { 14602 cpr.launchingApp = null; 14603 cpr.notifyAll(); 14604 } 14605 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14606 String names[] = cpr.info.authority.split(";"); 14607 for (int j = 0; j < names.length; j++) { 14608 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14609 } 14610 } 14611 14612 for (int i=0; i<cpr.connections.size(); i++) { 14613 ContentProviderConnection conn = cpr.connections.get(i); 14614 if (conn.waiting) { 14615 // If this connection is waiting for the provider, then we don't 14616 // need to mess with its process unless we are always removing 14617 // or for some reason the provider is not currently launching. 14618 if (inLaunching && !always) { 14619 continue; 14620 } 14621 } 14622 ProcessRecord capp = conn.client; 14623 conn.dead = true; 14624 if (conn.stableCount > 0) { 14625 if (!capp.persistent && capp.thread != null 14626 && capp.pid != 0 14627 && capp.pid != MY_PID) { 14628 capp.kill("depends on provider " 14629 + cpr.name.flattenToShortString() 14630 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14631 } 14632 } else if (capp.thread != null && conn.provider.provider != null) { 14633 try { 14634 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14635 } catch (RemoteException e) { 14636 } 14637 // In the protocol here, we don't expect the client to correctly 14638 // clean up this connection, we'll just remove it. 14639 cpr.connections.remove(i); 14640 conn.client.conProviders.remove(conn); 14641 } 14642 } 14643 14644 if (inLaunching && always) { 14645 mLaunchingProviders.remove(cpr); 14646 } 14647 return inLaunching; 14648 } 14649 14650 /** 14651 * Main code for cleaning up a process when it has gone away. This is 14652 * called both as a result of the process dying, or directly when stopping 14653 * a process when running in single process mode. 14654 * 14655 * @return Returns true if the given process has been restarted, so the 14656 * app that was passed in must remain on the process lists. 14657 */ 14658 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14659 boolean restarting, boolean allowRestart, int index) { 14660 if (index >= 0) { 14661 removeLruProcessLocked(app); 14662 ProcessList.remove(app.pid); 14663 } 14664 14665 mProcessesToGc.remove(app); 14666 mPendingPssProcesses.remove(app); 14667 14668 // Dismiss any open dialogs. 14669 if (app.crashDialog != null && !app.forceCrashReport) { 14670 app.crashDialog.dismiss(); 14671 app.crashDialog = null; 14672 } 14673 if (app.anrDialog != null) { 14674 app.anrDialog.dismiss(); 14675 app.anrDialog = null; 14676 } 14677 if (app.waitDialog != null) { 14678 app.waitDialog.dismiss(); 14679 app.waitDialog = null; 14680 } 14681 14682 app.crashing = false; 14683 app.notResponding = false; 14684 14685 app.resetPackageList(mProcessStats); 14686 app.unlinkDeathRecipient(); 14687 app.makeInactive(mProcessStats); 14688 app.waitingToKill = null; 14689 app.forcingToForeground = null; 14690 updateProcessForegroundLocked(app, false, false); 14691 app.foregroundActivities = false; 14692 app.hasShownUi = false; 14693 app.treatLikeActivity = false; 14694 app.hasAboveClient = false; 14695 app.hasClientActivities = false; 14696 14697 mServices.killServicesLocked(app, allowRestart); 14698 14699 boolean restart = false; 14700 14701 // Remove published content providers. 14702 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14703 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14704 final boolean always = app.bad || !allowRestart; 14705 if (removeDyingProviderLocked(app, cpr, always) || always) { 14706 // We left the provider in the launching list, need to 14707 // restart it. 14708 restart = true; 14709 } 14710 14711 cpr.provider = null; 14712 cpr.proc = null; 14713 } 14714 app.pubProviders.clear(); 14715 14716 // Take care of any launching providers waiting for this process. 14717 if (checkAppInLaunchingProvidersLocked(app, false)) { 14718 restart = true; 14719 } 14720 14721 // Unregister from connected content providers. 14722 if (!app.conProviders.isEmpty()) { 14723 for (int i=0; i<app.conProviders.size(); i++) { 14724 ContentProviderConnection conn = app.conProviders.get(i); 14725 conn.provider.connections.remove(conn); 14726 } 14727 app.conProviders.clear(); 14728 } 14729 14730 // At this point there may be remaining entries in mLaunchingProviders 14731 // where we were the only one waiting, so they are no longer of use. 14732 // Look for these and clean up if found. 14733 // XXX Commented out for now. Trying to figure out a way to reproduce 14734 // the actual situation to identify what is actually going on. 14735 if (false) { 14736 for (int i=0; i<mLaunchingProviders.size(); i++) { 14737 ContentProviderRecord cpr = (ContentProviderRecord) 14738 mLaunchingProviders.get(i); 14739 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14740 synchronized (cpr) { 14741 cpr.launchingApp = null; 14742 cpr.notifyAll(); 14743 } 14744 } 14745 } 14746 } 14747 14748 skipCurrentReceiverLocked(app); 14749 14750 // Unregister any receivers. 14751 for (int i=app.receivers.size()-1; i>=0; i--) { 14752 removeReceiverLocked(app.receivers.valueAt(i)); 14753 } 14754 app.receivers.clear(); 14755 14756 // If the app is undergoing backup, tell the backup manager about it 14757 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14758 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14759 + mBackupTarget.appInfo + " died during backup"); 14760 try { 14761 IBackupManager bm = IBackupManager.Stub.asInterface( 14762 ServiceManager.getService(Context.BACKUP_SERVICE)); 14763 bm.agentDisconnected(app.info.packageName); 14764 } catch (RemoteException e) { 14765 // can't happen; backup manager is local 14766 } 14767 } 14768 14769 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14770 ProcessChangeItem item = mPendingProcessChanges.get(i); 14771 if (item.pid == app.pid) { 14772 mPendingProcessChanges.remove(i); 14773 mAvailProcessChanges.add(item); 14774 } 14775 } 14776 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14777 14778 // If the caller is restarting this app, then leave it in its 14779 // current lists and let the caller take care of it. 14780 if (restarting) { 14781 return false; 14782 } 14783 14784 if (!app.persistent || app.isolated) { 14785 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14786 "Removing non-persistent process during cleanup: " + app); 14787 mProcessNames.remove(app.processName, app.uid); 14788 mIsolatedProcesses.remove(app.uid); 14789 if (mHeavyWeightProcess == app) { 14790 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14791 mHeavyWeightProcess.userId, 0)); 14792 mHeavyWeightProcess = null; 14793 } 14794 } else if (!app.removed) { 14795 // This app is persistent, so we need to keep its record around. 14796 // If it is not already on the pending app list, add it there 14797 // and start a new process for it. 14798 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14799 mPersistentStartingProcesses.add(app); 14800 restart = true; 14801 } 14802 } 14803 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14804 "Clean-up removing on hold: " + app); 14805 mProcessesOnHold.remove(app); 14806 14807 if (app == mHomeProcess) { 14808 mHomeProcess = null; 14809 } 14810 if (app == mPreviousProcess) { 14811 mPreviousProcess = null; 14812 } 14813 14814 if (restart && !app.isolated) { 14815 // We have components that still need to be running in the 14816 // process, so re-launch it. 14817 if (index < 0) { 14818 ProcessList.remove(app.pid); 14819 } 14820 mProcessNames.put(app.processName, app.uid, app); 14821 startProcessLocked(app, "restart", app.processName); 14822 return true; 14823 } else if (app.pid > 0 && app.pid != MY_PID) { 14824 // Goodbye! 14825 boolean removed; 14826 synchronized (mPidsSelfLocked) { 14827 mPidsSelfLocked.remove(app.pid); 14828 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14829 } 14830 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14831 if (app.isolated) { 14832 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14833 } 14834 app.setPid(0); 14835 } 14836 return false; 14837 } 14838 14839 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14840 // Look through the content providers we are waiting to have launched, 14841 // and if any run in this process then either schedule a restart of 14842 // the process or kill the client waiting for it if this process has 14843 // gone bad. 14844 int NL = mLaunchingProviders.size(); 14845 boolean restart = false; 14846 for (int i=0; i<NL; i++) { 14847 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14848 if (cpr.launchingApp == app) { 14849 if (!alwaysBad && !app.bad) { 14850 restart = true; 14851 } else { 14852 removeDyingProviderLocked(app, cpr, true); 14853 // cpr should have been removed from mLaunchingProviders 14854 NL = mLaunchingProviders.size(); 14855 i--; 14856 } 14857 } 14858 } 14859 return restart; 14860 } 14861 14862 // ========================================================= 14863 // SERVICES 14864 // ========================================================= 14865 14866 @Override 14867 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14868 int flags) { 14869 enforceNotIsolatedCaller("getServices"); 14870 synchronized (this) { 14871 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14872 } 14873 } 14874 14875 @Override 14876 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14877 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14878 synchronized (this) { 14879 return mServices.getRunningServiceControlPanelLocked(name); 14880 } 14881 } 14882 14883 @Override 14884 public ComponentName startService(IApplicationThread caller, Intent service, 14885 String resolvedType, int userId) { 14886 enforceNotIsolatedCaller("startService"); 14887 // Refuse possible leaked file descriptors 14888 if (service != null && service.hasFileDescriptors() == true) { 14889 throw new IllegalArgumentException("File descriptors passed in Intent"); 14890 } 14891 14892 if (DEBUG_SERVICE) 14893 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14894 synchronized(this) { 14895 final int callingPid = Binder.getCallingPid(); 14896 final int callingUid = Binder.getCallingUid(); 14897 final long origId = Binder.clearCallingIdentity(); 14898 ComponentName res = mServices.startServiceLocked(caller, service, 14899 resolvedType, callingPid, callingUid, userId); 14900 Binder.restoreCallingIdentity(origId); 14901 return res; 14902 } 14903 } 14904 14905 ComponentName startServiceInPackage(int uid, 14906 Intent service, String resolvedType, int userId) { 14907 synchronized(this) { 14908 if (DEBUG_SERVICE) 14909 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14910 final long origId = Binder.clearCallingIdentity(); 14911 ComponentName res = mServices.startServiceLocked(null, service, 14912 resolvedType, -1, uid, userId); 14913 Binder.restoreCallingIdentity(origId); 14914 return res; 14915 } 14916 } 14917 14918 @Override 14919 public int stopService(IApplicationThread caller, Intent service, 14920 String resolvedType, int userId) { 14921 enforceNotIsolatedCaller("stopService"); 14922 // Refuse possible leaked file descriptors 14923 if (service != null && service.hasFileDescriptors() == true) { 14924 throw new IllegalArgumentException("File descriptors passed in Intent"); 14925 } 14926 14927 synchronized(this) { 14928 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14929 } 14930 } 14931 14932 @Override 14933 public IBinder peekService(Intent service, String resolvedType) { 14934 enforceNotIsolatedCaller("peekService"); 14935 // Refuse possible leaked file descriptors 14936 if (service != null && service.hasFileDescriptors() == true) { 14937 throw new IllegalArgumentException("File descriptors passed in Intent"); 14938 } 14939 synchronized(this) { 14940 return mServices.peekServiceLocked(service, resolvedType); 14941 } 14942 } 14943 14944 @Override 14945 public boolean stopServiceToken(ComponentName className, IBinder token, 14946 int startId) { 14947 synchronized(this) { 14948 return mServices.stopServiceTokenLocked(className, token, startId); 14949 } 14950 } 14951 14952 @Override 14953 public void setServiceForeground(ComponentName className, IBinder token, 14954 int id, Notification notification, boolean removeNotification) { 14955 synchronized(this) { 14956 mServices.setServiceForegroundLocked(className, token, id, notification, 14957 removeNotification); 14958 } 14959 } 14960 14961 @Override 14962 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14963 boolean requireFull, String name, String callerPackage) { 14964 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14965 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14966 } 14967 14968 int unsafeConvertIncomingUser(int userId) { 14969 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14970 ? mCurrentUserId : userId; 14971 } 14972 14973 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14974 int allowMode, String name, String callerPackage) { 14975 final int callingUserId = UserHandle.getUserId(callingUid); 14976 if (callingUserId == userId) { 14977 return userId; 14978 } 14979 14980 // Note that we may be accessing mCurrentUserId outside of a lock... 14981 // shouldn't be a big deal, if this is being called outside 14982 // of a locked context there is intrinsically a race with 14983 // the value the caller will receive and someone else changing it. 14984 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14985 // we will switch to the calling user if access to the current user fails. 14986 int targetUserId = unsafeConvertIncomingUser(userId); 14987 14988 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14989 final boolean allow; 14990 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14991 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14992 // If the caller has this permission, they always pass go. And collect $200. 14993 allow = true; 14994 } else if (allowMode == ALLOW_FULL_ONLY) { 14995 // We require full access, sucks to be you. 14996 allow = false; 14997 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14998 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14999 // If the caller does not have either permission, they are always doomed. 15000 allow = false; 15001 } else if (allowMode == ALLOW_NON_FULL) { 15002 // We are blanket allowing non-full access, you lucky caller! 15003 allow = true; 15004 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15005 // We may or may not allow this depending on whether the two users are 15006 // in the same profile. 15007 synchronized (mUserProfileGroupIdsSelfLocked) { 15008 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15009 UserInfo.NO_PROFILE_GROUP_ID); 15010 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15011 UserInfo.NO_PROFILE_GROUP_ID); 15012 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15013 && callingProfile == targetProfile; 15014 } 15015 } else { 15016 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15017 } 15018 if (!allow) { 15019 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15020 // In this case, they would like to just execute as their 15021 // owner user instead of failing. 15022 targetUserId = callingUserId; 15023 } else { 15024 StringBuilder builder = new StringBuilder(128); 15025 builder.append("Permission Denial: "); 15026 builder.append(name); 15027 if (callerPackage != null) { 15028 builder.append(" from "); 15029 builder.append(callerPackage); 15030 } 15031 builder.append(" asks to run as user "); 15032 builder.append(userId); 15033 builder.append(" but is calling from user "); 15034 builder.append(UserHandle.getUserId(callingUid)); 15035 builder.append("; this requires "); 15036 builder.append(INTERACT_ACROSS_USERS_FULL); 15037 if (allowMode != ALLOW_FULL_ONLY) { 15038 builder.append(" or "); 15039 builder.append(INTERACT_ACROSS_USERS); 15040 } 15041 String msg = builder.toString(); 15042 Slog.w(TAG, msg); 15043 throw new SecurityException(msg); 15044 } 15045 } 15046 } 15047 if (!allowAll && targetUserId < 0) { 15048 throw new IllegalArgumentException( 15049 "Call does not support special user #" + targetUserId); 15050 } 15051 // Check shell permission 15052 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15053 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15054 targetUserId)) { 15055 throw new SecurityException("Shell does not have permission to access user " 15056 + targetUserId + "\n " + Debug.getCallers(3)); 15057 } 15058 } 15059 return targetUserId; 15060 } 15061 15062 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15063 String className, int flags) { 15064 boolean result = false; 15065 // For apps that don't have pre-defined UIDs, check for permission 15066 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15067 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15068 if (ActivityManager.checkUidPermission( 15069 INTERACT_ACROSS_USERS, 15070 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15071 ComponentName comp = new ComponentName(aInfo.packageName, className); 15072 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15073 + " requests FLAG_SINGLE_USER, but app does not hold " 15074 + INTERACT_ACROSS_USERS; 15075 Slog.w(TAG, msg); 15076 throw new SecurityException(msg); 15077 } 15078 // Permission passed 15079 result = true; 15080 } 15081 } else if ("system".equals(componentProcessName)) { 15082 result = true; 15083 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15084 // Phone app and persistent apps are allowed to export singleuser providers. 15085 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15086 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15087 } 15088 if (DEBUG_MU) { 15089 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15090 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15091 } 15092 return result; 15093 } 15094 15095 /** 15096 * Checks to see if the caller is in the same app as the singleton 15097 * component, or the component is in a special app. It allows special apps 15098 * to export singleton components but prevents exporting singleton 15099 * components for regular apps. 15100 */ 15101 boolean isValidSingletonCall(int callingUid, int componentUid) { 15102 int componentAppId = UserHandle.getAppId(componentUid); 15103 return UserHandle.isSameApp(callingUid, componentUid) 15104 || componentAppId == Process.SYSTEM_UID 15105 || componentAppId == Process.PHONE_UID 15106 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15107 == PackageManager.PERMISSION_GRANTED; 15108 } 15109 15110 public int bindService(IApplicationThread caller, IBinder token, 15111 Intent service, String resolvedType, 15112 IServiceConnection connection, int flags, int userId) { 15113 enforceNotIsolatedCaller("bindService"); 15114 15115 // Refuse possible leaked file descriptors 15116 if (service != null && service.hasFileDescriptors() == true) { 15117 throw new IllegalArgumentException("File descriptors passed in Intent"); 15118 } 15119 15120 synchronized(this) { 15121 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15122 connection, flags, userId); 15123 } 15124 } 15125 15126 public boolean unbindService(IServiceConnection connection) { 15127 synchronized (this) { 15128 return mServices.unbindServiceLocked(connection); 15129 } 15130 } 15131 15132 public void publishService(IBinder token, Intent intent, IBinder service) { 15133 // Refuse possible leaked file descriptors 15134 if (intent != null && intent.hasFileDescriptors() == true) { 15135 throw new IllegalArgumentException("File descriptors passed in Intent"); 15136 } 15137 15138 synchronized(this) { 15139 if (!(token instanceof ServiceRecord)) { 15140 throw new IllegalArgumentException("Invalid service token"); 15141 } 15142 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15143 } 15144 } 15145 15146 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15147 // Refuse possible leaked file descriptors 15148 if (intent != null && intent.hasFileDescriptors() == true) { 15149 throw new IllegalArgumentException("File descriptors passed in Intent"); 15150 } 15151 15152 synchronized(this) { 15153 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15154 } 15155 } 15156 15157 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15158 synchronized(this) { 15159 if (!(token instanceof ServiceRecord)) { 15160 throw new IllegalArgumentException("Invalid service token"); 15161 } 15162 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15163 } 15164 } 15165 15166 // ========================================================= 15167 // BACKUP AND RESTORE 15168 // ========================================================= 15169 15170 // Cause the target app to be launched if necessary and its backup agent 15171 // instantiated. The backup agent will invoke backupAgentCreated() on the 15172 // activity manager to announce its creation. 15173 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15174 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15175 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15176 15177 synchronized(this) { 15178 // !!! TODO: currently no check here that we're already bound 15179 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15180 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15181 synchronized (stats) { 15182 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15183 } 15184 15185 // Backup agent is now in use, its package can't be stopped. 15186 try { 15187 AppGlobals.getPackageManager().setPackageStoppedState( 15188 app.packageName, false, UserHandle.getUserId(app.uid)); 15189 } catch (RemoteException e) { 15190 } catch (IllegalArgumentException e) { 15191 Slog.w(TAG, "Failed trying to unstop package " 15192 + app.packageName + ": " + e); 15193 } 15194 15195 BackupRecord r = new BackupRecord(ss, app, backupMode); 15196 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15197 ? new ComponentName(app.packageName, app.backupAgentName) 15198 : new ComponentName("android", "FullBackupAgent"); 15199 // startProcessLocked() returns existing proc's record if it's already running 15200 ProcessRecord proc = startProcessLocked(app.processName, app, 15201 false, 0, "backup", hostingName, false, false, false); 15202 if (proc == null) { 15203 Slog.e(TAG, "Unable to start backup agent process " + r); 15204 return false; 15205 } 15206 15207 r.app = proc; 15208 mBackupTarget = r; 15209 mBackupAppName = app.packageName; 15210 15211 // Try not to kill the process during backup 15212 updateOomAdjLocked(proc); 15213 15214 // If the process is already attached, schedule the creation of the backup agent now. 15215 // If it is not yet live, this will be done when it attaches to the framework. 15216 if (proc.thread != null) { 15217 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15218 try { 15219 proc.thread.scheduleCreateBackupAgent(app, 15220 compatibilityInfoForPackageLocked(app), backupMode); 15221 } catch (RemoteException e) { 15222 // Will time out on the backup manager side 15223 } 15224 } else { 15225 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15226 } 15227 // Invariants: at this point, the target app process exists and the application 15228 // is either already running or in the process of coming up. mBackupTarget and 15229 // mBackupAppName describe the app, so that when it binds back to the AM we 15230 // know that it's scheduled for a backup-agent operation. 15231 } 15232 15233 return true; 15234 } 15235 15236 @Override 15237 public void clearPendingBackup() { 15238 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15239 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15240 15241 synchronized (this) { 15242 mBackupTarget = null; 15243 mBackupAppName = null; 15244 } 15245 } 15246 15247 // A backup agent has just come up 15248 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15249 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15250 + " = " + agent); 15251 15252 synchronized(this) { 15253 if (!agentPackageName.equals(mBackupAppName)) { 15254 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15255 return; 15256 } 15257 } 15258 15259 long oldIdent = Binder.clearCallingIdentity(); 15260 try { 15261 IBackupManager bm = IBackupManager.Stub.asInterface( 15262 ServiceManager.getService(Context.BACKUP_SERVICE)); 15263 bm.agentConnected(agentPackageName, agent); 15264 } catch (RemoteException e) { 15265 // can't happen; the backup manager service is local 15266 } catch (Exception e) { 15267 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15268 e.printStackTrace(); 15269 } finally { 15270 Binder.restoreCallingIdentity(oldIdent); 15271 } 15272 } 15273 15274 // done with this agent 15275 public void unbindBackupAgent(ApplicationInfo appInfo) { 15276 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15277 if (appInfo == null) { 15278 Slog.w(TAG, "unbind backup agent for null app"); 15279 return; 15280 } 15281 15282 synchronized(this) { 15283 try { 15284 if (mBackupAppName == null) { 15285 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15286 return; 15287 } 15288 15289 if (!mBackupAppName.equals(appInfo.packageName)) { 15290 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15291 return; 15292 } 15293 15294 // Not backing this app up any more; reset its OOM adjustment 15295 final ProcessRecord proc = mBackupTarget.app; 15296 updateOomAdjLocked(proc); 15297 15298 // If the app crashed during backup, 'thread' will be null here 15299 if (proc.thread != null) { 15300 try { 15301 proc.thread.scheduleDestroyBackupAgent(appInfo, 15302 compatibilityInfoForPackageLocked(appInfo)); 15303 } catch (Exception e) { 15304 Slog.e(TAG, "Exception when unbinding backup agent:"); 15305 e.printStackTrace(); 15306 } 15307 } 15308 } finally { 15309 mBackupTarget = null; 15310 mBackupAppName = null; 15311 } 15312 } 15313 } 15314 // ========================================================= 15315 // BROADCASTS 15316 // ========================================================= 15317 15318 private final List getStickiesLocked(String action, IntentFilter filter, 15319 List cur, int userId) { 15320 final ContentResolver resolver = mContext.getContentResolver(); 15321 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15322 if (stickies == null) { 15323 return cur; 15324 } 15325 final ArrayList<Intent> list = stickies.get(action); 15326 if (list == null) { 15327 return cur; 15328 } 15329 int N = list.size(); 15330 for (int i=0; i<N; i++) { 15331 Intent intent = list.get(i); 15332 if (filter.match(resolver, intent, true, TAG) >= 0) { 15333 if (cur == null) { 15334 cur = new ArrayList<Intent>(); 15335 } 15336 cur.add(intent); 15337 } 15338 } 15339 return cur; 15340 } 15341 15342 boolean isPendingBroadcastProcessLocked(int pid) { 15343 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15344 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15345 } 15346 15347 void skipPendingBroadcastLocked(int pid) { 15348 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15349 for (BroadcastQueue queue : mBroadcastQueues) { 15350 queue.skipPendingBroadcastLocked(pid); 15351 } 15352 } 15353 15354 // The app just attached; send any pending broadcasts that it should receive 15355 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15356 boolean didSomething = false; 15357 for (BroadcastQueue queue : mBroadcastQueues) { 15358 didSomething |= queue.sendPendingBroadcastsLocked(app); 15359 } 15360 return didSomething; 15361 } 15362 15363 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15364 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15365 enforceNotIsolatedCaller("registerReceiver"); 15366 int callingUid; 15367 int callingPid; 15368 synchronized(this) { 15369 ProcessRecord callerApp = null; 15370 if (caller != null) { 15371 callerApp = getRecordForAppLocked(caller); 15372 if (callerApp == null) { 15373 throw new SecurityException( 15374 "Unable to find app for caller " + caller 15375 + " (pid=" + Binder.getCallingPid() 15376 + ") when registering receiver " + receiver); 15377 } 15378 if (callerApp.info.uid != Process.SYSTEM_UID && 15379 !callerApp.pkgList.containsKey(callerPackage) && 15380 !"android".equals(callerPackage)) { 15381 throw new SecurityException("Given caller package " + callerPackage 15382 + " is not running in process " + callerApp); 15383 } 15384 callingUid = callerApp.info.uid; 15385 callingPid = callerApp.pid; 15386 } else { 15387 callerPackage = null; 15388 callingUid = Binder.getCallingUid(); 15389 callingPid = Binder.getCallingPid(); 15390 } 15391 15392 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15393 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15394 15395 List allSticky = null; 15396 15397 // Look for any matching sticky broadcasts... 15398 Iterator actions = filter.actionsIterator(); 15399 if (actions != null) { 15400 while (actions.hasNext()) { 15401 String action = (String)actions.next(); 15402 allSticky = getStickiesLocked(action, filter, allSticky, 15403 UserHandle.USER_ALL); 15404 allSticky = getStickiesLocked(action, filter, allSticky, 15405 UserHandle.getUserId(callingUid)); 15406 } 15407 } else { 15408 allSticky = getStickiesLocked(null, filter, allSticky, 15409 UserHandle.USER_ALL); 15410 allSticky = getStickiesLocked(null, filter, allSticky, 15411 UserHandle.getUserId(callingUid)); 15412 } 15413 15414 // The first sticky in the list is returned directly back to 15415 // the client. 15416 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15417 15418 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15419 + ": " + sticky); 15420 15421 if (receiver == null) { 15422 return sticky; 15423 } 15424 15425 ReceiverList rl 15426 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15427 if (rl == null) { 15428 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15429 userId, receiver); 15430 if (rl.app != null) { 15431 rl.app.receivers.add(rl); 15432 } else { 15433 try { 15434 receiver.asBinder().linkToDeath(rl, 0); 15435 } catch (RemoteException e) { 15436 return sticky; 15437 } 15438 rl.linkedToDeath = true; 15439 } 15440 mRegisteredReceivers.put(receiver.asBinder(), rl); 15441 } else if (rl.uid != callingUid) { 15442 throw new IllegalArgumentException( 15443 "Receiver requested to register for uid " + callingUid 15444 + " was previously registered for uid " + rl.uid); 15445 } else if (rl.pid != callingPid) { 15446 throw new IllegalArgumentException( 15447 "Receiver requested to register for pid " + callingPid 15448 + " was previously registered for pid " + rl.pid); 15449 } else if (rl.userId != userId) { 15450 throw new IllegalArgumentException( 15451 "Receiver requested to register for user " + userId 15452 + " was previously registered for user " + rl.userId); 15453 } 15454 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15455 permission, callingUid, userId); 15456 rl.add(bf); 15457 if (!bf.debugCheck()) { 15458 Slog.w(TAG, "==> For Dynamic broadast"); 15459 } 15460 mReceiverResolver.addFilter(bf); 15461 15462 // Enqueue broadcasts for all existing stickies that match 15463 // this filter. 15464 if (allSticky != null) { 15465 ArrayList receivers = new ArrayList(); 15466 receivers.add(bf); 15467 15468 int N = allSticky.size(); 15469 for (int i=0; i<N; i++) { 15470 Intent intent = (Intent)allSticky.get(i); 15471 BroadcastQueue queue = broadcastQueueForIntent(intent); 15472 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15473 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15474 null, null, false, true, true, -1); 15475 queue.enqueueParallelBroadcastLocked(r); 15476 queue.scheduleBroadcastsLocked(); 15477 } 15478 } 15479 15480 return sticky; 15481 } 15482 } 15483 15484 public void unregisterReceiver(IIntentReceiver receiver) { 15485 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15486 15487 final long origId = Binder.clearCallingIdentity(); 15488 try { 15489 boolean doTrim = false; 15490 15491 synchronized(this) { 15492 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15493 if (rl != null) { 15494 if (rl.curBroadcast != null) { 15495 BroadcastRecord r = rl.curBroadcast; 15496 final boolean doNext = finishReceiverLocked( 15497 receiver.asBinder(), r.resultCode, r.resultData, 15498 r.resultExtras, r.resultAbort); 15499 if (doNext) { 15500 doTrim = true; 15501 r.queue.processNextBroadcast(false); 15502 } 15503 } 15504 15505 if (rl.app != null) { 15506 rl.app.receivers.remove(rl); 15507 } 15508 removeReceiverLocked(rl); 15509 if (rl.linkedToDeath) { 15510 rl.linkedToDeath = false; 15511 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15512 } 15513 } 15514 } 15515 15516 // If we actually concluded any broadcasts, we might now be able 15517 // to trim the recipients' apps from our working set 15518 if (doTrim) { 15519 trimApplications(); 15520 return; 15521 } 15522 15523 } finally { 15524 Binder.restoreCallingIdentity(origId); 15525 } 15526 } 15527 15528 void removeReceiverLocked(ReceiverList rl) { 15529 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15530 int N = rl.size(); 15531 for (int i=0; i<N; i++) { 15532 mReceiverResolver.removeFilter(rl.get(i)); 15533 } 15534 } 15535 15536 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15537 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15538 ProcessRecord r = mLruProcesses.get(i); 15539 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15540 try { 15541 r.thread.dispatchPackageBroadcast(cmd, packages); 15542 } catch (RemoteException ex) { 15543 } 15544 } 15545 } 15546 } 15547 15548 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15549 int callingUid, int[] users) { 15550 List<ResolveInfo> receivers = null; 15551 try { 15552 HashSet<ComponentName> singleUserReceivers = null; 15553 boolean scannedFirstReceivers = false; 15554 for (int user : users) { 15555 // Skip users that have Shell restrictions 15556 if (callingUid == Process.SHELL_UID 15557 && getUserManagerLocked().hasUserRestriction( 15558 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15559 continue; 15560 } 15561 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15562 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15563 if (user != 0 && newReceivers != null) { 15564 // If this is not the primary user, we need to check for 15565 // any receivers that should be filtered out. 15566 for (int i=0; i<newReceivers.size(); i++) { 15567 ResolveInfo ri = newReceivers.get(i); 15568 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15569 newReceivers.remove(i); 15570 i--; 15571 } 15572 } 15573 } 15574 if (newReceivers != null && newReceivers.size() == 0) { 15575 newReceivers = null; 15576 } 15577 if (receivers == null) { 15578 receivers = newReceivers; 15579 } else if (newReceivers != null) { 15580 // We need to concatenate the additional receivers 15581 // found with what we have do far. This would be easy, 15582 // but we also need to de-dup any receivers that are 15583 // singleUser. 15584 if (!scannedFirstReceivers) { 15585 // Collect any single user receivers we had already retrieved. 15586 scannedFirstReceivers = true; 15587 for (int i=0; i<receivers.size(); i++) { 15588 ResolveInfo ri = receivers.get(i); 15589 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15590 ComponentName cn = new ComponentName( 15591 ri.activityInfo.packageName, ri.activityInfo.name); 15592 if (singleUserReceivers == null) { 15593 singleUserReceivers = new HashSet<ComponentName>(); 15594 } 15595 singleUserReceivers.add(cn); 15596 } 15597 } 15598 } 15599 // Add the new results to the existing results, tracking 15600 // and de-dupping single user receivers. 15601 for (int i=0; i<newReceivers.size(); i++) { 15602 ResolveInfo ri = newReceivers.get(i); 15603 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15604 ComponentName cn = new ComponentName( 15605 ri.activityInfo.packageName, ri.activityInfo.name); 15606 if (singleUserReceivers == null) { 15607 singleUserReceivers = new HashSet<ComponentName>(); 15608 } 15609 if (!singleUserReceivers.contains(cn)) { 15610 singleUserReceivers.add(cn); 15611 receivers.add(ri); 15612 } 15613 } else { 15614 receivers.add(ri); 15615 } 15616 } 15617 } 15618 } 15619 } catch (RemoteException ex) { 15620 // pm is in same process, this will never happen. 15621 } 15622 return receivers; 15623 } 15624 15625 private final int broadcastIntentLocked(ProcessRecord callerApp, 15626 String callerPackage, Intent intent, String resolvedType, 15627 IIntentReceiver resultTo, int resultCode, String resultData, 15628 Bundle map, String requiredPermission, int appOp, 15629 boolean ordered, boolean sticky, int callingPid, int callingUid, 15630 int userId) { 15631 intent = new Intent(intent); 15632 15633 // By default broadcasts do not go to stopped apps. 15634 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15635 15636 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15637 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15638 + " ordered=" + ordered + " userid=" + userId); 15639 if ((resultTo != null) && !ordered) { 15640 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15641 } 15642 15643 userId = handleIncomingUser(callingPid, callingUid, userId, 15644 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15645 15646 // Make sure that the user who is receiving this broadcast is started. 15647 // If not, we will just skip it. 15648 15649 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15650 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15651 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15652 Slog.w(TAG, "Skipping broadcast of " + intent 15653 + ": user " + userId + " is stopped"); 15654 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15655 } 15656 } 15657 15658 /* 15659 * Prevent non-system code (defined here to be non-persistent 15660 * processes) from sending protected broadcasts. 15661 */ 15662 int callingAppId = UserHandle.getAppId(callingUid); 15663 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15664 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15665 || callingAppId == Process.NFC_UID || callingUid == 0) { 15666 // Always okay. 15667 } else if (callerApp == null || !callerApp.persistent) { 15668 try { 15669 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15670 intent.getAction())) { 15671 String msg = "Permission Denial: not allowed to send broadcast " 15672 + intent.getAction() + " from pid=" 15673 + callingPid + ", uid=" + callingUid; 15674 Slog.w(TAG, msg); 15675 throw new SecurityException(msg); 15676 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15677 // Special case for compatibility: we don't want apps to send this, 15678 // but historically it has not been protected and apps may be using it 15679 // to poke their own app widget. So, instead of making it protected, 15680 // just limit it to the caller. 15681 if (callerApp == null) { 15682 String msg = "Permission Denial: not allowed to send broadcast " 15683 + intent.getAction() + " from unknown caller."; 15684 Slog.w(TAG, msg); 15685 throw new SecurityException(msg); 15686 } else if (intent.getComponent() != null) { 15687 // They are good enough to send to an explicit component... verify 15688 // it is being sent to the calling app. 15689 if (!intent.getComponent().getPackageName().equals( 15690 callerApp.info.packageName)) { 15691 String msg = "Permission Denial: not allowed to send broadcast " 15692 + intent.getAction() + " to " 15693 + intent.getComponent().getPackageName() + " from " 15694 + callerApp.info.packageName; 15695 Slog.w(TAG, msg); 15696 throw new SecurityException(msg); 15697 } 15698 } else { 15699 // Limit broadcast to their own package. 15700 intent.setPackage(callerApp.info.packageName); 15701 } 15702 } 15703 } catch (RemoteException e) { 15704 Slog.w(TAG, "Remote exception", e); 15705 return ActivityManager.BROADCAST_SUCCESS; 15706 } 15707 } 15708 15709 final String action = intent.getAction(); 15710 if (action != null) { 15711 switch (action) { 15712 case Intent.ACTION_UID_REMOVED: 15713 case Intent.ACTION_PACKAGE_REMOVED: 15714 case Intent.ACTION_PACKAGE_CHANGED: 15715 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15716 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15717 // Handle special intents: if this broadcast is from the package 15718 // manager about a package being removed, we need to remove all of 15719 // its activities from the history stack. 15720 if (checkComponentPermission( 15721 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15722 callingPid, callingUid, -1, true) 15723 != PackageManager.PERMISSION_GRANTED) { 15724 String msg = "Permission Denial: " + intent.getAction() 15725 + " broadcast from " + callerPackage + " (pid=" + callingPid 15726 + ", uid=" + callingUid + ")" 15727 + " requires " 15728 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15729 Slog.w(TAG, msg); 15730 throw new SecurityException(msg); 15731 } 15732 switch (action) { 15733 case Intent.ACTION_UID_REMOVED: 15734 final Bundle intentExtras = intent.getExtras(); 15735 final int uid = intentExtras != null 15736 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15737 if (uid >= 0) { 15738 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15739 synchronized (bs) { 15740 bs.removeUidStatsLocked(uid); 15741 } 15742 mAppOpsService.uidRemoved(uid); 15743 } 15744 break; 15745 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15746 // If resources are unavailable just force stop all those packages 15747 // and flush the attribute cache as well. 15748 String list[] = 15749 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15750 if (list != null && list.length > 0) { 15751 for (int i = 0; i < list.length; i++) { 15752 forceStopPackageLocked(list[i], -1, false, true, true, 15753 false, false, userId, "storage unmount"); 15754 } 15755 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15756 sendPackageBroadcastLocked( 15757 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15758 userId); 15759 } 15760 break; 15761 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15762 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15763 break; 15764 case Intent.ACTION_PACKAGE_REMOVED: 15765 case Intent.ACTION_PACKAGE_CHANGED: 15766 Uri data = intent.getData(); 15767 String ssp; 15768 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15769 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15770 boolean fullUninstall = removed && 15771 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15772 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15773 forceStopPackageLocked(ssp, UserHandle.getAppId( 15774 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15775 false, true, true, false, fullUninstall, userId, 15776 removed ? "pkg removed" : "pkg changed"); 15777 } 15778 if (removed) { 15779 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15780 new String[] {ssp}, userId); 15781 if (fullUninstall) { 15782 mAppOpsService.packageRemoved( 15783 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15784 15785 // Remove all permissions granted from/to this package 15786 removeUriPermissionsForPackageLocked(ssp, userId, true); 15787 15788 removeTasksByPackageNameLocked(ssp, userId); 15789 } 15790 } else { 15791 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15792 } 15793 } 15794 break; 15795 } 15796 break; 15797 case Intent.ACTION_PACKAGE_ADDED: 15798 // Special case for adding a package: by default turn on compatibility mode. 15799 Uri data = intent.getData(); 15800 String ssp; 15801 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15802 final boolean replacing = 15803 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15804 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15805 15806 if (replacing) { 15807 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15808 } 15809 } 15810 break; 15811 case Intent.ACTION_TIMEZONE_CHANGED: 15812 // If this is the time zone changed action, queue up a message that will reset 15813 // the timezone of all currently running processes. This message will get 15814 // queued up before the broadcast happens. 15815 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15816 break; 15817 case Intent.ACTION_TIME_CHANGED: 15818 // If the user set the time, let all running processes know. 15819 final int is24Hour = 15820 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15821 : 0; 15822 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15823 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15824 synchronized (stats) { 15825 stats.noteCurrentTimeChangedLocked(); 15826 } 15827 break; 15828 case Intent.ACTION_CLEAR_DNS_CACHE: 15829 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15830 break; 15831 case Proxy.PROXY_CHANGE_ACTION: 15832 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15833 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15834 break; 15835 } 15836 } 15837 15838 // Add to the sticky list if requested. 15839 if (sticky) { 15840 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15841 callingPid, callingUid) 15842 != PackageManager.PERMISSION_GRANTED) { 15843 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15844 + callingPid + ", uid=" + callingUid 15845 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15846 Slog.w(TAG, msg); 15847 throw new SecurityException(msg); 15848 } 15849 if (requiredPermission != null) { 15850 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15851 + " and enforce permission " + requiredPermission); 15852 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15853 } 15854 if (intent.getComponent() != null) { 15855 throw new SecurityException( 15856 "Sticky broadcasts can't target a specific component"); 15857 } 15858 // We use userId directly here, since the "all" target is maintained 15859 // as a separate set of sticky broadcasts. 15860 if (userId != UserHandle.USER_ALL) { 15861 // But first, if this is not a broadcast to all users, then 15862 // make sure it doesn't conflict with an existing broadcast to 15863 // all users. 15864 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15865 UserHandle.USER_ALL); 15866 if (stickies != null) { 15867 ArrayList<Intent> list = stickies.get(intent.getAction()); 15868 if (list != null) { 15869 int N = list.size(); 15870 int i; 15871 for (i=0; i<N; i++) { 15872 if (intent.filterEquals(list.get(i))) { 15873 throw new IllegalArgumentException( 15874 "Sticky broadcast " + intent + " for user " 15875 + userId + " conflicts with existing global broadcast"); 15876 } 15877 } 15878 } 15879 } 15880 } 15881 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15882 if (stickies == null) { 15883 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15884 mStickyBroadcasts.put(userId, stickies); 15885 } 15886 ArrayList<Intent> list = stickies.get(intent.getAction()); 15887 if (list == null) { 15888 list = new ArrayList<Intent>(); 15889 stickies.put(intent.getAction(), list); 15890 } 15891 int N = list.size(); 15892 int i; 15893 for (i=0; i<N; i++) { 15894 if (intent.filterEquals(list.get(i))) { 15895 // This sticky already exists, replace it. 15896 list.set(i, new Intent(intent)); 15897 break; 15898 } 15899 } 15900 if (i >= N) { 15901 list.add(new Intent(intent)); 15902 } 15903 } 15904 15905 int[] users; 15906 if (userId == UserHandle.USER_ALL) { 15907 // Caller wants broadcast to go to all started users. 15908 users = mStartedUserArray; 15909 } else { 15910 // Caller wants broadcast to go to one specific user. 15911 users = new int[] {userId}; 15912 } 15913 15914 // Figure out who all will receive this broadcast. 15915 List receivers = null; 15916 List<BroadcastFilter> registeredReceivers = null; 15917 // Need to resolve the intent to interested receivers... 15918 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15919 == 0) { 15920 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15921 } 15922 if (intent.getComponent() == null) { 15923 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15924 // Query one target user at a time, excluding shell-restricted users 15925 UserManagerService ums = getUserManagerLocked(); 15926 for (int i = 0; i < users.length; i++) { 15927 if (ums.hasUserRestriction( 15928 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15929 continue; 15930 } 15931 List<BroadcastFilter> registeredReceiversForUser = 15932 mReceiverResolver.queryIntent(intent, 15933 resolvedType, false, users[i]); 15934 if (registeredReceivers == null) { 15935 registeredReceivers = registeredReceiversForUser; 15936 } else if (registeredReceiversForUser != null) { 15937 registeredReceivers.addAll(registeredReceiversForUser); 15938 } 15939 } 15940 } else { 15941 registeredReceivers = mReceiverResolver.queryIntent(intent, 15942 resolvedType, false, userId); 15943 } 15944 } 15945 15946 final boolean replacePending = 15947 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15948 15949 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15950 + " replacePending=" + replacePending); 15951 15952 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15953 if (!ordered && NR > 0) { 15954 // If we are not serializing this broadcast, then send the 15955 // registered receivers separately so they don't wait for the 15956 // components to be launched. 15957 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15958 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15959 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15960 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15961 ordered, sticky, false, userId); 15962 if (DEBUG_BROADCAST) Slog.v( 15963 TAG, "Enqueueing parallel broadcast " + r); 15964 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15965 if (!replaced) { 15966 queue.enqueueParallelBroadcastLocked(r); 15967 queue.scheduleBroadcastsLocked(); 15968 } 15969 registeredReceivers = null; 15970 NR = 0; 15971 } 15972 15973 // Merge into one list. 15974 int ir = 0; 15975 if (receivers != null) { 15976 // A special case for PACKAGE_ADDED: do not allow the package 15977 // being added to see this broadcast. This prevents them from 15978 // using this as a back door to get run as soon as they are 15979 // installed. Maybe in the future we want to have a special install 15980 // broadcast or such for apps, but we'd like to deliberately make 15981 // this decision. 15982 String skipPackages[] = null; 15983 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15984 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15985 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15986 Uri data = intent.getData(); 15987 if (data != null) { 15988 String pkgName = data.getSchemeSpecificPart(); 15989 if (pkgName != null) { 15990 skipPackages = new String[] { pkgName }; 15991 } 15992 } 15993 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15994 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15995 } 15996 if (skipPackages != null && (skipPackages.length > 0)) { 15997 for (String skipPackage : skipPackages) { 15998 if (skipPackage != null) { 15999 int NT = receivers.size(); 16000 for (int it=0; it<NT; it++) { 16001 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16002 if (curt.activityInfo.packageName.equals(skipPackage)) { 16003 receivers.remove(it); 16004 it--; 16005 NT--; 16006 } 16007 } 16008 } 16009 } 16010 } 16011 16012 int NT = receivers != null ? receivers.size() : 0; 16013 int it = 0; 16014 ResolveInfo curt = null; 16015 BroadcastFilter curr = null; 16016 while (it < NT && ir < NR) { 16017 if (curt == null) { 16018 curt = (ResolveInfo)receivers.get(it); 16019 } 16020 if (curr == null) { 16021 curr = registeredReceivers.get(ir); 16022 } 16023 if (curr.getPriority() >= curt.priority) { 16024 // Insert this broadcast record into the final list. 16025 receivers.add(it, curr); 16026 ir++; 16027 curr = null; 16028 it++; 16029 NT++; 16030 } else { 16031 // Skip to the next ResolveInfo in the final list. 16032 it++; 16033 curt = null; 16034 } 16035 } 16036 } 16037 while (ir < NR) { 16038 if (receivers == null) { 16039 receivers = new ArrayList(); 16040 } 16041 receivers.add(registeredReceivers.get(ir)); 16042 ir++; 16043 } 16044 16045 if ((receivers != null && receivers.size() > 0) 16046 || resultTo != null) { 16047 BroadcastQueue queue = broadcastQueueForIntent(intent); 16048 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16049 callerPackage, callingPid, callingUid, resolvedType, 16050 requiredPermission, appOp, receivers, resultTo, resultCode, 16051 resultData, map, ordered, sticky, false, userId); 16052 if (DEBUG_BROADCAST) Slog.v( 16053 TAG, "Enqueueing ordered broadcast " + r 16054 + ": prev had " + queue.mOrderedBroadcasts.size()); 16055 if (DEBUG_BROADCAST) { 16056 int seq = r.intent.getIntExtra("seq", -1); 16057 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16058 } 16059 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16060 if (!replaced) { 16061 queue.enqueueOrderedBroadcastLocked(r); 16062 queue.scheduleBroadcastsLocked(); 16063 } 16064 } 16065 16066 return ActivityManager.BROADCAST_SUCCESS; 16067 } 16068 16069 final Intent verifyBroadcastLocked(Intent intent) { 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 int flags = intent.getFlags(); 16076 16077 if (!mProcessesReady) { 16078 // if the caller really truly claims to know what they're doing, go 16079 // ahead and allow the broadcast without launching any receivers 16080 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16081 intent = new Intent(intent); 16082 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16083 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16084 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16085 + " before boot completion"); 16086 throw new IllegalStateException("Cannot broadcast before boot completed"); 16087 } 16088 } 16089 16090 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16091 throw new IllegalArgumentException( 16092 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16093 } 16094 16095 return intent; 16096 } 16097 16098 public final int broadcastIntent(IApplicationThread caller, 16099 Intent intent, String resolvedType, IIntentReceiver resultTo, 16100 int resultCode, String resultData, Bundle map, 16101 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16102 enforceNotIsolatedCaller("broadcastIntent"); 16103 synchronized(this) { 16104 intent = verifyBroadcastLocked(intent); 16105 16106 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16107 final int callingPid = Binder.getCallingPid(); 16108 final int callingUid = Binder.getCallingUid(); 16109 final long origId = Binder.clearCallingIdentity(); 16110 int res = broadcastIntentLocked(callerApp, 16111 callerApp != null ? callerApp.info.packageName : null, 16112 intent, resolvedType, resultTo, 16113 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16114 callingPid, callingUid, userId); 16115 Binder.restoreCallingIdentity(origId); 16116 return res; 16117 } 16118 } 16119 16120 int broadcastIntentInPackage(String packageName, int uid, 16121 Intent intent, String resolvedType, IIntentReceiver resultTo, 16122 int resultCode, String resultData, Bundle map, 16123 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16124 synchronized(this) { 16125 intent = verifyBroadcastLocked(intent); 16126 16127 final long origId = Binder.clearCallingIdentity(); 16128 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16129 resultTo, resultCode, resultData, map, requiredPermission, 16130 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16131 Binder.restoreCallingIdentity(origId); 16132 return res; 16133 } 16134 } 16135 16136 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16137 // Refuse possible leaked file descriptors 16138 if (intent != null && intent.hasFileDescriptors() == true) { 16139 throw new IllegalArgumentException("File descriptors passed in Intent"); 16140 } 16141 16142 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16143 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16144 16145 synchronized(this) { 16146 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16147 != PackageManager.PERMISSION_GRANTED) { 16148 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16149 + Binder.getCallingPid() 16150 + ", uid=" + Binder.getCallingUid() 16151 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16152 Slog.w(TAG, msg); 16153 throw new SecurityException(msg); 16154 } 16155 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16156 if (stickies != null) { 16157 ArrayList<Intent> list = stickies.get(intent.getAction()); 16158 if (list != null) { 16159 int N = list.size(); 16160 int i; 16161 for (i=0; i<N; i++) { 16162 if (intent.filterEquals(list.get(i))) { 16163 list.remove(i); 16164 break; 16165 } 16166 } 16167 if (list.size() <= 0) { 16168 stickies.remove(intent.getAction()); 16169 } 16170 } 16171 if (stickies.size() <= 0) { 16172 mStickyBroadcasts.remove(userId); 16173 } 16174 } 16175 } 16176 } 16177 16178 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16179 String resultData, Bundle resultExtras, boolean resultAbort) { 16180 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16181 if (r == null) { 16182 Slog.w(TAG, "finishReceiver called but not found on queue"); 16183 return false; 16184 } 16185 16186 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16187 } 16188 16189 void backgroundServicesFinishedLocked(int userId) { 16190 for (BroadcastQueue queue : mBroadcastQueues) { 16191 queue.backgroundServicesFinishedLocked(userId); 16192 } 16193 } 16194 16195 public void finishReceiver(IBinder who, int resultCode, String resultData, 16196 Bundle resultExtras, boolean resultAbort) { 16197 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16198 16199 // Refuse possible leaked file descriptors 16200 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16201 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16202 } 16203 16204 final long origId = Binder.clearCallingIdentity(); 16205 try { 16206 boolean doNext = false; 16207 BroadcastRecord r; 16208 16209 synchronized(this) { 16210 r = broadcastRecordForReceiverLocked(who); 16211 if (r != null) { 16212 doNext = r.queue.finishReceiverLocked(r, resultCode, 16213 resultData, resultExtras, resultAbort, true); 16214 } 16215 } 16216 16217 if (doNext) { 16218 r.queue.processNextBroadcast(false); 16219 } 16220 trimApplications(); 16221 } finally { 16222 Binder.restoreCallingIdentity(origId); 16223 } 16224 } 16225 16226 // ========================================================= 16227 // INSTRUMENTATION 16228 // ========================================================= 16229 16230 public boolean startInstrumentation(ComponentName className, 16231 String profileFile, int flags, Bundle arguments, 16232 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16233 int userId, String abiOverride) { 16234 enforceNotIsolatedCaller("startInstrumentation"); 16235 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16236 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16237 // Refuse possible leaked file descriptors 16238 if (arguments != null && arguments.hasFileDescriptors()) { 16239 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16240 } 16241 16242 synchronized(this) { 16243 InstrumentationInfo ii = null; 16244 ApplicationInfo ai = null; 16245 try { 16246 ii = mContext.getPackageManager().getInstrumentationInfo( 16247 className, STOCK_PM_FLAGS); 16248 ai = AppGlobals.getPackageManager().getApplicationInfo( 16249 ii.targetPackage, STOCK_PM_FLAGS, userId); 16250 } catch (PackageManager.NameNotFoundException e) { 16251 } catch (RemoteException e) { 16252 } 16253 if (ii == null) { 16254 reportStartInstrumentationFailure(watcher, className, 16255 "Unable to find instrumentation info for: " + className); 16256 return false; 16257 } 16258 if (ai == null) { 16259 reportStartInstrumentationFailure(watcher, className, 16260 "Unable to find instrumentation target package: " + ii.targetPackage); 16261 return false; 16262 } 16263 16264 int match = mContext.getPackageManager().checkSignatures( 16265 ii.targetPackage, ii.packageName); 16266 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16267 String msg = "Permission Denial: starting instrumentation " 16268 + className + " from pid=" 16269 + Binder.getCallingPid() 16270 + ", uid=" + Binder.getCallingPid() 16271 + " not allowed because package " + ii.packageName 16272 + " does not have a signature matching the target " 16273 + ii.targetPackage; 16274 reportStartInstrumentationFailure(watcher, className, msg); 16275 throw new SecurityException(msg); 16276 } 16277 16278 final long origId = Binder.clearCallingIdentity(); 16279 // Instrumentation can kill and relaunch even persistent processes 16280 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16281 "start instr"); 16282 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16283 app.instrumentationClass = className; 16284 app.instrumentationInfo = ai; 16285 app.instrumentationProfileFile = profileFile; 16286 app.instrumentationArguments = arguments; 16287 app.instrumentationWatcher = watcher; 16288 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16289 app.instrumentationResultClass = className; 16290 Binder.restoreCallingIdentity(origId); 16291 } 16292 16293 return true; 16294 } 16295 16296 /** 16297 * Report errors that occur while attempting to start Instrumentation. Always writes the 16298 * error to the logs, but if somebody is watching, send the report there too. This enables 16299 * the "am" command to report errors with more information. 16300 * 16301 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16302 * @param cn The component name of the instrumentation. 16303 * @param report The error report. 16304 */ 16305 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16306 ComponentName cn, String report) { 16307 Slog.w(TAG, report); 16308 try { 16309 if (watcher != null) { 16310 Bundle results = new Bundle(); 16311 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16312 results.putString("Error", report); 16313 watcher.instrumentationStatus(cn, -1, results); 16314 } 16315 } catch (RemoteException e) { 16316 Slog.w(TAG, e); 16317 } 16318 } 16319 16320 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16321 if (app.instrumentationWatcher != null) { 16322 try { 16323 // NOTE: IInstrumentationWatcher *must* be oneway here 16324 app.instrumentationWatcher.instrumentationFinished( 16325 app.instrumentationClass, 16326 resultCode, 16327 results); 16328 } catch (RemoteException e) { 16329 } 16330 } 16331 if (app.instrumentationUiAutomationConnection != null) { 16332 try { 16333 app.instrumentationUiAutomationConnection.shutdown(); 16334 } catch (RemoteException re) { 16335 /* ignore */ 16336 } 16337 // Only a UiAutomation can set this flag and now that 16338 // it is finished we make sure it is reset to its default. 16339 mUserIsMonkey = false; 16340 } 16341 app.instrumentationWatcher = null; 16342 app.instrumentationUiAutomationConnection = null; 16343 app.instrumentationClass = null; 16344 app.instrumentationInfo = null; 16345 app.instrumentationProfileFile = null; 16346 app.instrumentationArguments = null; 16347 16348 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16349 "finished inst"); 16350 } 16351 16352 public void finishInstrumentation(IApplicationThread target, 16353 int resultCode, Bundle results) { 16354 int userId = UserHandle.getCallingUserId(); 16355 // Refuse possible leaked file descriptors 16356 if (results != null && results.hasFileDescriptors()) { 16357 throw new IllegalArgumentException("File descriptors passed in Intent"); 16358 } 16359 16360 synchronized(this) { 16361 ProcessRecord app = getRecordForAppLocked(target); 16362 if (app == null) { 16363 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16364 return; 16365 } 16366 final long origId = Binder.clearCallingIdentity(); 16367 finishInstrumentationLocked(app, resultCode, results); 16368 Binder.restoreCallingIdentity(origId); 16369 } 16370 } 16371 16372 // ========================================================= 16373 // CONFIGURATION 16374 // ========================================================= 16375 16376 public ConfigurationInfo getDeviceConfigurationInfo() { 16377 ConfigurationInfo config = new ConfigurationInfo(); 16378 synchronized (this) { 16379 config.reqTouchScreen = mConfiguration.touchscreen; 16380 config.reqKeyboardType = mConfiguration.keyboard; 16381 config.reqNavigation = mConfiguration.navigation; 16382 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16383 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16384 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16385 } 16386 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16387 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16388 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16389 } 16390 config.reqGlEsVersion = GL_ES_VERSION; 16391 } 16392 return config; 16393 } 16394 16395 ActivityStack getFocusedStack() { 16396 return mStackSupervisor.getFocusedStack(); 16397 } 16398 16399 public Configuration getConfiguration() { 16400 Configuration ci; 16401 synchronized(this) { 16402 ci = new Configuration(mConfiguration); 16403 } 16404 return ci; 16405 } 16406 16407 public void updatePersistentConfiguration(Configuration values) { 16408 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16409 "updateConfiguration()"); 16410 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16411 "updateConfiguration()"); 16412 if (values == null) { 16413 throw new NullPointerException("Configuration must not be null"); 16414 } 16415 16416 synchronized(this) { 16417 final long origId = Binder.clearCallingIdentity(); 16418 updateConfigurationLocked(values, null, true, false); 16419 Binder.restoreCallingIdentity(origId); 16420 } 16421 } 16422 16423 public void updateConfiguration(Configuration values) { 16424 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16425 "updateConfiguration()"); 16426 16427 synchronized(this) { 16428 if (values == null && mWindowManager != null) { 16429 // sentinel: fetch the current configuration from the window manager 16430 values = mWindowManager.computeNewConfiguration(); 16431 } 16432 16433 if (mWindowManager != null) { 16434 mProcessList.applyDisplaySize(mWindowManager); 16435 } 16436 16437 final long origId = Binder.clearCallingIdentity(); 16438 if (values != null) { 16439 Settings.System.clearConfiguration(values); 16440 } 16441 updateConfigurationLocked(values, null, false, false); 16442 Binder.restoreCallingIdentity(origId); 16443 } 16444 } 16445 16446 /** 16447 * Do either or both things: (1) change the current configuration, and (2) 16448 * make sure the given activity is running with the (now) current 16449 * configuration. Returns true if the activity has been left running, or 16450 * false if <var>starting</var> is being destroyed to match the new 16451 * configuration. 16452 * @param persistent TODO 16453 */ 16454 boolean updateConfigurationLocked(Configuration values, 16455 ActivityRecord starting, boolean persistent, boolean initLocale) { 16456 int changes = 0; 16457 16458 if (values != null) { 16459 Configuration newConfig = new Configuration(mConfiguration); 16460 changes = newConfig.updateFrom(values); 16461 if (changes != 0) { 16462 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16463 Slog.i(TAG, "Updating configuration to: " + values); 16464 } 16465 16466 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16467 16468 if (values.locale != null && !initLocale) { 16469 saveLocaleLocked(values.locale, 16470 !values.locale.equals(mConfiguration.locale), 16471 values.userSetLocale); 16472 } 16473 16474 mConfigurationSeq++; 16475 if (mConfigurationSeq <= 0) { 16476 mConfigurationSeq = 1; 16477 } 16478 newConfig.seq = mConfigurationSeq; 16479 mConfiguration = newConfig; 16480 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16481 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16482 //mUsageStatsService.noteStartConfig(newConfig); 16483 16484 final Configuration configCopy = new Configuration(mConfiguration); 16485 16486 // TODO: If our config changes, should we auto dismiss any currently 16487 // showing dialogs? 16488 mShowDialogs = shouldShowDialogs(newConfig); 16489 16490 AttributeCache ac = AttributeCache.instance(); 16491 if (ac != null) { 16492 ac.updateConfiguration(configCopy); 16493 } 16494 16495 // Make sure all resources in our process are updated 16496 // right now, so that anyone who is going to retrieve 16497 // resource values after we return will be sure to get 16498 // the new ones. This is especially important during 16499 // boot, where the first config change needs to guarantee 16500 // all resources have that config before following boot 16501 // code is executed. 16502 mSystemThread.applyConfigurationToResources(configCopy); 16503 16504 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16505 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16506 msg.obj = new Configuration(configCopy); 16507 mHandler.sendMessage(msg); 16508 } 16509 16510 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16511 ProcessRecord app = mLruProcesses.get(i); 16512 try { 16513 if (app.thread != null) { 16514 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16515 + app.processName + " new config " + mConfiguration); 16516 app.thread.scheduleConfigurationChanged(configCopy); 16517 } 16518 } catch (Exception e) { 16519 } 16520 } 16521 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16522 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16523 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16524 | Intent.FLAG_RECEIVER_FOREGROUND); 16525 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16526 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16527 Process.SYSTEM_UID, UserHandle.USER_ALL); 16528 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16529 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16530 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16531 broadcastIntentLocked(null, null, intent, 16532 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16533 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16534 } 16535 } 16536 } 16537 16538 boolean kept = true; 16539 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16540 // mainStack is null during startup. 16541 if (mainStack != null) { 16542 if (changes != 0 && starting == null) { 16543 // If the configuration changed, and the caller is not already 16544 // in the process of starting an activity, then find the top 16545 // activity to check if its configuration needs to change. 16546 starting = mainStack.topRunningActivityLocked(null); 16547 } 16548 16549 if (starting != null) { 16550 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16551 // And we need to make sure at this point that all other activities 16552 // are made visible with the correct configuration. 16553 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16554 } 16555 } 16556 16557 if (values != null && mWindowManager != null) { 16558 mWindowManager.setNewConfiguration(mConfiguration); 16559 } 16560 16561 return kept; 16562 } 16563 16564 /** 16565 * Decide based on the configuration whether we should shouw the ANR, 16566 * crash, etc dialogs. The idea is that if there is no affordnace to 16567 * press the on-screen buttons, we shouldn't show the dialog. 16568 * 16569 * A thought: SystemUI might also want to get told about this, the Power 16570 * dialog / global actions also might want different behaviors. 16571 */ 16572 private static final boolean shouldShowDialogs(Configuration config) { 16573 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16574 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16575 } 16576 16577 /** 16578 * Save the locale. You must be inside a synchronized (this) block. 16579 */ 16580 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16581 if(isDiff) { 16582 SystemProperties.set("user.language", l.getLanguage()); 16583 SystemProperties.set("user.region", l.getCountry()); 16584 } 16585 16586 if(isPersist) { 16587 SystemProperties.set("persist.sys.language", l.getLanguage()); 16588 SystemProperties.set("persist.sys.country", l.getCountry()); 16589 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16590 16591 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16592 } 16593 } 16594 16595 @Override 16596 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16597 synchronized (this) { 16598 ActivityRecord srec = ActivityRecord.forToken(token); 16599 if (srec.task != null && srec.task.stack != null) { 16600 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16601 } 16602 } 16603 return false; 16604 } 16605 16606 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16607 Intent resultData) { 16608 16609 synchronized (this) { 16610 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16611 if (stack != null) { 16612 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16613 } 16614 return false; 16615 } 16616 } 16617 16618 public int getLaunchedFromUid(IBinder activityToken) { 16619 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16620 if (srec == null) { 16621 return -1; 16622 } 16623 return srec.launchedFromUid; 16624 } 16625 16626 public String getLaunchedFromPackage(IBinder activityToken) { 16627 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16628 if (srec == null) { 16629 return null; 16630 } 16631 return srec.launchedFromPackage; 16632 } 16633 16634 // ========================================================= 16635 // LIFETIME MANAGEMENT 16636 // ========================================================= 16637 16638 // Returns which broadcast queue the app is the current [or imminent] receiver 16639 // on, or 'null' if the app is not an active broadcast recipient. 16640 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16641 BroadcastRecord r = app.curReceiver; 16642 if (r != null) { 16643 return r.queue; 16644 } 16645 16646 // It's not the current receiver, but it might be starting up to become one 16647 synchronized (this) { 16648 for (BroadcastQueue queue : mBroadcastQueues) { 16649 r = queue.mPendingBroadcast; 16650 if (r != null && r.curApp == app) { 16651 // found it; report which queue it's in 16652 return queue; 16653 } 16654 } 16655 } 16656 16657 return null; 16658 } 16659 16660 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16661 boolean doingAll, long now) { 16662 if (mAdjSeq == app.adjSeq) { 16663 // This adjustment has already been computed. 16664 return app.curRawAdj; 16665 } 16666 16667 if (app.thread == null) { 16668 app.adjSeq = mAdjSeq; 16669 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16670 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16671 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16672 } 16673 16674 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16675 app.adjSource = null; 16676 app.adjTarget = null; 16677 app.empty = false; 16678 app.cached = false; 16679 16680 final int activitiesSize = app.activities.size(); 16681 16682 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16683 // The max adjustment doesn't allow this app to be anything 16684 // below foreground, so it is not worth doing work for it. 16685 app.adjType = "fixed"; 16686 app.adjSeq = mAdjSeq; 16687 app.curRawAdj = app.maxAdj; 16688 app.foregroundActivities = false; 16689 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16690 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16691 // System processes can do UI, and when they do we want to have 16692 // them trim their memory after the user leaves the UI. To 16693 // facilitate this, here we need to determine whether or not it 16694 // is currently showing UI. 16695 app.systemNoUi = true; 16696 if (app == TOP_APP) { 16697 app.systemNoUi = false; 16698 } else if (activitiesSize > 0) { 16699 for (int j = 0; j < activitiesSize; j++) { 16700 final ActivityRecord r = app.activities.get(j); 16701 if (r.visible) { 16702 app.systemNoUi = false; 16703 } 16704 } 16705 } 16706 if (!app.systemNoUi) { 16707 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16708 } 16709 return (app.curAdj=app.maxAdj); 16710 } 16711 16712 app.systemNoUi = false; 16713 16714 // Determine the importance of the process, starting with most 16715 // important to least, and assign an appropriate OOM adjustment. 16716 int adj; 16717 int schedGroup; 16718 int procState; 16719 boolean foregroundActivities = false; 16720 BroadcastQueue queue; 16721 if (app == TOP_APP) { 16722 // The last app on the list is the foreground app. 16723 adj = ProcessList.FOREGROUND_APP_ADJ; 16724 schedGroup = Process.THREAD_GROUP_DEFAULT; 16725 app.adjType = "top-activity"; 16726 foregroundActivities = true; 16727 procState = ActivityManager.PROCESS_STATE_TOP; 16728 } else if (app.instrumentationClass != null) { 16729 // Don't want to kill running instrumentation. 16730 adj = ProcessList.FOREGROUND_APP_ADJ; 16731 schedGroup = Process.THREAD_GROUP_DEFAULT; 16732 app.adjType = "instrumentation"; 16733 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16734 } else if ((queue = isReceivingBroadcast(app)) != null) { 16735 // An app that is currently receiving a broadcast also 16736 // counts as being in the foreground for OOM killer purposes. 16737 // It's placed in a sched group based on the nature of the 16738 // broadcast as reflected by which queue it's active in. 16739 adj = ProcessList.FOREGROUND_APP_ADJ; 16740 schedGroup = (queue == mFgBroadcastQueue) 16741 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16742 app.adjType = "broadcast"; 16743 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16744 } else if (app.executingServices.size() > 0) { 16745 // An app that is currently executing a service callback also 16746 // counts as being in the foreground. 16747 adj = ProcessList.FOREGROUND_APP_ADJ; 16748 schedGroup = app.execServicesFg ? 16749 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16750 app.adjType = "exec-service"; 16751 procState = ActivityManager.PROCESS_STATE_SERVICE; 16752 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16753 } else { 16754 // As far as we know the process is empty. We may change our mind later. 16755 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16756 // At this point we don't actually know the adjustment. Use the cached adj 16757 // value that the caller wants us to. 16758 adj = cachedAdj; 16759 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16760 app.cached = true; 16761 app.empty = true; 16762 app.adjType = "cch-empty"; 16763 } 16764 16765 // Examine all activities if not already foreground. 16766 if (!foregroundActivities && activitiesSize > 0) { 16767 for (int j = 0; j < activitiesSize; j++) { 16768 final ActivityRecord r = app.activities.get(j); 16769 if (r.app != app) { 16770 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16771 + app + "?!?"); 16772 continue; 16773 } 16774 if (r.visible) { 16775 // App has a visible activity; only upgrade adjustment. 16776 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16777 adj = ProcessList.VISIBLE_APP_ADJ; 16778 app.adjType = "visible"; 16779 } 16780 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16781 procState = ActivityManager.PROCESS_STATE_TOP; 16782 } 16783 schedGroup = Process.THREAD_GROUP_DEFAULT; 16784 app.cached = false; 16785 app.empty = false; 16786 foregroundActivities = true; 16787 break; 16788 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16789 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16790 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16791 app.adjType = "pausing"; 16792 } 16793 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16794 procState = ActivityManager.PROCESS_STATE_TOP; 16795 } 16796 schedGroup = Process.THREAD_GROUP_DEFAULT; 16797 app.cached = false; 16798 app.empty = false; 16799 foregroundActivities = true; 16800 } else if (r.state == ActivityState.STOPPING) { 16801 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16802 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16803 app.adjType = "stopping"; 16804 } 16805 // For the process state, we will at this point consider the 16806 // process to be cached. It will be cached either as an activity 16807 // or empty depending on whether the activity is finishing. We do 16808 // this so that we can treat the process as cached for purposes of 16809 // memory trimming (determing current memory level, trim command to 16810 // send to process) since there can be an arbitrary number of stopping 16811 // processes and they should soon all go into the cached state. 16812 if (!r.finishing) { 16813 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16814 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16815 } 16816 } 16817 app.cached = false; 16818 app.empty = false; 16819 foregroundActivities = true; 16820 } else { 16821 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16822 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16823 app.adjType = "cch-act"; 16824 } 16825 } 16826 } 16827 } 16828 16829 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16830 if (app.foregroundServices) { 16831 // The user is aware of this app, so make it visible. 16832 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16833 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16834 app.cached = false; 16835 app.adjType = "fg-service"; 16836 schedGroup = Process.THREAD_GROUP_DEFAULT; 16837 } else if (app.forcingToForeground != null) { 16838 // The user is aware of this app, so make it visible. 16839 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16840 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16841 app.cached = false; 16842 app.adjType = "force-fg"; 16843 app.adjSource = app.forcingToForeground; 16844 schedGroup = Process.THREAD_GROUP_DEFAULT; 16845 } 16846 } 16847 16848 if (app == mHeavyWeightProcess) { 16849 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16850 // We don't want to kill the current heavy-weight process. 16851 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16852 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16853 app.cached = false; 16854 app.adjType = "heavy"; 16855 } 16856 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16857 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16858 } 16859 } 16860 16861 if (app == mHomeProcess) { 16862 if (adj > ProcessList.HOME_APP_ADJ) { 16863 // This process is hosting what we currently consider to be the 16864 // home app, so we don't want to let it go into the background. 16865 adj = ProcessList.HOME_APP_ADJ; 16866 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16867 app.cached = false; 16868 app.adjType = "home"; 16869 } 16870 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16871 procState = ActivityManager.PROCESS_STATE_HOME; 16872 } 16873 } 16874 16875 if (app == mPreviousProcess && app.activities.size() > 0) { 16876 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16877 // This was the previous process that showed UI to the user. 16878 // We want to try to keep it around more aggressively, to give 16879 // a good experience around switching between two apps. 16880 adj = ProcessList.PREVIOUS_APP_ADJ; 16881 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16882 app.cached = false; 16883 app.adjType = "previous"; 16884 } 16885 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16886 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16887 } 16888 } 16889 16890 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16891 + " reason=" + app.adjType); 16892 16893 // By default, we use the computed adjustment. It may be changed if 16894 // there are applications dependent on our services or providers, but 16895 // this gives us a baseline and makes sure we don't get into an 16896 // infinite recursion. 16897 app.adjSeq = mAdjSeq; 16898 app.curRawAdj = adj; 16899 app.hasStartedServices = false; 16900 16901 if (mBackupTarget != null && app == mBackupTarget.app) { 16902 // If possible we want to avoid killing apps while they're being backed up 16903 if (adj > ProcessList.BACKUP_APP_ADJ) { 16904 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16905 adj = ProcessList.BACKUP_APP_ADJ; 16906 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16907 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16908 } 16909 app.adjType = "backup"; 16910 app.cached = false; 16911 } 16912 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16913 procState = ActivityManager.PROCESS_STATE_BACKUP; 16914 } 16915 } 16916 16917 boolean mayBeTop = false; 16918 16919 for (int is = app.services.size()-1; 16920 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16921 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16922 || procState > ActivityManager.PROCESS_STATE_TOP); 16923 is--) { 16924 ServiceRecord s = app.services.valueAt(is); 16925 if (s.startRequested) { 16926 app.hasStartedServices = true; 16927 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16928 procState = ActivityManager.PROCESS_STATE_SERVICE; 16929 } 16930 if (app.hasShownUi && app != mHomeProcess) { 16931 // If this process has shown some UI, let it immediately 16932 // go to the LRU list because it may be pretty heavy with 16933 // UI stuff. We'll tag it with a label just to help 16934 // debug and understand what is going on. 16935 if (adj > ProcessList.SERVICE_ADJ) { 16936 app.adjType = "cch-started-ui-services"; 16937 } 16938 } else { 16939 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16940 // This service has seen some activity within 16941 // recent memory, so we will keep its process ahead 16942 // of the background processes. 16943 if (adj > ProcessList.SERVICE_ADJ) { 16944 adj = ProcessList.SERVICE_ADJ; 16945 app.adjType = "started-services"; 16946 app.cached = false; 16947 } 16948 } 16949 // If we have let the service slide into the background 16950 // state, still have some text describing what it is doing 16951 // even though the service no longer has an impact. 16952 if (adj > ProcessList.SERVICE_ADJ) { 16953 app.adjType = "cch-started-services"; 16954 } 16955 } 16956 } 16957 for (int conni = s.connections.size()-1; 16958 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16959 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16960 || procState > ActivityManager.PROCESS_STATE_TOP); 16961 conni--) { 16962 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16963 for (int i = 0; 16964 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16965 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16966 || procState > ActivityManager.PROCESS_STATE_TOP); 16967 i++) { 16968 // XXX should compute this based on the max of 16969 // all connected clients. 16970 ConnectionRecord cr = clist.get(i); 16971 if (cr.binding.client == app) { 16972 // Binding to ourself is not interesting. 16973 continue; 16974 } 16975 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16976 ProcessRecord client = cr.binding.client; 16977 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16978 TOP_APP, doingAll, now); 16979 int clientProcState = client.curProcState; 16980 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16981 // If the other app is cached for any reason, for purposes here 16982 // we are going to consider it empty. The specific cached state 16983 // doesn't propagate except under certain conditions. 16984 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16985 } 16986 String adjType = null; 16987 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16988 // Not doing bind OOM management, so treat 16989 // this guy more like a started service. 16990 if (app.hasShownUi && app != mHomeProcess) { 16991 // If this process has shown some UI, let it immediately 16992 // go to the LRU list because it may be pretty heavy with 16993 // UI stuff. We'll tag it with a label just to help 16994 // debug and understand what is going on. 16995 if (adj > clientAdj) { 16996 adjType = "cch-bound-ui-services"; 16997 } 16998 app.cached = false; 16999 clientAdj = adj; 17000 clientProcState = procState; 17001 } else { 17002 if (now >= (s.lastActivity 17003 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17004 // This service has not seen activity within 17005 // recent memory, so allow it to drop to the 17006 // LRU list if there is no other reason to keep 17007 // it around. We'll also tag it with a label just 17008 // to help debug and undertand what is going on. 17009 if (adj > clientAdj) { 17010 adjType = "cch-bound-services"; 17011 } 17012 clientAdj = adj; 17013 } 17014 } 17015 } 17016 if (adj > clientAdj) { 17017 // If this process has recently shown UI, and 17018 // the process that is binding to it is less 17019 // important than being visible, then we don't 17020 // care about the binding as much as we care 17021 // about letting this process get into the LRU 17022 // list to be killed and restarted if needed for 17023 // memory. 17024 if (app.hasShownUi && app != mHomeProcess 17025 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17026 adjType = "cch-bound-ui-services"; 17027 } else { 17028 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17029 |Context.BIND_IMPORTANT)) != 0) { 17030 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17031 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17032 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17033 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17034 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17035 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17036 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17037 adj = clientAdj; 17038 } else { 17039 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17040 adj = ProcessList.VISIBLE_APP_ADJ; 17041 } 17042 } 17043 if (!client.cached) { 17044 app.cached = false; 17045 } 17046 adjType = "service"; 17047 } 17048 } 17049 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17050 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17051 schedGroup = Process.THREAD_GROUP_DEFAULT; 17052 } 17053 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17054 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17055 // Special handling of clients who are in the top state. 17056 // We *may* want to consider this process to be in the 17057 // top state as well, but only if there is not another 17058 // reason for it to be running. Being on the top is a 17059 // special state, meaning you are specifically running 17060 // for the current top app. If the process is already 17061 // running in the background for some other reason, it 17062 // is more important to continue considering it to be 17063 // in the background state. 17064 mayBeTop = true; 17065 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17066 } else { 17067 // Special handling for above-top states (persistent 17068 // processes). These should not bring the current process 17069 // into the top state, since they are not on top. Instead 17070 // give them the best state after that. 17071 clientProcState = 17072 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17073 } 17074 } 17075 } else { 17076 if (clientProcState < 17077 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17078 clientProcState = 17079 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17080 } 17081 } 17082 if (procState > clientProcState) { 17083 procState = clientProcState; 17084 } 17085 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17086 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17087 app.pendingUiClean = true; 17088 } 17089 if (adjType != null) { 17090 app.adjType = adjType; 17091 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17092 .REASON_SERVICE_IN_USE; 17093 app.adjSource = cr.binding.client; 17094 app.adjSourceProcState = clientProcState; 17095 app.adjTarget = s.name; 17096 } 17097 } 17098 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17099 app.treatLikeActivity = true; 17100 } 17101 final ActivityRecord a = cr.activity; 17102 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17103 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17104 (a.visible || a.state == ActivityState.RESUMED 17105 || a.state == ActivityState.PAUSING)) { 17106 adj = ProcessList.FOREGROUND_APP_ADJ; 17107 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17108 schedGroup = Process.THREAD_GROUP_DEFAULT; 17109 } 17110 app.cached = false; 17111 app.adjType = "service"; 17112 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17113 .REASON_SERVICE_IN_USE; 17114 app.adjSource = a; 17115 app.adjSourceProcState = procState; 17116 app.adjTarget = s.name; 17117 } 17118 } 17119 } 17120 } 17121 } 17122 17123 for (int provi = app.pubProviders.size()-1; 17124 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17125 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17126 || procState > ActivityManager.PROCESS_STATE_TOP); 17127 provi--) { 17128 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17129 for (int i = cpr.connections.size()-1; 17130 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17131 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17132 || procState > ActivityManager.PROCESS_STATE_TOP); 17133 i--) { 17134 ContentProviderConnection conn = cpr.connections.get(i); 17135 ProcessRecord client = conn.client; 17136 if (client == app) { 17137 // Being our own client is not interesting. 17138 continue; 17139 } 17140 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17141 int clientProcState = client.curProcState; 17142 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17143 // If the other app is cached for any reason, for purposes here 17144 // we are going to consider it empty. 17145 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17146 } 17147 if (adj > clientAdj) { 17148 if (app.hasShownUi && app != mHomeProcess 17149 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17150 app.adjType = "cch-ui-provider"; 17151 } else { 17152 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17153 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17154 app.adjType = "provider"; 17155 } 17156 app.cached &= client.cached; 17157 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17158 .REASON_PROVIDER_IN_USE; 17159 app.adjSource = client; 17160 app.adjSourceProcState = clientProcState; 17161 app.adjTarget = cpr.name; 17162 } 17163 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17164 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17165 // Special handling of clients who are in the top state. 17166 // We *may* want to consider this process to be in the 17167 // top state as well, but only if there is not another 17168 // reason for it to be running. Being on the top is a 17169 // special state, meaning you are specifically running 17170 // for the current top app. If the process is already 17171 // running in the background for some other reason, it 17172 // is more important to continue considering it to be 17173 // in the background state. 17174 mayBeTop = true; 17175 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17176 } else { 17177 // Special handling for above-top states (persistent 17178 // processes). These should not bring the current process 17179 // into the top state, since they are not on top. Instead 17180 // give them the best state after that. 17181 clientProcState = 17182 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17183 } 17184 } 17185 if (procState > clientProcState) { 17186 procState = clientProcState; 17187 } 17188 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17189 schedGroup = Process.THREAD_GROUP_DEFAULT; 17190 } 17191 } 17192 // If the provider has external (non-framework) process 17193 // dependencies, ensure that its adjustment is at least 17194 // FOREGROUND_APP_ADJ. 17195 if (cpr.hasExternalProcessHandles()) { 17196 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17197 adj = ProcessList.FOREGROUND_APP_ADJ; 17198 schedGroup = Process.THREAD_GROUP_DEFAULT; 17199 app.cached = false; 17200 app.adjType = "provider"; 17201 app.adjTarget = cpr.name; 17202 } 17203 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17204 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17205 } 17206 } 17207 } 17208 17209 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17210 // A client of one of our services or providers is in the top state. We 17211 // *may* want to be in the top state, but not if we are already running in 17212 // the background for some other reason. For the decision here, we are going 17213 // to pick out a few specific states that we want to remain in when a client 17214 // is top (states that tend to be longer-term) and otherwise allow it to go 17215 // to the top state. 17216 switch (procState) { 17217 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17218 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17219 case ActivityManager.PROCESS_STATE_SERVICE: 17220 // These all are longer-term states, so pull them up to the top 17221 // of the background states, but not all the way to the top state. 17222 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17223 break; 17224 default: 17225 // Otherwise, top is a better choice, so take it. 17226 procState = ActivityManager.PROCESS_STATE_TOP; 17227 break; 17228 } 17229 } 17230 17231 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17232 if (app.hasClientActivities) { 17233 // This is a cached process, but with client activities. Mark it so. 17234 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17235 app.adjType = "cch-client-act"; 17236 } else if (app.treatLikeActivity) { 17237 // This is a cached process, but somebody wants us to treat it like it has 17238 // an activity, okay! 17239 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17240 app.adjType = "cch-as-act"; 17241 } 17242 } 17243 17244 if (adj == ProcessList.SERVICE_ADJ) { 17245 if (doingAll) { 17246 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17247 mNewNumServiceProcs++; 17248 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17249 if (!app.serviceb) { 17250 // This service isn't far enough down on the LRU list to 17251 // normally be a B service, but if we are low on RAM and it 17252 // is large we want to force it down since we would prefer to 17253 // keep launcher over it. 17254 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17255 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17256 app.serviceHighRam = true; 17257 app.serviceb = true; 17258 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17259 } else { 17260 mNewNumAServiceProcs++; 17261 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17262 } 17263 } else { 17264 app.serviceHighRam = false; 17265 } 17266 } 17267 if (app.serviceb) { 17268 adj = ProcessList.SERVICE_B_ADJ; 17269 } 17270 } 17271 17272 app.curRawAdj = adj; 17273 17274 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17275 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17276 if (adj > app.maxAdj) { 17277 adj = app.maxAdj; 17278 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17279 schedGroup = Process.THREAD_GROUP_DEFAULT; 17280 } 17281 } 17282 17283 // Do final modification to adj. Everything we do between here and applying 17284 // the final setAdj must be done in this function, because we will also use 17285 // it when computing the final cached adj later. Note that we don't need to 17286 // worry about this for max adj above, since max adj will always be used to 17287 // keep it out of the cached vaues. 17288 app.curAdj = app.modifyRawOomAdj(adj); 17289 app.curSchedGroup = schedGroup; 17290 app.curProcState = procState; 17291 app.foregroundActivities = foregroundActivities; 17292 17293 return app.curRawAdj; 17294 } 17295 17296 /** 17297 * Schedule PSS collection of a process. 17298 */ 17299 void requestPssLocked(ProcessRecord proc, int procState) { 17300 if (mPendingPssProcesses.contains(proc)) { 17301 return; 17302 } 17303 if (mPendingPssProcesses.size() == 0) { 17304 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17305 } 17306 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17307 proc.pssProcState = procState; 17308 mPendingPssProcesses.add(proc); 17309 } 17310 17311 /** 17312 * Schedule PSS collection of all processes. 17313 */ 17314 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17315 if (!always) { 17316 if (now < (mLastFullPssTime + 17317 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17318 return; 17319 } 17320 } 17321 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17322 mLastFullPssTime = now; 17323 mFullPssPending = true; 17324 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17325 mPendingPssProcesses.clear(); 17326 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17327 ProcessRecord app = mLruProcesses.get(i); 17328 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17329 app.pssProcState = app.setProcState; 17330 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17331 isSleeping(), now); 17332 mPendingPssProcesses.add(app); 17333 } 17334 } 17335 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17336 } 17337 17338 /** 17339 * Ask a given process to GC right now. 17340 */ 17341 final void performAppGcLocked(ProcessRecord app) { 17342 try { 17343 app.lastRequestedGc = SystemClock.uptimeMillis(); 17344 if (app.thread != null) { 17345 if (app.reportLowMemory) { 17346 app.reportLowMemory = false; 17347 app.thread.scheduleLowMemory(); 17348 } else { 17349 app.thread.processInBackground(); 17350 } 17351 } 17352 } catch (Exception e) { 17353 // whatever. 17354 } 17355 } 17356 17357 /** 17358 * Returns true if things are idle enough to perform GCs. 17359 */ 17360 private final boolean canGcNowLocked() { 17361 boolean processingBroadcasts = false; 17362 for (BroadcastQueue q : mBroadcastQueues) { 17363 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17364 processingBroadcasts = true; 17365 } 17366 } 17367 return !processingBroadcasts 17368 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17369 } 17370 17371 /** 17372 * Perform GCs on all processes that are waiting for it, but only 17373 * if things are idle. 17374 */ 17375 final void performAppGcsLocked() { 17376 final int N = mProcessesToGc.size(); 17377 if (N <= 0) { 17378 return; 17379 } 17380 if (canGcNowLocked()) { 17381 while (mProcessesToGc.size() > 0) { 17382 ProcessRecord proc = mProcessesToGc.remove(0); 17383 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17384 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17385 <= SystemClock.uptimeMillis()) { 17386 // To avoid spamming the system, we will GC processes one 17387 // at a time, waiting a few seconds between each. 17388 performAppGcLocked(proc); 17389 scheduleAppGcsLocked(); 17390 return; 17391 } else { 17392 // It hasn't been long enough since we last GCed this 17393 // process... put it in the list to wait for its time. 17394 addProcessToGcListLocked(proc); 17395 break; 17396 } 17397 } 17398 } 17399 17400 scheduleAppGcsLocked(); 17401 } 17402 } 17403 17404 /** 17405 * If all looks good, perform GCs on all processes waiting for them. 17406 */ 17407 final void performAppGcsIfAppropriateLocked() { 17408 if (canGcNowLocked()) { 17409 performAppGcsLocked(); 17410 return; 17411 } 17412 // Still not idle, wait some more. 17413 scheduleAppGcsLocked(); 17414 } 17415 17416 /** 17417 * Schedule the execution of all pending app GCs. 17418 */ 17419 final void scheduleAppGcsLocked() { 17420 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17421 17422 if (mProcessesToGc.size() > 0) { 17423 // Schedule a GC for the time to the next process. 17424 ProcessRecord proc = mProcessesToGc.get(0); 17425 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17426 17427 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17428 long now = SystemClock.uptimeMillis(); 17429 if (when < (now+GC_TIMEOUT)) { 17430 when = now + GC_TIMEOUT; 17431 } 17432 mHandler.sendMessageAtTime(msg, when); 17433 } 17434 } 17435 17436 /** 17437 * Add a process to the array of processes waiting to be GCed. Keeps the 17438 * list in sorted order by the last GC time. The process can't already be 17439 * on the list. 17440 */ 17441 final void addProcessToGcListLocked(ProcessRecord proc) { 17442 boolean added = false; 17443 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17444 if (mProcessesToGc.get(i).lastRequestedGc < 17445 proc.lastRequestedGc) { 17446 added = true; 17447 mProcessesToGc.add(i+1, proc); 17448 break; 17449 } 17450 } 17451 if (!added) { 17452 mProcessesToGc.add(0, proc); 17453 } 17454 } 17455 17456 /** 17457 * Set up to ask a process to GC itself. This will either do it 17458 * immediately, or put it on the list of processes to gc the next 17459 * time things are idle. 17460 */ 17461 final void scheduleAppGcLocked(ProcessRecord app) { 17462 long now = SystemClock.uptimeMillis(); 17463 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17464 return; 17465 } 17466 if (!mProcessesToGc.contains(app)) { 17467 addProcessToGcListLocked(app); 17468 scheduleAppGcsLocked(); 17469 } 17470 } 17471 17472 final void checkExcessivePowerUsageLocked(boolean doKills) { 17473 updateCpuStatsNow(); 17474 17475 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17476 boolean doWakeKills = doKills; 17477 boolean doCpuKills = doKills; 17478 if (mLastPowerCheckRealtime == 0) { 17479 doWakeKills = false; 17480 } 17481 if (mLastPowerCheckUptime == 0) { 17482 doCpuKills = false; 17483 } 17484 if (stats.isScreenOn()) { 17485 doWakeKills = false; 17486 } 17487 final long curRealtime = SystemClock.elapsedRealtime(); 17488 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17489 final long curUptime = SystemClock.uptimeMillis(); 17490 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17491 mLastPowerCheckRealtime = curRealtime; 17492 mLastPowerCheckUptime = curUptime; 17493 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17494 doWakeKills = false; 17495 } 17496 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17497 doCpuKills = false; 17498 } 17499 int i = mLruProcesses.size(); 17500 while (i > 0) { 17501 i--; 17502 ProcessRecord app = mLruProcesses.get(i); 17503 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17504 long wtime; 17505 synchronized (stats) { 17506 wtime = stats.getProcessWakeTime(app.info.uid, 17507 app.pid, curRealtime); 17508 } 17509 long wtimeUsed = wtime - app.lastWakeTime; 17510 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17511 if (DEBUG_POWER) { 17512 StringBuilder sb = new StringBuilder(128); 17513 sb.append("Wake for "); 17514 app.toShortString(sb); 17515 sb.append(": over "); 17516 TimeUtils.formatDuration(realtimeSince, sb); 17517 sb.append(" used "); 17518 TimeUtils.formatDuration(wtimeUsed, sb); 17519 sb.append(" ("); 17520 sb.append((wtimeUsed*100)/realtimeSince); 17521 sb.append("%)"); 17522 Slog.i(TAG, sb.toString()); 17523 sb.setLength(0); 17524 sb.append("CPU for "); 17525 app.toShortString(sb); 17526 sb.append(": over "); 17527 TimeUtils.formatDuration(uptimeSince, sb); 17528 sb.append(" used "); 17529 TimeUtils.formatDuration(cputimeUsed, sb); 17530 sb.append(" ("); 17531 sb.append((cputimeUsed*100)/uptimeSince); 17532 sb.append("%)"); 17533 Slog.i(TAG, sb.toString()); 17534 } 17535 // If a process has held a wake lock for more 17536 // than 50% of the time during this period, 17537 // that sounds bad. Kill! 17538 if (doWakeKills && realtimeSince > 0 17539 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17540 synchronized (stats) { 17541 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17542 realtimeSince, wtimeUsed); 17543 } 17544 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17545 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17546 } else if (doCpuKills && uptimeSince > 0 17547 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17548 synchronized (stats) { 17549 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17550 uptimeSince, cputimeUsed); 17551 } 17552 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17553 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17554 } else { 17555 app.lastWakeTime = wtime; 17556 app.lastCpuTime = app.curCpuTime; 17557 } 17558 } 17559 } 17560 } 17561 17562 private final boolean applyOomAdjLocked(ProcessRecord app, 17563 ProcessRecord TOP_APP, boolean doingAll, long now) { 17564 boolean success = true; 17565 17566 if (app.curRawAdj != app.setRawAdj) { 17567 app.setRawAdj = app.curRawAdj; 17568 } 17569 17570 int changes = 0; 17571 17572 if (app.curAdj != app.setAdj) { 17573 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17574 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17575 TAG, "Set " + app.pid + " " + app.processName + 17576 " adj " + app.curAdj + ": " + app.adjType); 17577 app.setAdj = app.curAdj; 17578 } 17579 17580 if (app.setSchedGroup != app.curSchedGroup) { 17581 app.setSchedGroup = app.curSchedGroup; 17582 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17583 "Setting process group of " + app.processName 17584 + " to " + app.curSchedGroup); 17585 if (app.waitingToKill != null && 17586 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17587 app.kill(app.waitingToKill, true); 17588 success = false; 17589 } else { 17590 if (true) { 17591 long oldId = Binder.clearCallingIdentity(); 17592 try { 17593 Process.setProcessGroup(app.pid, app.curSchedGroup); 17594 } catch (Exception e) { 17595 Slog.w(TAG, "Failed setting process group of " + app.pid 17596 + " to " + app.curSchedGroup); 17597 e.printStackTrace(); 17598 } finally { 17599 Binder.restoreCallingIdentity(oldId); 17600 } 17601 } else { 17602 if (app.thread != null) { 17603 try { 17604 app.thread.setSchedulingGroup(app.curSchedGroup); 17605 } catch (RemoteException e) { 17606 } 17607 } 17608 } 17609 Process.setSwappiness(app.pid, 17610 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17611 } 17612 } 17613 if (app.repForegroundActivities != app.foregroundActivities) { 17614 app.repForegroundActivities = app.foregroundActivities; 17615 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17616 } 17617 if (app.repProcState != app.curProcState) { 17618 app.repProcState = app.curProcState; 17619 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17620 if (app.thread != null) { 17621 try { 17622 if (false) { 17623 //RuntimeException h = new RuntimeException("here"); 17624 Slog.i(TAG, "Sending new process state " + app.repProcState 17625 + " to " + app /*, h*/); 17626 } 17627 app.thread.setProcessState(app.repProcState); 17628 } catch (RemoteException e) { 17629 } 17630 } 17631 } 17632 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17633 app.setProcState)) { 17634 app.lastStateTime = now; 17635 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17636 isSleeping(), now); 17637 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17638 + ProcessList.makeProcStateString(app.setProcState) + " to " 17639 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17640 + (app.nextPssTime-now) + ": " + app); 17641 } else { 17642 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17643 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17644 requestPssLocked(app, app.setProcState); 17645 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17646 isSleeping(), now); 17647 } else if (false && DEBUG_PSS) { 17648 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17649 } 17650 } 17651 if (app.setProcState != app.curProcState) { 17652 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17653 "Proc state change of " + app.processName 17654 + " to " + app.curProcState); 17655 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17656 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17657 if (setImportant && !curImportant) { 17658 // This app is no longer something we consider important enough to allow to 17659 // use arbitrary amounts of battery power. Note 17660 // its current wake lock time to later know to kill it if 17661 // it is not behaving well. 17662 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17663 synchronized (stats) { 17664 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17665 app.pid, SystemClock.elapsedRealtime()); 17666 } 17667 app.lastCpuTime = app.curCpuTime; 17668 17669 } 17670 app.setProcState = app.curProcState; 17671 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17672 app.notCachedSinceIdle = false; 17673 } 17674 if (!doingAll) { 17675 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17676 } else { 17677 app.procStateChanged = true; 17678 } 17679 } 17680 17681 if (changes != 0) { 17682 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17683 int i = mPendingProcessChanges.size()-1; 17684 ProcessChangeItem item = null; 17685 while (i >= 0) { 17686 item = mPendingProcessChanges.get(i); 17687 if (item.pid == app.pid) { 17688 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17689 break; 17690 } 17691 i--; 17692 } 17693 if (i < 0) { 17694 // No existing item in pending changes; need a new one. 17695 final int NA = mAvailProcessChanges.size(); 17696 if (NA > 0) { 17697 item = mAvailProcessChanges.remove(NA-1); 17698 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17699 } else { 17700 item = new ProcessChangeItem(); 17701 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17702 } 17703 item.changes = 0; 17704 item.pid = app.pid; 17705 item.uid = app.info.uid; 17706 if (mPendingProcessChanges.size() == 0) { 17707 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17708 "*** Enqueueing dispatch processes changed!"); 17709 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17710 } 17711 mPendingProcessChanges.add(item); 17712 } 17713 item.changes |= changes; 17714 item.processState = app.repProcState; 17715 item.foregroundActivities = app.repForegroundActivities; 17716 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17717 + Integer.toHexString(System.identityHashCode(item)) 17718 + " " + app.toShortString() + ": changes=" + item.changes 17719 + " procState=" + item.processState 17720 + " foreground=" + item.foregroundActivities 17721 + " type=" + app.adjType + " source=" + app.adjSource 17722 + " target=" + app.adjTarget); 17723 } 17724 17725 return success; 17726 } 17727 17728 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17729 if (proc.thread != null) { 17730 if (proc.baseProcessTracker != null) { 17731 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17732 } 17733 if (proc.repProcState >= 0) { 17734 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17735 proc.repProcState); 17736 } 17737 } 17738 } 17739 17740 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17741 ProcessRecord TOP_APP, boolean doingAll, long now) { 17742 if (app.thread == null) { 17743 return false; 17744 } 17745 17746 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17747 17748 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17749 } 17750 17751 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17752 boolean oomAdj) { 17753 if (isForeground != proc.foregroundServices) { 17754 proc.foregroundServices = isForeground; 17755 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17756 proc.info.uid); 17757 if (isForeground) { 17758 if (curProcs == null) { 17759 curProcs = new ArrayList<ProcessRecord>(); 17760 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17761 } 17762 if (!curProcs.contains(proc)) { 17763 curProcs.add(proc); 17764 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17765 proc.info.packageName, proc.info.uid); 17766 } 17767 } else { 17768 if (curProcs != null) { 17769 if (curProcs.remove(proc)) { 17770 mBatteryStatsService.noteEvent( 17771 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17772 proc.info.packageName, proc.info.uid); 17773 if (curProcs.size() <= 0) { 17774 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17775 } 17776 } 17777 } 17778 } 17779 if (oomAdj) { 17780 updateOomAdjLocked(); 17781 } 17782 } 17783 } 17784 17785 private final ActivityRecord resumedAppLocked() { 17786 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17787 String pkg; 17788 int uid; 17789 if (act != null) { 17790 pkg = act.packageName; 17791 uid = act.info.applicationInfo.uid; 17792 } else { 17793 pkg = null; 17794 uid = -1; 17795 } 17796 // Has the UID or resumed package name changed? 17797 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17798 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17799 if (mCurResumedPackage != null) { 17800 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17801 mCurResumedPackage, mCurResumedUid); 17802 } 17803 mCurResumedPackage = pkg; 17804 mCurResumedUid = uid; 17805 if (mCurResumedPackage != null) { 17806 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17807 mCurResumedPackage, mCurResumedUid); 17808 } 17809 } 17810 return act; 17811 } 17812 17813 final boolean updateOomAdjLocked(ProcessRecord app) { 17814 final ActivityRecord TOP_ACT = resumedAppLocked(); 17815 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17816 final boolean wasCached = app.cached; 17817 17818 mAdjSeq++; 17819 17820 // This is the desired cached adjusment we want to tell it to use. 17821 // If our app is currently cached, we know it, and that is it. Otherwise, 17822 // we don't know it yet, and it needs to now be cached we will then 17823 // need to do a complete oom adj. 17824 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17825 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17826 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17827 SystemClock.uptimeMillis()); 17828 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17829 // Changed to/from cached state, so apps after it in the LRU 17830 // list may also be changed. 17831 updateOomAdjLocked(); 17832 } 17833 return success; 17834 } 17835 17836 final void updateOomAdjLocked() { 17837 final ActivityRecord TOP_ACT = resumedAppLocked(); 17838 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17839 final long now = SystemClock.uptimeMillis(); 17840 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17841 final int N = mLruProcesses.size(); 17842 17843 if (false) { 17844 RuntimeException e = new RuntimeException(); 17845 e.fillInStackTrace(); 17846 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17847 } 17848 17849 mAdjSeq++; 17850 mNewNumServiceProcs = 0; 17851 mNewNumAServiceProcs = 0; 17852 17853 final int emptyProcessLimit; 17854 final int cachedProcessLimit; 17855 if (mProcessLimit <= 0) { 17856 emptyProcessLimit = cachedProcessLimit = 0; 17857 } else if (mProcessLimit == 1) { 17858 emptyProcessLimit = 1; 17859 cachedProcessLimit = 0; 17860 } else { 17861 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17862 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17863 } 17864 17865 // Let's determine how many processes we have running vs. 17866 // how many slots we have for background processes; we may want 17867 // to put multiple processes in a slot of there are enough of 17868 // them. 17869 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17870 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17871 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17872 if (numEmptyProcs > cachedProcessLimit) { 17873 // If there are more empty processes than our limit on cached 17874 // processes, then use the cached process limit for the factor. 17875 // This ensures that the really old empty processes get pushed 17876 // down to the bottom, so if we are running low on memory we will 17877 // have a better chance at keeping around more cached processes 17878 // instead of a gazillion empty processes. 17879 numEmptyProcs = cachedProcessLimit; 17880 } 17881 int emptyFactor = numEmptyProcs/numSlots; 17882 if (emptyFactor < 1) emptyFactor = 1; 17883 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17884 if (cachedFactor < 1) cachedFactor = 1; 17885 int stepCached = 0; 17886 int stepEmpty = 0; 17887 int numCached = 0; 17888 int numEmpty = 0; 17889 int numTrimming = 0; 17890 17891 mNumNonCachedProcs = 0; 17892 mNumCachedHiddenProcs = 0; 17893 17894 // First update the OOM adjustment for each of the 17895 // application processes based on their current state. 17896 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17897 int nextCachedAdj = curCachedAdj+1; 17898 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17899 int nextEmptyAdj = curEmptyAdj+2; 17900 for (int i=N-1; i>=0; i--) { 17901 ProcessRecord app = mLruProcesses.get(i); 17902 if (!app.killedByAm && app.thread != null) { 17903 app.procStateChanged = false; 17904 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17905 17906 // If we haven't yet assigned the final cached adj 17907 // to the process, do that now. 17908 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17909 switch (app.curProcState) { 17910 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17911 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17912 // This process is a cached process holding activities... 17913 // assign it the next cached value for that type, and then 17914 // step that cached level. 17915 app.curRawAdj = curCachedAdj; 17916 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17917 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17918 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17919 + ")"); 17920 if (curCachedAdj != nextCachedAdj) { 17921 stepCached++; 17922 if (stepCached >= cachedFactor) { 17923 stepCached = 0; 17924 curCachedAdj = nextCachedAdj; 17925 nextCachedAdj += 2; 17926 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17927 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17928 } 17929 } 17930 } 17931 break; 17932 default: 17933 // For everything else, assign next empty cached process 17934 // level and bump that up. Note that this means that 17935 // long-running services that have dropped down to the 17936 // cached level will be treated as empty (since their process 17937 // state is still as a service), which is what we want. 17938 app.curRawAdj = curEmptyAdj; 17939 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17940 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17941 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17942 + ")"); 17943 if (curEmptyAdj != nextEmptyAdj) { 17944 stepEmpty++; 17945 if (stepEmpty >= emptyFactor) { 17946 stepEmpty = 0; 17947 curEmptyAdj = nextEmptyAdj; 17948 nextEmptyAdj += 2; 17949 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17950 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17951 } 17952 } 17953 } 17954 break; 17955 } 17956 } 17957 17958 applyOomAdjLocked(app, TOP_APP, true, now); 17959 17960 // Count the number of process types. 17961 switch (app.curProcState) { 17962 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17963 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17964 mNumCachedHiddenProcs++; 17965 numCached++; 17966 if (numCached > cachedProcessLimit) { 17967 app.kill("cached #" + numCached, true); 17968 } 17969 break; 17970 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17971 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17972 && app.lastActivityTime < oldTime) { 17973 app.kill("empty for " 17974 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17975 / 1000) + "s", true); 17976 } else { 17977 numEmpty++; 17978 if (numEmpty > emptyProcessLimit) { 17979 app.kill("empty #" + numEmpty, true); 17980 } 17981 } 17982 break; 17983 default: 17984 mNumNonCachedProcs++; 17985 break; 17986 } 17987 17988 if (app.isolated && app.services.size() <= 0) { 17989 // If this is an isolated process, and there are no 17990 // services running in it, then the process is no longer 17991 // needed. We agressively kill these because we can by 17992 // definition not re-use the same process again, and it is 17993 // good to avoid having whatever code was running in them 17994 // left sitting around after no longer needed. 17995 app.kill("isolated not needed", true); 17996 } 17997 17998 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17999 && !app.killedByAm) { 18000 numTrimming++; 18001 } 18002 } 18003 } 18004 18005 mNumServiceProcs = mNewNumServiceProcs; 18006 18007 // Now determine the memory trimming level of background processes. 18008 // Unfortunately we need to start at the back of the list to do this 18009 // properly. We only do this if the number of background apps we 18010 // are managing to keep around is less than half the maximum we desire; 18011 // if we are keeping a good number around, we'll let them use whatever 18012 // memory they want. 18013 final int numCachedAndEmpty = numCached + numEmpty; 18014 int memFactor; 18015 if (numCached <= ProcessList.TRIM_CACHED_APPS 18016 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18017 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18018 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18019 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18020 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18021 } else { 18022 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18023 } 18024 } else { 18025 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18026 } 18027 // We always allow the memory level to go up (better). We only allow it to go 18028 // down if we are in a state where that is allowed, *and* the total number of processes 18029 // has gone down since last time. 18030 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18031 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18032 + " last=" + mLastNumProcesses); 18033 if (memFactor > mLastMemoryLevel) { 18034 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18035 memFactor = mLastMemoryLevel; 18036 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18037 } 18038 } 18039 mLastMemoryLevel = memFactor; 18040 mLastNumProcesses = mLruProcesses.size(); 18041 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18042 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18043 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18044 if (mLowRamStartTime == 0) { 18045 mLowRamStartTime = now; 18046 } 18047 int step = 0; 18048 int fgTrimLevel; 18049 switch (memFactor) { 18050 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18051 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18052 break; 18053 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18054 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18055 break; 18056 default: 18057 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18058 break; 18059 } 18060 int factor = numTrimming/3; 18061 int minFactor = 2; 18062 if (mHomeProcess != null) minFactor++; 18063 if (mPreviousProcess != null) minFactor++; 18064 if (factor < minFactor) factor = minFactor; 18065 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18066 for (int i=N-1; i>=0; i--) { 18067 ProcessRecord app = mLruProcesses.get(i); 18068 if (allChanged || app.procStateChanged) { 18069 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18070 app.procStateChanged = false; 18071 } 18072 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18073 && !app.killedByAm) { 18074 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18075 try { 18076 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18077 "Trimming memory of " + app.processName 18078 + " to " + curLevel); 18079 app.thread.scheduleTrimMemory(curLevel); 18080 } catch (RemoteException e) { 18081 } 18082 if (false) { 18083 // For now we won't do this; our memory trimming seems 18084 // to be good enough at this point that destroying 18085 // activities causes more harm than good. 18086 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18087 && app != mHomeProcess && app != mPreviousProcess) { 18088 // Need to do this on its own message because the stack may not 18089 // be in a consistent state at this point. 18090 // For these apps we will also finish their activities 18091 // to help them free memory. 18092 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18093 } 18094 } 18095 } 18096 app.trimMemoryLevel = curLevel; 18097 step++; 18098 if (step >= factor) { 18099 step = 0; 18100 switch (curLevel) { 18101 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18102 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18103 break; 18104 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18105 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18106 break; 18107 } 18108 } 18109 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18110 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18111 && app.thread != null) { 18112 try { 18113 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18114 "Trimming memory of heavy-weight " + app.processName 18115 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18116 app.thread.scheduleTrimMemory( 18117 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18118 } catch (RemoteException e) { 18119 } 18120 } 18121 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18122 } else { 18123 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18124 || app.systemNoUi) && app.pendingUiClean) { 18125 // If this application is now in the background and it 18126 // had done UI, then give it the special trim level to 18127 // have it free UI resources. 18128 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18129 if (app.trimMemoryLevel < level && app.thread != null) { 18130 try { 18131 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18132 "Trimming memory of bg-ui " + app.processName 18133 + " to " + level); 18134 app.thread.scheduleTrimMemory(level); 18135 } catch (RemoteException e) { 18136 } 18137 } 18138 app.pendingUiClean = false; 18139 } 18140 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18141 try { 18142 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18143 "Trimming memory of fg " + app.processName 18144 + " to " + fgTrimLevel); 18145 app.thread.scheduleTrimMemory(fgTrimLevel); 18146 } catch (RemoteException e) { 18147 } 18148 } 18149 app.trimMemoryLevel = fgTrimLevel; 18150 } 18151 } 18152 } else { 18153 if (mLowRamStartTime != 0) { 18154 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18155 mLowRamStartTime = 0; 18156 } 18157 for (int i=N-1; i>=0; i--) { 18158 ProcessRecord app = mLruProcesses.get(i); 18159 if (allChanged || app.procStateChanged) { 18160 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18161 app.procStateChanged = false; 18162 } 18163 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18164 || app.systemNoUi) && app.pendingUiClean) { 18165 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18166 && app.thread != null) { 18167 try { 18168 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18169 "Trimming memory of ui hidden " + app.processName 18170 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18171 app.thread.scheduleTrimMemory( 18172 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18173 } catch (RemoteException e) { 18174 } 18175 } 18176 app.pendingUiClean = false; 18177 } 18178 app.trimMemoryLevel = 0; 18179 } 18180 } 18181 18182 if (mAlwaysFinishActivities) { 18183 // Need to do this on its own message because the stack may not 18184 // be in a consistent state at this point. 18185 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18186 } 18187 18188 if (allChanged) { 18189 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18190 } 18191 18192 if (mProcessStats.shouldWriteNowLocked(now)) { 18193 mHandler.post(new Runnable() { 18194 @Override public void run() { 18195 synchronized (ActivityManagerService.this) { 18196 mProcessStats.writeStateAsyncLocked(); 18197 } 18198 } 18199 }); 18200 } 18201 18202 if (DEBUG_OOM_ADJ) { 18203 if (false) { 18204 RuntimeException here = new RuntimeException("here"); 18205 here.fillInStackTrace(); 18206 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18207 } else { 18208 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18209 } 18210 } 18211 } 18212 18213 final void trimApplications() { 18214 synchronized (this) { 18215 int i; 18216 18217 // First remove any unused application processes whose package 18218 // has been removed. 18219 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18220 final ProcessRecord app = mRemovedProcesses.get(i); 18221 if (app.activities.size() == 0 18222 && app.curReceiver == null && app.services.size() == 0) { 18223 Slog.i( 18224 TAG, "Exiting empty application process " 18225 + app.processName + " (" 18226 + (app.thread != null ? app.thread.asBinder() : null) 18227 + ")\n"); 18228 if (app.pid > 0 && app.pid != MY_PID) { 18229 app.kill("empty", false); 18230 } else { 18231 try { 18232 app.thread.scheduleExit(); 18233 } catch (Exception e) { 18234 // Ignore exceptions. 18235 } 18236 } 18237 cleanUpApplicationRecordLocked(app, false, true, -1); 18238 mRemovedProcesses.remove(i); 18239 18240 if (app.persistent) { 18241 addAppLocked(app.info, false, null /* ABI override */); 18242 } 18243 } 18244 } 18245 18246 // Now update the oom adj for all processes. 18247 updateOomAdjLocked(); 18248 } 18249 } 18250 18251 /** This method sends the specified signal to each of the persistent apps */ 18252 public void signalPersistentProcesses(int sig) throws RemoteException { 18253 if (sig != Process.SIGNAL_USR1) { 18254 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18255 } 18256 18257 synchronized (this) { 18258 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18259 != PackageManager.PERMISSION_GRANTED) { 18260 throw new SecurityException("Requires permission " 18261 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18262 } 18263 18264 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18265 ProcessRecord r = mLruProcesses.get(i); 18266 if (r.thread != null && r.persistent) { 18267 Process.sendSignal(r.pid, sig); 18268 } 18269 } 18270 } 18271 } 18272 18273 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18274 if (proc == null || proc == mProfileProc) { 18275 proc = mProfileProc; 18276 profileType = mProfileType; 18277 clearProfilerLocked(); 18278 } 18279 if (proc == null) { 18280 return; 18281 } 18282 try { 18283 proc.thread.profilerControl(false, null, profileType); 18284 } catch (RemoteException e) { 18285 throw new IllegalStateException("Process disappeared"); 18286 } 18287 } 18288 18289 private void clearProfilerLocked() { 18290 if (mProfileFd != null) { 18291 try { 18292 mProfileFd.close(); 18293 } catch (IOException e) { 18294 } 18295 } 18296 mProfileApp = null; 18297 mProfileProc = null; 18298 mProfileFile = null; 18299 mProfileType = 0; 18300 mAutoStopProfiler = false; 18301 mSamplingInterval = 0; 18302 } 18303 18304 public boolean profileControl(String process, int userId, boolean start, 18305 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18306 18307 try { 18308 synchronized (this) { 18309 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18310 // its own permission. 18311 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18312 != PackageManager.PERMISSION_GRANTED) { 18313 throw new SecurityException("Requires permission " 18314 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18315 } 18316 18317 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18318 throw new IllegalArgumentException("null profile info or fd"); 18319 } 18320 18321 ProcessRecord proc = null; 18322 if (process != null) { 18323 proc = findProcessLocked(process, userId, "profileControl"); 18324 } 18325 18326 if (start && (proc == null || proc.thread == null)) { 18327 throw new IllegalArgumentException("Unknown process: " + process); 18328 } 18329 18330 if (start) { 18331 stopProfilerLocked(null, 0); 18332 setProfileApp(proc.info, proc.processName, profilerInfo); 18333 mProfileProc = proc; 18334 mProfileType = profileType; 18335 ParcelFileDescriptor fd = profilerInfo.profileFd; 18336 try { 18337 fd = fd.dup(); 18338 } catch (IOException e) { 18339 fd = null; 18340 } 18341 profilerInfo.profileFd = fd; 18342 proc.thread.profilerControl(start, profilerInfo, profileType); 18343 fd = null; 18344 mProfileFd = null; 18345 } else { 18346 stopProfilerLocked(proc, profileType); 18347 if (profilerInfo != null && profilerInfo.profileFd != null) { 18348 try { 18349 profilerInfo.profileFd.close(); 18350 } catch (IOException e) { 18351 } 18352 } 18353 } 18354 18355 return true; 18356 } 18357 } catch (RemoteException e) { 18358 throw new IllegalStateException("Process disappeared"); 18359 } finally { 18360 if (profilerInfo != null && profilerInfo.profileFd != null) { 18361 try { 18362 profilerInfo.profileFd.close(); 18363 } catch (IOException e) { 18364 } 18365 } 18366 } 18367 } 18368 18369 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18370 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18371 userId, true, ALLOW_FULL_ONLY, callName, null); 18372 ProcessRecord proc = null; 18373 try { 18374 int pid = Integer.parseInt(process); 18375 synchronized (mPidsSelfLocked) { 18376 proc = mPidsSelfLocked.get(pid); 18377 } 18378 } catch (NumberFormatException e) { 18379 } 18380 18381 if (proc == null) { 18382 ArrayMap<String, SparseArray<ProcessRecord>> all 18383 = mProcessNames.getMap(); 18384 SparseArray<ProcessRecord> procs = all.get(process); 18385 if (procs != null && procs.size() > 0) { 18386 proc = procs.valueAt(0); 18387 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18388 for (int i=1; i<procs.size(); i++) { 18389 ProcessRecord thisProc = procs.valueAt(i); 18390 if (thisProc.userId == userId) { 18391 proc = thisProc; 18392 break; 18393 } 18394 } 18395 } 18396 } 18397 } 18398 18399 return proc; 18400 } 18401 18402 public boolean dumpHeap(String process, int userId, boolean managed, 18403 String path, ParcelFileDescriptor fd) throws RemoteException { 18404 18405 try { 18406 synchronized (this) { 18407 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18408 // its own permission (same as profileControl). 18409 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18410 != PackageManager.PERMISSION_GRANTED) { 18411 throw new SecurityException("Requires permission " 18412 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18413 } 18414 18415 if (fd == null) { 18416 throw new IllegalArgumentException("null fd"); 18417 } 18418 18419 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18420 if (proc == null || proc.thread == null) { 18421 throw new IllegalArgumentException("Unknown process: " + process); 18422 } 18423 18424 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18425 if (!isDebuggable) { 18426 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18427 throw new SecurityException("Process not debuggable: " + proc); 18428 } 18429 } 18430 18431 proc.thread.dumpHeap(managed, path, fd); 18432 fd = null; 18433 return true; 18434 } 18435 } catch (RemoteException e) { 18436 throw new IllegalStateException("Process disappeared"); 18437 } finally { 18438 if (fd != null) { 18439 try { 18440 fd.close(); 18441 } catch (IOException e) { 18442 } 18443 } 18444 } 18445 } 18446 18447 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18448 public void monitor() { 18449 synchronized (this) { } 18450 } 18451 18452 void onCoreSettingsChange(Bundle settings) { 18453 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18454 ProcessRecord processRecord = mLruProcesses.get(i); 18455 try { 18456 if (processRecord.thread != null) { 18457 processRecord.thread.setCoreSettings(settings); 18458 } 18459 } catch (RemoteException re) { 18460 /* ignore */ 18461 } 18462 } 18463 } 18464 18465 // Multi-user methods 18466 18467 /** 18468 * Start user, if its not already running, but don't bring it to foreground. 18469 */ 18470 @Override 18471 public boolean startUserInBackground(final int userId) { 18472 return startUser(userId, /* foreground */ false); 18473 } 18474 18475 /** 18476 * Start user, if its not already running, and bring it to foreground. 18477 */ 18478 boolean startUserInForeground(final int userId, Dialog dlg) { 18479 boolean result = startUser(userId, /* foreground */ true); 18480 dlg.dismiss(); 18481 return result; 18482 } 18483 18484 /** 18485 * Refreshes the list of users related to the current user when either a 18486 * user switch happens or when a new related user is started in the 18487 * background. 18488 */ 18489 private void updateCurrentProfileIdsLocked() { 18490 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18491 mCurrentUserId, false /* enabledOnly */); 18492 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18493 for (int i = 0; i < currentProfileIds.length; i++) { 18494 currentProfileIds[i] = profiles.get(i).id; 18495 } 18496 mCurrentProfileIds = currentProfileIds; 18497 18498 synchronized (mUserProfileGroupIdsSelfLocked) { 18499 mUserProfileGroupIdsSelfLocked.clear(); 18500 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18501 for (int i = 0; i < users.size(); i++) { 18502 UserInfo user = users.get(i); 18503 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18504 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18505 } 18506 } 18507 } 18508 } 18509 18510 private Set getProfileIdsLocked(int userId) { 18511 Set userIds = new HashSet<Integer>(); 18512 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18513 userId, false /* enabledOnly */); 18514 for (UserInfo user : profiles) { 18515 userIds.add(Integer.valueOf(user.id)); 18516 } 18517 return userIds; 18518 } 18519 18520 @Override 18521 public boolean switchUser(final int userId) { 18522 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18523 String userName; 18524 synchronized (this) { 18525 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18526 if (userInfo == null) { 18527 Slog.w(TAG, "No user info for user #" + userId); 18528 return false; 18529 } 18530 if (userInfo.isManagedProfile()) { 18531 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18532 return false; 18533 } 18534 userName = userInfo.name; 18535 mTargetUserId = userId; 18536 } 18537 mHandler.removeMessages(START_USER_SWITCH_MSG); 18538 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18539 return true; 18540 } 18541 18542 private void showUserSwitchDialog(int userId, String userName) { 18543 // The dialog will show and then initiate the user switch by calling startUserInForeground 18544 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18545 true /* above system */); 18546 d.show(); 18547 } 18548 18549 private boolean startUser(final int userId, final boolean foreground) { 18550 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18551 != PackageManager.PERMISSION_GRANTED) { 18552 String msg = "Permission Denial: switchUser() from pid=" 18553 + Binder.getCallingPid() 18554 + ", uid=" + Binder.getCallingUid() 18555 + " requires " + INTERACT_ACROSS_USERS_FULL; 18556 Slog.w(TAG, msg); 18557 throw new SecurityException(msg); 18558 } 18559 18560 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18561 18562 final long ident = Binder.clearCallingIdentity(); 18563 try { 18564 synchronized (this) { 18565 final int oldUserId = mCurrentUserId; 18566 if (oldUserId == userId) { 18567 return true; 18568 } 18569 18570 mStackSupervisor.setLockTaskModeLocked(null, false); 18571 18572 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18573 if (userInfo == null) { 18574 Slog.w(TAG, "No user info for user #" + userId); 18575 return false; 18576 } 18577 if (foreground && userInfo.isManagedProfile()) { 18578 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18579 return false; 18580 } 18581 18582 if (foreground) { 18583 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18584 R.anim.screen_user_enter); 18585 } 18586 18587 boolean needStart = false; 18588 18589 // If the user we are switching to is not currently started, then 18590 // we need to start it now. 18591 if (mStartedUsers.get(userId) == null) { 18592 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18593 updateStartedUserArrayLocked(); 18594 needStart = true; 18595 } 18596 18597 final Integer userIdInt = Integer.valueOf(userId); 18598 mUserLru.remove(userIdInt); 18599 mUserLru.add(userIdInt); 18600 18601 if (foreground) { 18602 mCurrentUserId = userId; 18603 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18604 updateCurrentProfileIdsLocked(); 18605 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18606 // Once the internal notion of the active user has switched, we lock the device 18607 // with the option to show the user switcher on the keyguard. 18608 mWindowManager.lockNow(null); 18609 } else { 18610 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18611 updateCurrentProfileIdsLocked(); 18612 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18613 mUserLru.remove(currentUserIdInt); 18614 mUserLru.add(currentUserIdInt); 18615 } 18616 18617 final UserStartedState uss = mStartedUsers.get(userId); 18618 18619 // Make sure user is in the started state. If it is currently 18620 // stopping, we need to knock that off. 18621 if (uss.mState == UserStartedState.STATE_STOPPING) { 18622 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18623 // so we can just fairly silently bring the user back from 18624 // the almost-dead. 18625 uss.mState = UserStartedState.STATE_RUNNING; 18626 updateStartedUserArrayLocked(); 18627 needStart = true; 18628 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18629 // This means ACTION_SHUTDOWN has been sent, so we will 18630 // need to treat this as a new boot of the user. 18631 uss.mState = UserStartedState.STATE_BOOTING; 18632 updateStartedUserArrayLocked(); 18633 needStart = true; 18634 } 18635 18636 if (uss.mState == UserStartedState.STATE_BOOTING) { 18637 // Booting up a new user, need to tell system services about it. 18638 // Note that this is on the same handler as scheduling of broadcasts, 18639 // which is important because it needs to go first. 18640 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18641 } 18642 18643 if (foreground) { 18644 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18645 oldUserId)); 18646 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18647 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18648 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18649 oldUserId, userId, uss)); 18650 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18651 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18652 } 18653 18654 if (needStart) { 18655 // Send USER_STARTED broadcast 18656 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18657 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18658 | Intent.FLAG_RECEIVER_FOREGROUND); 18659 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18660 broadcastIntentLocked(null, null, intent, 18661 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18662 false, false, MY_PID, Process.SYSTEM_UID, userId); 18663 } 18664 18665 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18666 if (userId != UserHandle.USER_OWNER) { 18667 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18668 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18669 broadcastIntentLocked(null, null, intent, null, 18670 new IIntentReceiver.Stub() { 18671 public void performReceive(Intent intent, int resultCode, 18672 String data, Bundle extras, boolean ordered, 18673 boolean sticky, int sendingUser) { 18674 onUserInitialized(uss, foreground, oldUserId, userId); 18675 } 18676 }, 0, null, null, null, AppOpsManager.OP_NONE, 18677 true, false, MY_PID, Process.SYSTEM_UID, 18678 userId); 18679 uss.initializing = true; 18680 } else { 18681 getUserManagerLocked().makeInitialized(userInfo.id); 18682 } 18683 } 18684 18685 if (foreground) { 18686 if (!uss.initializing) { 18687 moveUserToForeground(uss, oldUserId, userId); 18688 } 18689 } else { 18690 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18691 } 18692 18693 if (needStart) { 18694 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18695 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18696 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18697 broadcastIntentLocked(null, null, intent, 18698 null, new IIntentReceiver.Stub() { 18699 @Override 18700 public void performReceive(Intent intent, int resultCode, String data, 18701 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18702 throws RemoteException { 18703 } 18704 }, 0, null, null, 18705 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18706 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18707 } 18708 } 18709 } finally { 18710 Binder.restoreCallingIdentity(ident); 18711 } 18712 18713 return true; 18714 } 18715 18716 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18717 long ident = Binder.clearCallingIdentity(); 18718 try { 18719 Intent intent; 18720 if (oldUserId >= 0) { 18721 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18722 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18723 int count = profiles.size(); 18724 for (int i = 0; i < count; i++) { 18725 int profileUserId = profiles.get(i).id; 18726 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18727 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18728 | Intent.FLAG_RECEIVER_FOREGROUND); 18729 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18730 broadcastIntentLocked(null, null, intent, 18731 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18732 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18733 } 18734 } 18735 if (newUserId >= 0) { 18736 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18737 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18738 int count = profiles.size(); 18739 for (int i = 0; i < count; i++) { 18740 int profileUserId = profiles.get(i).id; 18741 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18742 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18743 | Intent.FLAG_RECEIVER_FOREGROUND); 18744 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18745 broadcastIntentLocked(null, null, intent, 18746 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18747 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18748 } 18749 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18750 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18751 | Intent.FLAG_RECEIVER_FOREGROUND); 18752 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18753 broadcastIntentLocked(null, null, intent, 18754 null, null, 0, null, null, 18755 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18756 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18757 } 18758 } finally { 18759 Binder.restoreCallingIdentity(ident); 18760 } 18761 } 18762 18763 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18764 final int newUserId) { 18765 final int N = mUserSwitchObservers.beginBroadcast(); 18766 if (N > 0) { 18767 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18768 int mCount = 0; 18769 @Override 18770 public void sendResult(Bundle data) throws RemoteException { 18771 synchronized (ActivityManagerService.this) { 18772 if (mCurUserSwitchCallback == this) { 18773 mCount++; 18774 if (mCount == N) { 18775 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18776 } 18777 } 18778 } 18779 } 18780 }; 18781 synchronized (this) { 18782 uss.switching = true; 18783 mCurUserSwitchCallback = callback; 18784 } 18785 for (int i=0; i<N; i++) { 18786 try { 18787 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18788 newUserId, callback); 18789 } catch (RemoteException e) { 18790 } 18791 } 18792 } else { 18793 synchronized (this) { 18794 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18795 } 18796 } 18797 mUserSwitchObservers.finishBroadcast(); 18798 } 18799 18800 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18801 synchronized (this) { 18802 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18803 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18804 } 18805 } 18806 18807 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18808 mCurUserSwitchCallback = null; 18809 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18810 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18811 oldUserId, newUserId, uss)); 18812 } 18813 18814 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18815 synchronized (this) { 18816 if (foreground) { 18817 moveUserToForeground(uss, oldUserId, newUserId); 18818 } 18819 } 18820 18821 completeSwitchAndInitalize(uss, newUserId, true, false); 18822 } 18823 18824 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18825 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18826 if (homeInFront) { 18827 startHomeActivityLocked(newUserId); 18828 } else { 18829 mStackSupervisor.resumeTopActivitiesLocked(); 18830 } 18831 EventLogTags.writeAmSwitchUser(newUserId); 18832 getUserManagerLocked().userForeground(newUserId); 18833 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18834 } 18835 18836 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18837 completeSwitchAndInitalize(uss, newUserId, false, true); 18838 } 18839 18840 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18841 boolean clearInitializing, boolean clearSwitching) { 18842 boolean unfrozen = false; 18843 synchronized (this) { 18844 if (clearInitializing) { 18845 uss.initializing = false; 18846 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18847 } 18848 if (clearSwitching) { 18849 uss.switching = false; 18850 } 18851 if (!uss.switching && !uss.initializing) { 18852 mWindowManager.stopFreezingScreen(); 18853 unfrozen = true; 18854 } 18855 } 18856 if (unfrozen) { 18857 final int N = mUserSwitchObservers.beginBroadcast(); 18858 for (int i=0; i<N; i++) { 18859 try { 18860 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18861 } catch (RemoteException e) { 18862 } 18863 } 18864 mUserSwitchObservers.finishBroadcast(); 18865 } 18866 } 18867 18868 void scheduleStartProfilesLocked() { 18869 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18870 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18871 DateUtils.SECOND_IN_MILLIS); 18872 } 18873 } 18874 18875 void startProfilesLocked() { 18876 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18877 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18878 mCurrentUserId, false /* enabledOnly */); 18879 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18880 for (UserInfo user : profiles) { 18881 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18882 && user.id != mCurrentUserId) { 18883 toStart.add(user); 18884 } 18885 } 18886 final int n = toStart.size(); 18887 int i = 0; 18888 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18889 startUserInBackground(toStart.get(i).id); 18890 } 18891 if (i < n) { 18892 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18893 } 18894 } 18895 18896 void finishUserBoot(UserStartedState uss) { 18897 synchronized (this) { 18898 if (uss.mState == UserStartedState.STATE_BOOTING 18899 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18900 uss.mState = UserStartedState.STATE_RUNNING; 18901 final int userId = uss.mHandle.getIdentifier(); 18902 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18903 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18904 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18905 broadcastIntentLocked(null, null, intent, 18906 null, null, 0, null, null, 18907 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18908 true, false, MY_PID, Process.SYSTEM_UID, userId); 18909 } 18910 } 18911 } 18912 18913 void finishUserSwitch(UserStartedState uss) { 18914 synchronized (this) { 18915 finishUserBoot(uss); 18916 18917 startProfilesLocked(); 18918 18919 int num = mUserLru.size(); 18920 int i = 0; 18921 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18922 Integer oldUserId = mUserLru.get(i); 18923 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18924 if (oldUss == null) { 18925 // Shouldn't happen, but be sane if it does. 18926 mUserLru.remove(i); 18927 num--; 18928 continue; 18929 } 18930 if (oldUss.mState == UserStartedState.STATE_STOPPING 18931 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18932 // This user is already stopping, doesn't count. 18933 num--; 18934 i++; 18935 continue; 18936 } 18937 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18938 // Owner and current can't be stopped, but count as running. 18939 i++; 18940 continue; 18941 } 18942 // This is a user to be stopped. 18943 stopUserLocked(oldUserId, null); 18944 num--; 18945 i++; 18946 } 18947 } 18948 } 18949 18950 @Override 18951 public int stopUser(final int userId, final IStopUserCallback callback) { 18952 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18953 != PackageManager.PERMISSION_GRANTED) { 18954 String msg = "Permission Denial: switchUser() from pid=" 18955 + Binder.getCallingPid() 18956 + ", uid=" + Binder.getCallingUid() 18957 + " requires " + INTERACT_ACROSS_USERS_FULL; 18958 Slog.w(TAG, msg); 18959 throw new SecurityException(msg); 18960 } 18961 if (userId <= 0) { 18962 throw new IllegalArgumentException("Can't stop primary user " + userId); 18963 } 18964 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18965 synchronized (this) { 18966 return stopUserLocked(userId, callback); 18967 } 18968 } 18969 18970 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18971 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18972 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18973 return ActivityManager.USER_OP_IS_CURRENT; 18974 } 18975 18976 final UserStartedState uss = mStartedUsers.get(userId); 18977 if (uss == null) { 18978 // User is not started, nothing to do... but we do need to 18979 // callback if requested. 18980 if (callback != null) { 18981 mHandler.post(new Runnable() { 18982 @Override 18983 public void run() { 18984 try { 18985 callback.userStopped(userId); 18986 } catch (RemoteException e) { 18987 } 18988 } 18989 }); 18990 } 18991 return ActivityManager.USER_OP_SUCCESS; 18992 } 18993 18994 if (callback != null) { 18995 uss.mStopCallbacks.add(callback); 18996 } 18997 18998 if (uss.mState != UserStartedState.STATE_STOPPING 18999 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19000 uss.mState = UserStartedState.STATE_STOPPING; 19001 updateStartedUserArrayLocked(); 19002 19003 long ident = Binder.clearCallingIdentity(); 19004 try { 19005 // We are going to broadcast ACTION_USER_STOPPING and then 19006 // once that is done send a final ACTION_SHUTDOWN and then 19007 // stop the user. 19008 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19009 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19010 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19011 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19012 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19013 // This is the result receiver for the final shutdown broadcast. 19014 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19015 @Override 19016 public void performReceive(Intent intent, int resultCode, String data, 19017 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19018 finishUserStop(uss); 19019 } 19020 }; 19021 // This is the result receiver for the initial stopping broadcast. 19022 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19023 @Override 19024 public void performReceive(Intent intent, int resultCode, String data, 19025 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19026 // On to the next. 19027 synchronized (ActivityManagerService.this) { 19028 if (uss.mState != UserStartedState.STATE_STOPPING) { 19029 // Whoops, we are being started back up. Abort, abort! 19030 return; 19031 } 19032 uss.mState = UserStartedState.STATE_SHUTDOWN; 19033 } 19034 mBatteryStatsService.noteEvent( 19035 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19036 Integer.toString(userId), userId); 19037 mSystemServiceManager.stopUser(userId); 19038 broadcastIntentLocked(null, null, shutdownIntent, 19039 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19040 true, false, MY_PID, Process.SYSTEM_UID, userId); 19041 } 19042 }; 19043 // Kick things off. 19044 broadcastIntentLocked(null, null, stoppingIntent, 19045 null, stoppingReceiver, 0, null, null, 19046 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19047 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19048 } finally { 19049 Binder.restoreCallingIdentity(ident); 19050 } 19051 } 19052 19053 return ActivityManager.USER_OP_SUCCESS; 19054 } 19055 19056 void finishUserStop(UserStartedState uss) { 19057 final int userId = uss.mHandle.getIdentifier(); 19058 boolean stopped; 19059 ArrayList<IStopUserCallback> callbacks; 19060 synchronized (this) { 19061 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19062 if (mStartedUsers.get(userId) != uss) { 19063 stopped = false; 19064 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19065 stopped = false; 19066 } else { 19067 stopped = true; 19068 // User can no longer run. 19069 mStartedUsers.remove(userId); 19070 mUserLru.remove(Integer.valueOf(userId)); 19071 updateStartedUserArrayLocked(); 19072 19073 // Clean up all state and processes associated with the user. 19074 // Kill all the processes for the user. 19075 forceStopUserLocked(userId, "finish user"); 19076 } 19077 19078 // Explicitly remove the old information in mRecentTasks. 19079 removeRecentTasksForUserLocked(userId); 19080 } 19081 19082 for (int i=0; i<callbacks.size(); i++) { 19083 try { 19084 if (stopped) callbacks.get(i).userStopped(userId); 19085 else callbacks.get(i).userStopAborted(userId); 19086 } catch (RemoteException e) { 19087 } 19088 } 19089 19090 if (stopped) { 19091 mSystemServiceManager.cleanupUser(userId); 19092 synchronized (this) { 19093 mStackSupervisor.removeUserLocked(userId); 19094 } 19095 } 19096 } 19097 19098 @Override 19099 public UserInfo getCurrentUser() { 19100 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19101 != PackageManager.PERMISSION_GRANTED) && ( 19102 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19103 != PackageManager.PERMISSION_GRANTED)) { 19104 String msg = "Permission Denial: getCurrentUser() from pid=" 19105 + Binder.getCallingPid() 19106 + ", uid=" + Binder.getCallingUid() 19107 + " requires " + INTERACT_ACROSS_USERS; 19108 Slog.w(TAG, msg); 19109 throw new SecurityException(msg); 19110 } 19111 synchronized (this) { 19112 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19113 return getUserManagerLocked().getUserInfo(userId); 19114 } 19115 } 19116 19117 int getCurrentUserIdLocked() { 19118 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19119 } 19120 19121 @Override 19122 public boolean isUserRunning(int userId, boolean orStopped) { 19123 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19124 != PackageManager.PERMISSION_GRANTED) { 19125 String msg = "Permission Denial: isUserRunning() from pid=" 19126 + Binder.getCallingPid() 19127 + ", uid=" + Binder.getCallingUid() 19128 + " requires " + INTERACT_ACROSS_USERS; 19129 Slog.w(TAG, msg); 19130 throw new SecurityException(msg); 19131 } 19132 synchronized (this) { 19133 return isUserRunningLocked(userId, orStopped); 19134 } 19135 } 19136 19137 boolean isUserRunningLocked(int userId, boolean orStopped) { 19138 UserStartedState state = mStartedUsers.get(userId); 19139 if (state == null) { 19140 return false; 19141 } 19142 if (orStopped) { 19143 return true; 19144 } 19145 return state.mState != UserStartedState.STATE_STOPPING 19146 && state.mState != UserStartedState.STATE_SHUTDOWN; 19147 } 19148 19149 @Override 19150 public int[] getRunningUserIds() { 19151 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19152 != PackageManager.PERMISSION_GRANTED) { 19153 String msg = "Permission Denial: isUserRunning() from pid=" 19154 + Binder.getCallingPid() 19155 + ", uid=" + Binder.getCallingUid() 19156 + " requires " + INTERACT_ACROSS_USERS; 19157 Slog.w(TAG, msg); 19158 throw new SecurityException(msg); 19159 } 19160 synchronized (this) { 19161 return mStartedUserArray; 19162 } 19163 } 19164 19165 private void updateStartedUserArrayLocked() { 19166 int num = 0; 19167 for (int i=0; i<mStartedUsers.size(); i++) { 19168 UserStartedState uss = mStartedUsers.valueAt(i); 19169 // This list does not include stopping users. 19170 if (uss.mState != UserStartedState.STATE_STOPPING 19171 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19172 num++; 19173 } 19174 } 19175 mStartedUserArray = new int[num]; 19176 num = 0; 19177 for (int i=0; i<mStartedUsers.size(); i++) { 19178 UserStartedState uss = mStartedUsers.valueAt(i); 19179 if (uss.mState != UserStartedState.STATE_STOPPING 19180 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19181 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19182 num++; 19183 } 19184 } 19185 } 19186 19187 @Override 19188 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19189 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19190 != PackageManager.PERMISSION_GRANTED) { 19191 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19192 + Binder.getCallingPid() 19193 + ", uid=" + Binder.getCallingUid() 19194 + " requires " + INTERACT_ACROSS_USERS_FULL; 19195 Slog.w(TAG, msg); 19196 throw new SecurityException(msg); 19197 } 19198 19199 mUserSwitchObservers.register(observer); 19200 } 19201 19202 @Override 19203 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19204 mUserSwitchObservers.unregister(observer); 19205 } 19206 19207 private boolean userExists(int userId) { 19208 if (userId == 0) { 19209 return true; 19210 } 19211 UserManagerService ums = getUserManagerLocked(); 19212 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19213 } 19214 19215 int[] getUsersLocked() { 19216 UserManagerService ums = getUserManagerLocked(); 19217 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19218 } 19219 19220 UserManagerService getUserManagerLocked() { 19221 if (mUserManager == null) { 19222 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19223 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19224 } 19225 return mUserManager; 19226 } 19227 19228 private int applyUserId(int uid, int userId) { 19229 return UserHandle.getUid(userId, uid); 19230 } 19231 19232 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19233 if (info == null) return null; 19234 ApplicationInfo newInfo = new ApplicationInfo(info); 19235 newInfo.uid = applyUserId(info.uid, userId); 19236 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19237 + info.packageName; 19238 return newInfo; 19239 } 19240 19241 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19242 if (aInfo == null 19243 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19244 return aInfo; 19245 } 19246 19247 ActivityInfo info = new ActivityInfo(aInfo); 19248 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19249 return info; 19250 } 19251 19252 private final class LocalService extends ActivityManagerInternal { 19253 @Override 19254 public void onWakefulnessChanged(int wakefulness) { 19255 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19256 } 19257 19258 @Override 19259 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19260 String processName, String abiOverride, int uid, Runnable crashHandler) { 19261 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19262 processName, abiOverride, uid, crashHandler); 19263 } 19264 } 19265 19266 /** 19267 * An implementation of IAppTask, that allows an app to manage its own tasks via 19268 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19269 * only the process that calls getAppTasks() can call the AppTask methods. 19270 */ 19271 class AppTaskImpl extends IAppTask.Stub { 19272 private int mTaskId; 19273 private int mCallingUid; 19274 19275 public AppTaskImpl(int taskId, int callingUid) { 19276 mTaskId = taskId; 19277 mCallingUid = callingUid; 19278 } 19279 19280 private void checkCaller() { 19281 if (mCallingUid != Binder.getCallingUid()) { 19282 throw new SecurityException("Caller " + mCallingUid 19283 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19284 } 19285 } 19286 19287 @Override 19288 public void finishAndRemoveTask() { 19289 checkCaller(); 19290 19291 synchronized (ActivityManagerService.this) { 19292 long origId = Binder.clearCallingIdentity(); 19293 try { 19294 if (!removeTaskByIdLocked(mTaskId, false)) { 19295 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19296 } 19297 } finally { 19298 Binder.restoreCallingIdentity(origId); 19299 } 19300 } 19301 } 19302 19303 @Override 19304 public ActivityManager.RecentTaskInfo getTaskInfo() { 19305 checkCaller(); 19306 19307 synchronized (ActivityManagerService.this) { 19308 long origId = Binder.clearCallingIdentity(); 19309 try { 19310 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19311 if (tr == null) { 19312 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19313 } 19314 return createRecentTaskInfoFromTaskRecord(tr); 19315 } finally { 19316 Binder.restoreCallingIdentity(origId); 19317 } 19318 } 19319 } 19320 19321 @Override 19322 public void moveToFront() { 19323 checkCaller(); 19324 19325 final TaskRecord tr; 19326 synchronized (ActivityManagerService.this) { 19327 tr = recentTaskForIdLocked(mTaskId); 19328 if (tr == null) { 19329 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19330 } 19331 if (tr.getRootActivity() != null) { 19332 moveTaskToFrontLocked(tr.taskId, 0, null); 19333 return; 19334 } 19335 } 19336 19337 startActivityFromRecentsInner(tr.taskId, null); 19338 } 19339 19340 @Override 19341 public int startActivity(IBinder whoThread, String callingPackage, 19342 Intent intent, String resolvedType, Bundle options) { 19343 checkCaller(); 19344 19345 int callingUser = UserHandle.getCallingUserId(); 19346 TaskRecord tr; 19347 IApplicationThread appThread; 19348 synchronized (ActivityManagerService.this) { 19349 tr = recentTaskForIdLocked(mTaskId); 19350 if (tr == null) { 19351 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19352 } 19353 appThread = ApplicationThreadNative.asInterface(whoThread); 19354 if (appThread == null) { 19355 throw new IllegalArgumentException("Bad app thread " + appThread); 19356 } 19357 } 19358 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19359 resolvedType, null, null, null, null, 0, 0, null, null, 19360 null, options, callingUser, null, tr); 19361 } 19362 19363 @Override 19364 public void setExcludeFromRecents(boolean exclude) { 19365 checkCaller(); 19366 19367 synchronized (ActivityManagerService.this) { 19368 long origId = Binder.clearCallingIdentity(); 19369 try { 19370 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19371 if (tr == null) { 19372 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19373 } 19374 Intent intent = tr.getBaseIntent(); 19375 if (exclude) { 19376 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19377 } else { 19378 intent.setFlags(intent.getFlags() 19379 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19380 } 19381 } finally { 19382 Binder.restoreCallingIdentity(origId); 19383 } 19384 } 19385 } 19386 } 19387} 19388