ActivityManagerService.java revision 2faf91fbb300882afd1092b788aa16295eb3dde8
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 synchronized (ActivityManagerService.this) { 1673 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1674 } 1675 break; 1676 } 1677 case START_PROFILES_MSG: { 1678 synchronized (ActivityManagerService.this) { 1679 startProfilesLocked(); 1680 } 1681 break; 1682 } 1683 case UPDATE_TIME: { 1684 synchronized (ActivityManagerService.this) { 1685 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1686 ProcessRecord r = mLruProcesses.get(i); 1687 if (r.thread != null) { 1688 try { 1689 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1690 } catch (RemoteException ex) { 1691 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1692 } 1693 } 1694 } 1695 } 1696 break; 1697 } 1698 case SYSTEM_USER_START_MSG: { 1699 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1700 Integer.toString(msg.arg1), msg.arg1); 1701 mSystemServiceManager.startUser(msg.arg1); 1702 break; 1703 } 1704 case SYSTEM_USER_CURRENT_MSG: { 1705 mBatteryStatsService.noteEvent( 1706 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1707 Integer.toString(msg.arg2), msg.arg2); 1708 mBatteryStatsService.noteEvent( 1709 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1710 Integer.toString(msg.arg1), msg.arg1); 1711 mSystemServiceManager.switchUser(msg.arg1); 1712 break; 1713 } 1714 case ENTER_ANIMATION_COMPLETE_MSG: { 1715 synchronized (ActivityManagerService.this) { 1716 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1717 if (r != null && r.app != null && r.app.thread != null) { 1718 try { 1719 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1720 } catch (RemoteException e) { 1721 } 1722 } 1723 } 1724 break; 1725 } 1726 case FINISH_BOOTING_MSG: { 1727 if (msg.arg1 != 0) { 1728 finishBooting(); 1729 } 1730 if (msg.arg2 != 0) { 1731 enableScreenAfterBoot(); 1732 } 1733 break; 1734 } 1735 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1736 try { 1737 Locale l = (Locale) msg.obj; 1738 IBinder service = ServiceManager.getService("mount"); 1739 IMountService mountService = IMountService.Stub.asInterface(service); 1740 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1741 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1742 } catch (RemoteException e) { 1743 Log.e(TAG, "Error storing locale for decryption UI", e); 1744 } 1745 break; 1746 } 1747 case DISMISS_DIALOG_MSG: { 1748 final Dialog d = (Dialog) msg.obj; 1749 d.dismiss(); 1750 break; 1751 } 1752 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1753 synchronized (ActivityManagerService.this) { 1754 int i = mTaskStackListeners.beginBroadcast(); 1755 while (i > 0) { 1756 i--; 1757 try { 1758 // Make a one-way callback to the listener 1759 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1760 } catch (RemoteException e){ 1761 // Handled by the RemoteCallbackList 1762 } 1763 } 1764 mTaskStackListeners.finishBroadcast(); 1765 } 1766 break; 1767 } 1768 } 1769 } 1770 }; 1771 1772 static final int COLLECT_PSS_BG_MSG = 1; 1773 1774 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1775 @Override 1776 public void handleMessage(Message msg) { 1777 switch (msg.what) { 1778 case COLLECT_PSS_BG_MSG: { 1779 long start = SystemClock.uptimeMillis(); 1780 MemInfoReader memInfo = null; 1781 synchronized (ActivityManagerService.this) { 1782 if (mFullPssPending) { 1783 mFullPssPending = false; 1784 memInfo = new MemInfoReader(); 1785 } 1786 } 1787 if (memInfo != null) { 1788 updateCpuStatsNow(); 1789 long nativeTotalPss = 0; 1790 synchronized (mProcessCpuTracker) { 1791 final int N = mProcessCpuTracker.countStats(); 1792 for (int j=0; j<N; j++) { 1793 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1794 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1795 // This is definitely an application process; skip it. 1796 continue; 1797 } 1798 synchronized (mPidsSelfLocked) { 1799 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1800 // This is one of our own processes; skip it. 1801 continue; 1802 } 1803 } 1804 nativeTotalPss += Debug.getPss(st.pid, null); 1805 } 1806 } 1807 memInfo.readMemInfo(); 1808 synchronized (ActivityManagerService.this) { 1809 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1810 + (SystemClock.uptimeMillis()-start) + "ms"); 1811 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1812 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1813 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1814 } 1815 } 1816 1817 int i = 0; 1818 int num = 0; 1819 long[] tmp = new long[1]; 1820 do { 1821 ProcessRecord proc; 1822 int procState; 1823 int pid; 1824 synchronized (ActivityManagerService.this) { 1825 if (i >= mPendingPssProcesses.size()) { 1826 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1827 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1828 mPendingPssProcesses.clear(); 1829 return; 1830 } 1831 proc = mPendingPssProcesses.get(i); 1832 procState = proc.pssProcState; 1833 if (proc.thread != null && procState == proc.setProcState) { 1834 pid = proc.pid; 1835 } else { 1836 proc = null; 1837 pid = 0; 1838 } 1839 i++; 1840 } 1841 if (proc != null) { 1842 long pss = Debug.getPss(pid, tmp); 1843 synchronized (ActivityManagerService.this) { 1844 if (proc.thread != null && proc.setProcState == procState 1845 && proc.pid == pid) { 1846 num++; 1847 proc.lastPssTime = SystemClock.uptimeMillis(); 1848 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1849 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1850 + ": " + pss + " lastPss=" + proc.lastPss 1851 + " state=" + ProcessList.makeProcStateString(procState)); 1852 if (proc.initialIdlePss == 0) { 1853 proc.initialIdlePss = pss; 1854 } 1855 proc.lastPss = pss; 1856 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1857 proc.lastCachedPss = pss; 1858 } 1859 } 1860 } 1861 } 1862 } while (true); 1863 } 1864 } 1865 } 1866 }; 1867 1868 public void setSystemProcess() { 1869 try { 1870 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1871 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1872 ServiceManager.addService("meminfo", new MemBinder(this)); 1873 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1874 ServiceManager.addService("dbinfo", new DbBinder(this)); 1875 if (MONITOR_CPU_USAGE) { 1876 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1877 } 1878 ServiceManager.addService("permission", new PermissionController(this)); 1879 1880 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1881 "android", STOCK_PM_FLAGS); 1882 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1883 1884 synchronized (this) { 1885 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1886 app.persistent = true; 1887 app.pid = MY_PID; 1888 app.maxAdj = ProcessList.SYSTEM_ADJ; 1889 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1890 mProcessNames.put(app.processName, app.uid, app); 1891 synchronized (mPidsSelfLocked) { 1892 mPidsSelfLocked.put(app.pid, app); 1893 } 1894 updateLruProcessLocked(app, false, null); 1895 updateOomAdjLocked(); 1896 } 1897 } catch (PackageManager.NameNotFoundException e) { 1898 throw new RuntimeException( 1899 "Unable to find android system package", e); 1900 } 1901 } 1902 1903 public void setWindowManager(WindowManagerService wm) { 1904 mWindowManager = wm; 1905 mStackSupervisor.setWindowManager(wm); 1906 } 1907 1908 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1909 mUsageStatsService = usageStatsManager; 1910 } 1911 1912 public void startObservingNativeCrashes() { 1913 final NativeCrashListener ncl = new NativeCrashListener(this); 1914 ncl.start(); 1915 } 1916 1917 public IAppOpsService getAppOpsService() { 1918 return mAppOpsService; 1919 } 1920 1921 static class MemBinder extends Binder { 1922 ActivityManagerService mActivityManagerService; 1923 MemBinder(ActivityManagerService activityManagerService) { 1924 mActivityManagerService = activityManagerService; 1925 } 1926 1927 @Override 1928 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1929 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1930 != PackageManager.PERMISSION_GRANTED) { 1931 pw.println("Permission Denial: can't dump meminfo from from pid=" 1932 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1933 + " without permission " + android.Manifest.permission.DUMP); 1934 return; 1935 } 1936 1937 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1938 } 1939 } 1940 1941 static class GraphicsBinder extends Binder { 1942 ActivityManagerService mActivityManagerService; 1943 GraphicsBinder(ActivityManagerService activityManagerService) { 1944 mActivityManagerService = activityManagerService; 1945 } 1946 1947 @Override 1948 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1949 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1950 != PackageManager.PERMISSION_GRANTED) { 1951 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1952 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1953 + " without permission " + android.Manifest.permission.DUMP); 1954 return; 1955 } 1956 1957 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1958 } 1959 } 1960 1961 static class DbBinder extends Binder { 1962 ActivityManagerService mActivityManagerService; 1963 DbBinder(ActivityManagerService activityManagerService) { 1964 mActivityManagerService = activityManagerService; 1965 } 1966 1967 @Override 1968 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1969 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1970 != PackageManager.PERMISSION_GRANTED) { 1971 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1972 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1973 + " without permission " + android.Manifest.permission.DUMP); 1974 return; 1975 } 1976 1977 mActivityManagerService.dumpDbInfo(fd, pw, args); 1978 } 1979 } 1980 1981 static class CpuBinder extends Binder { 1982 ActivityManagerService mActivityManagerService; 1983 CpuBinder(ActivityManagerService activityManagerService) { 1984 mActivityManagerService = activityManagerService; 1985 } 1986 1987 @Override 1988 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1989 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1990 != PackageManager.PERMISSION_GRANTED) { 1991 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1992 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1993 + " without permission " + android.Manifest.permission.DUMP); 1994 return; 1995 } 1996 1997 synchronized (mActivityManagerService.mProcessCpuTracker) { 1998 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1999 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2000 SystemClock.uptimeMillis())); 2001 } 2002 } 2003 } 2004 2005 public static final class Lifecycle extends SystemService { 2006 private final ActivityManagerService mService; 2007 2008 public Lifecycle(Context context) { 2009 super(context); 2010 mService = new ActivityManagerService(context); 2011 } 2012 2013 @Override 2014 public void onStart() { 2015 mService.start(); 2016 } 2017 2018 public ActivityManagerService getService() { 2019 return mService; 2020 } 2021 } 2022 2023 // Note: This method is invoked on the main thread but may need to attach various 2024 // handlers to other threads. So take care to be explicit about the looper. 2025 public ActivityManagerService(Context systemContext) { 2026 mContext = systemContext; 2027 mFactoryTest = FactoryTest.getMode(); 2028 mSystemThread = ActivityThread.currentActivityThread(); 2029 2030 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2031 2032 mHandlerThread = new ServiceThread(TAG, 2033 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2034 mHandlerThread.start(); 2035 mHandler = new MainHandler(mHandlerThread.getLooper()); 2036 2037 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2038 "foreground", BROADCAST_FG_TIMEOUT, false); 2039 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2040 "background", BROADCAST_BG_TIMEOUT, true); 2041 mBroadcastQueues[0] = mFgBroadcastQueue; 2042 mBroadcastQueues[1] = mBgBroadcastQueue; 2043 2044 mServices = new ActiveServices(this); 2045 mProviderMap = new ProviderMap(this); 2046 2047 // TODO: Move creation of battery stats service outside of activity manager service. 2048 File dataDir = Environment.getDataDirectory(); 2049 File systemDir = new File(dataDir, "system"); 2050 systemDir.mkdirs(); 2051 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2052 mBatteryStatsService.getActiveStatistics().readLocked(); 2053 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2054 mOnBattery = DEBUG_POWER ? true 2055 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2056 mBatteryStatsService.getActiveStatistics().setCallback(this); 2057 2058 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2059 2060 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2061 2062 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2063 2064 // User 0 is the first and only user that runs at boot. 2065 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2066 mUserLru.add(Integer.valueOf(0)); 2067 updateStartedUserArrayLocked(); 2068 2069 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2070 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2071 2072 mConfiguration.setToDefaults(); 2073 mConfiguration.setLocale(Locale.getDefault()); 2074 2075 mConfigurationSeq = mConfiguration.seq = 1; 2076 mProcessCpuTracker.init(); 2077 2078 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2079 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2080 mStackSupervisor = new ActivityStackSupervisor(this); 2081 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2082 2083 mProcessCpuThread = new Thread("CpuTracker") { 2084 @Override 2085 public void run() { 2086 while (true) { 2087 try { 2088 try { 2089 synchronized(this) { 2090 final long now = SystemClock.uptimeMillis(); 2091 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2092 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2093 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2094 // + ", write delay=" + nextWriteDelay); 2095 if (nextWriteDelay < nextCpuDelay) { 2096 nextCpuDelay = nextWriteDelay; 2097 } 2098 if (nextCpuDelay > 0) { 2099 mProcessCpuMutexFree.set(true); 2100 this.wait(nextCpuDelay); 2101 } 2102 } 2103 } catch (InterruptedException e) { 2104 } 2105 updateCpuStatsNow(); 2106 } catch (Exception e) { 2107 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2108 } 2109 } 2110 } 2111 }; 2112 2113 Watchdog.getInstance().addMonitor(this); 2114 Watchdog.getInstance().addThread(mHandler); 2115 } 2116 2117 public void setSystemServiceManager(SystemServiceManager mgr) { 2118 mSystemServiceManager = mgr; 2119 } 2120 2121 public void setInstaller(Installer installer) { 2122 mInstaller = installer; 2123 } 2124 2125 private void start() { 2126 Process.removeAllProcessGroups(); 2127 mProcessCpuThread.start(); 2128 2129 mBatteryStatsService.publish(mContext); 2130 mAppOpsService.publish(mContext); 2131 Slog.d("AppOps", "AppOpsService published"); 2132 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2133 } 2134 2135 public void initPowerManagement() { 2136 mStackSupervisor.initPowerManagement(); 2137 mBatteryStatsService.initPowerManagement(); 2138 } 2139 2140 @Override 2141 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2142 throws RemoteException { 2143 if (code == SYSPROPS_TRANSACTION) { 2144 // We need to tell all apps about the system property change. 2145 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2146 synchronized(this) { 2147 final int NP = mProcessNames.getMap().size(); 2148 for (int ip=0; ip<NP; ip++) { 2149 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2150 final int NA = apps.size(); 2151 for (int ia=0; ia<NA; ia++) { 2152 ProcessRecord app = apps.valueAt(ia); 2153 if (app.thread != null) { 2154 procs.add(app.thread.asBinder()); 2155 } 2156 } 2157 } 2158 } 2159 2160 int N = procs.size(); 2161 for (int i=0; i<N; i++) { 2162 Parcel data2 = Parcel.obtain(); 2163 try { 2164 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2165 } catch (RemoteException e) { 2166 } 2167 data2.recycle(); 2168 } 2169 } 2170 try { 2171 return super.onTransact(code, data, reply, flags); 2172 } catch (RuntimeException e) { 2173 // The activity manager only throws security exceptions, so let's 2174 // log all others. 2175 if (!(e instanceof SecurityException)) { 2176 Slog.wtf(TAG, "Activity Manager Crash", e); 2177 } 2178 throw e; 2179 } 2180 } 2181 2182 void updateCpuStats() { 2183 final long now = SystemClock.uptimeMillis(); 2184 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2185 return; 2186 } 2187 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2188 synchronized (mProcessCpuThread) { 2189 mProcessCpuThread.notify(); 2190 } 2191 } 2192 } 2193 2194 void updateCpuStatsNow() { 2195 synchronized (mProcessCpuTracker) { 2196 mProcessCpuMutexFree.set(false); 2197 final long now = SystemClock.uptimeMillis(); 2198 boolean haveNewCpuStats = false; 2199 2200 if (MONITOR_CPU_USAGE && 2201 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2202 mLastCpuTime.set(now); 2203 haveNewCpuStats = true; 2204 mProcessCpuTracker.update(); 2205 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2206 //Slog.i(TAG, "Total CPU usage: " 2207 // + mProcessCpu.getTotalCpuPercent() + "%"); 2208 2209 // Slog the cpu usage if the property is set. 2210 if ("true".equals(SystemProperties.get("events.cpu"))) { 2211 int user = mProcessCpuTracker.getLastUserTime(); 2212 int system = mProcessCpuTracker.getLastSystemTime(); 2213 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2214 int irq = mProcessCpuTracker.getLastIrqTime(); 2215 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2216 int idle = mProcessCpuTracker.getLastIdleTime(); 2217 2218 int total = user + system + iowait + irq + softIrq + idle; 2219 if (total == 0) total = 1; 2220 2221 EventLog.writeEvent(EventLogTags.CPU, 2222 ((user+system+iowait+irq+softIrq) * 100) / total, 2223 (user * 100) / total, 2224 (system * 100) / total, 2225 (iowait * 100) / total, 2226 (irq * 100) / total, 2227 (softIrq * 100) / total); 2228 } 2229 } 2230 2231 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2232 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2233 synchronized(bstats) { 2234 synchronized(mPidsSelfLocked) { 2235 if (haveNewCpuStats) { 2236 if (mOnBattery) { 2237 int perc = bstats.startAddingCpuLocked(); 2238 int totalUTime = 0; 2239 int totalSTime = 0; 2240 final int N = mProcessCpuTracker.countStats(); 2241 for (int i=0; i<N; i++) { 2242 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2243 if (!st.working) { 2244 continue; 2245 } 2246 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2247 int otherUTime = (st.rel_utime*perc)/100; 2248 int otherSTime = (st.rel_stime*perc)/100; 2249 totalUTime += otherUTime; 2250 totalSTime += otherSTime; 2251 if (pr != null) { 2252 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2253 if (ps == null || !ps.isActive()) { 2254 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2255 pr.info.uid, pr.processName); 2256 } 2257 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2258 st.rel_stime-otherSTime); 2259 ps.addSpeedStepTimes(cpuSpeedTimes); 2260 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2261 } else { 2262 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2263 if (ps == null || !ps.isActive()) { 2264 st.batteryStats = ps = bstats.getProcessStatsLocked( 2265 bstats.mapUid(st.uid), st.name); 2266 } 2267 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2268 st.rel_stime-otherSTime); 2269 ps.addSpeedStepTimes(cpuSpeedTimes); 2270 } 2271 } 2272 bstats.finishAddingCpuLocked(perc, totalUTime, 2273 totalSTime, cpuSpeedTimes); 2274 } 2275 } 2276 } 2277 2278 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2279 mLastWriteTime = now; 2280 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2281 } 2282 } 2283 } 2284 } 2285 2286 @Override 2287 public void batteryNeedsCpuUpdate() { 2288 updateCpuStatsNow(); 2289 } 2290 2291 @Override 2292 public void batteryPowerChanged(boolean onBattery) { 2293 // When plugging in, update the CPU stats first before changing 2294 // the plug state. 2295 updateCpuStatsNow(); 2296 synchronized (this) { 2297 synchronized(mPidsSelfLocked) { 2298 mOnBattery = DEBUG_POWER ? true : onBattery; 2299 } 2300 } 2301 } 2302 2303 /** 2304 * Initialize the application bind args. These are passed to each 2305 * process when the bindApplication() IPC is sent to the process. They're 2306 * lazily setup to make sure the services are running when they're asked for. 2307 */ 2308 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2309 if (mAppBindArgs == null) { 2310 mAppBindArgs = new HashMap<>(); 2311 2312 // Isolated processes won't get this optimization, so that we don't 2313 // violate the rules about which services they have access to. 2314 if (!isolated) { 2315 // Setup the application init args 2316 mAppBindArgs.put("package", ServiceManager.getService("package")); 2317 mAppBindArgs.put("window", ServiceManager.getService("window")); 2318 mAppBindArgs.put(Context.ALARM_SERVICE, 2319 ServiceManager.getService(Context.ALARM_SERVICE)); 2320 } 2321 } 2322 return mAppBindArgs; 2323 } 2324 2325 final void setFocusedActivityLocked(ActivityRecord r) { 2326 if (mFocusedActivity != r) { 2327 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2328 mFocusedActivity = r; 2329 if (r.task != null && r.task.voiceInteractor != null) { 2330 startRunningVoiceLocked(); 2331 } else { 2332 finishRunningVoiceLocked(); 2333 } 2334 mStackSupervisor.setFocusedStack(r); 2335 if (r != null) { 2336 mWindowManager.setFocusedApp(r.appToken, true); 2337 } 2338 applyUpdateLockStateLocked(r); 2339 } 2340 } 2341 2342 final void clearFocusedActivity(ActivityRecord r) { 2343 if (mFocusedActivity == r) { 2344 mFocusedActivity = null; 2345 } 2346 } 2347 2348 @Override 2349 public void setFocusedStack(int stackId) { 2350 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2351 synchronized (ActivityManagerService.this) { 2352 ActivityStack stack = mStackSupervisor.getStack(stackId); 2353 if (stack != null) { 2354 ActivityRecord r = stack.topRunningActivityLocked(null); 2355 if (r != null) { 2356 setFocusedActivityLocked(r); 2357 } 2358 } 2359 } 2360 } 2361 2362 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2363 @Override 2364 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2365 synchronized (ActivityManagerService.this) { 2366 if (listener != null) { 2367 mTaskStackListeners.register(listener); 2368 } 2369 } 2370 } 2371 2372 @Override 2373 public void notifyActivityDrawn(IBinder token) { 2374 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2375 synchronized (this) { 2376 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2377 if (r != null) { 2378 r.task.stack.notifyActivityDrawnLocked(r); 2379 } 2380 } 2381 } 2382 2383 final void applyUpdateLockStateLocked(ActivityRecord r) { 2384 // Modifications to the UpdateLock state are done on our handler, outside 2385 // the activity manager's locks. The new state is determined based on the 2386 // state *now* of the relevant activity record. The object is passed to 2387 // the handler solely for logging detail, not to be consulted/modified. 2388 final boolean nextState = r != null && r.immersive; 2389 mHandler.sendMessage( 2390 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2391 } 2392 2393 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2394 Message msg = Message.obtain(); 2395 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2396 msg.obj = r.task.askedCompatMode ? null : r; 2397 mHandler.sendMessage(msg); 2398 } 2399 2400 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2401 String what, Object obj, ProcessRecord srcApp) { 2402 app.lastActivityTime = now; 2403 2404 if (app.activities.size() > 0) { 2405 // Don't want to touch dependent processes that are hosting activities. 2406 return index; 2407 } 2408 2409 int lrui = mLruProcesses.lastIndexOf(app); 2410 if (lrui < 0) { 2411 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2412 + what + " " + obj + " from " + srcApp); 2413 return index; 2414 } 2415 2416 if (lrui >= index) { 2417 // Don't want to cause this to move dependent processes *back* in the 2418 // list as if they were less frequently used. 2419 return index; 2420 } 2421 2422 if (lrui >= mLruProcessActivityStart) { 2423 // Don't want to touch dependent processes that are hosting activities. 2424 return index; 2425 } 2426 2427 mLruProcesses.remove(lrui); 2428 if (index > 0) { 2429 index--; 2430 } 2431 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2432 + " in LRU list: " + app); 2433 mLruProcesses.add(index, app); 2434 return index; 2435 } 2436 2437 final void removeLruProcessLocked(ProcessRecord app) { 2438 int lrui = mLruProcesses.lastIndexOf(app); 2439 if (lrui >= 0) { 2440 if (!app.killed) { 2441 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2442 Process.killProcessQuiet(app.pid); 2443 Process.killProcessGroup(app.info.uid, app.pid); 2444 } 2445 if (lrui <= mLruProcessActivityStart) { 2446 mLruProcessActivityStart--; 2447 } 2448 if (lrui <= mLruProcessServiceStart) { 2449 mLruProcessServiceStart--; 2450 } 2451 mLruProcesses.remove(lrui); 2452 } 2453 } 2454 2455 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2456 ProcessRecord client) { 2457 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2458 || app.treatLikeActivity; 2459 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2460 if (!activityChange && hasActivity) { 2461 // The process has activities, so we are only allowing activity-based adjustments 2462 // to move it. It should be kept in the front of the list with other 2463 // processes that have activities, and we don't want those to change their 2464 // order except due to activity operations. 2465 return; 2466 } 2467 2468 mLruSeq++; 2469 final long now = SystemClock.uptimeMillis(); 2470 app.lastActivityTime = now; 2471 2472 // First a quick reject: if the app is already at the position we will 2473 // put it, then there is nothing to do. 2474 if (hasActivity) { 2475 final int N = mLruProcesses.size(); 2476 if (N > 0 && mLruProcesses.get(N-1) == app) { 2477 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2478 return; 2479 } 2480 } else { 2481 if (mLruProcessServiceStart > 0 2482 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2483 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2484 return; 2485 } 2486 } 2487 2488 int lrui = mLruProcesses.lastIndexOf(app); 2489 2490 if (app.persistent && lrui >= 0) { 2491 // We don't care about the position of persistent processes, as long as 2492 // they are in the list. 2493 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2494 return; 2495 } 2496 2497 /* In progress: compute new position first, so we can avoid doing work 2498 if the process is not actually going to move. Not yet working. 2499 int addIndex; 2500 int nextIndex; 2501 boolean inActivity = false, inService = false; 2502 if (hasActivity) { 2503 // Process has activities, put it at the very tipsy-top. 2504 addIndex = mLruProcesses.size(); 2505 nextIndex = mLruProcessServiceStart; 2506 inActivity = true; 2507 } else if (hasService) { 2508 // Process has services, put it at the top of the service list. 2509 addIndex = mLruProcessActivityStart; 2510 nextIndex = mLruProcessServiceStart; 2511 inActivity = true; 2512 inService = true; 2513 } else { 2514 // Process not otherwise of interest, it goes to the top of the non-service area. 2515 addIndex = mLruProcessServiceStart; 2516 if (client != null) { 2517 int clientIndex = mLruProcesses.lastIndexOf(client); 2518 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2519 + app); 2520 if (clientIndex >= 0 && addIndex > clientIndex) { 2521 addIndex = clientIndex; 2522 } 2523 } 2524 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2525 } 2526 2527 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2528 + mLruProcessActivityStart + "): " + app); 2529 */ 2530 2531 if (lrui >= 0) { 2532 if (lrui < mLruProcessActivityStart) { 2533 mLruProcessActivityStart--; 2534 } 2535 if (lrui < mLruProcessServiceStart) { 2536 mLruProcessServiceStart--; 2537 } 2538 /* 2539 if (addIndex > lrui) { 2540 addIndex--; 2541 } 2542 if (nextIndex > lrui) { 2543 nextIndex--; 2544 } 2545 */ 2546 mLruProcesses.remove(lrui); 2547 } 2548 2549 /* 2550 mLruProcesses.add(addIndex, app); 2551 if (inActivity) { 2552 mLruProcessActivityStart++; 2553 } 2554 if (inService) { 2555 mLruProcessActivityStart++; 2556 } 2557 */ 2558 2559 int nextIndex; 2560 if (hasActivity) { 2561 final int N = mLruProcesses.size(); 2562 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2563 // Process doesn't have activities, but has clients with 2564 // activities... move it up, but one below the top (the top 2565 // should always have a real activity). 2566 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2567 mLruProcesses.add(N-1, app); 2568 // To keep it from spamming the LRU list (by making a bunch of clients), 2569 // we will push down any other entries owned by the app. 2570 final int uid = app.info.uid; 2571 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2572 ProcessRecord subProc = mLruProcesses.get(i); 2573 if (subProc.info.uid == uid) { 2574 // We want to push this one down the list. If the process after 2575 // it is for the same uid, however, don't do so, because we don't 2576 // want them internally to be re-ordered. 2577 if (mLruProcesses.get(i-1).info.uid != uid) { 2578 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2579 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2580 ProcessRecord tmp = mLruProcesses.get(i); 2581 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2582 mLruProcesses.set(i-1, tmp); 2583 i--; 2584 } 2585 } else { 2586 // A gap, we can stop here. 2587 break; 2588 } 2589 } 2590 } else { 2591 // Process has activities, put it at the very tipsy-top. 2592 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2593 mLruProcesses.add(app); 2594 } 2595 nextIndex = mLruProcessServiceStart; 2596 } else if (hasService) { 2597 // Process has services, put it at the top of the service list. 2598 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2599 mLruProcesses.add(mLruProcessActivityStart, app); 2600 nextIndex = mLruProcessServiceStart; 2601 mLruProcessActivityStart++; 2602 } else { 2603 // Process not otherwise of interest, it goes to the top of the non-service area. 2604 int index = mLruProcessServiceStart; 2605 if (client != null) { 2606 // If there is a client, don't allow the process to be moved up higher 2607 // in the list than that client. 2608 int clientIndex = mLruProcesses.lastIndexOf(client); 2609 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2610 + " when updating " + app); 2611 if (clientIndex <= lrui) { 2612 // Don't allow the client index restriction to push it down farther in the 2613 // list than it already is. 2614 clientIndex = lrui; 2615 } 2616 if (clientIndex >= 0 && index > clientIndex) { 2617 index = clientIndex; 2618 } 2619 } 2620 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2621 mLruProcesses.add(index, app); 2622 nextIndex = index-1; 2623 mLruProcessActivityStart++; 2624 mLruProcessServiceStart++; 2625 } 2626 2627 // If the app is currently using a content provider or service, 2628 // bump those processes as well. 2629 for (int j=app.connections.size()-1; j>=0; j--) { 2630 ConnectionRecord cr = app.connections.valueAt(j); 2631 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2632 && cr.binding.service.app != null 2633 && cr.binding.service.app.lruSeq != mLruSeq 2634 && !cr.binding.service.app.persistent) { 2635 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2636 "service connection", cr, app); 2637 } 2638 } 2639 for (int j=app.conProviders.size()-1; j>=0; j--) { 2640 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2641 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2642 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2643 "provider reference", cpr, app); 2644 } 2645 } 2646 } 2647 2648 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2649 if (uid == Process.SYSTEM_UID) { 2650 // The system gets to run in any process. If there are multiple 2651 // processes with the same uid, just pick the first (this 2652 // should never happen). 2653 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2654 if (procs == null) return null; 2655 final int N = procs.size(); 2656 for (int i = 0; i < N; i++) { 2657 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2658 } 2659 } 2660 ProcessRecord proc = mProcessNames.get(processName, uid); 2661 if (false && proc != null && !keepIfLarge 2662 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2663 && proc.lastCachedPss >= 4000) { 2664 // Turn this condition on to cause killing to happen regularly, for testing. 2665 if (proc.baseProcessTracker != null) { 2666 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2667 } 2668 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2669 } else if (proc != null && !keepIfLarge 2670 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2671 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2672 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2673 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2674 if (proc.baseProcessTracker != null) { 2675 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2676 } 2677 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2678 } 2679 } 2680 return proc; 2681 } 2682 2683 void ensurePackageDexOpt(String packageName) { 2684 IPackageManager pm = AppGlobals.getPackageManager(); 2685 try { 2686 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2687 mDidDexOpt = true; 2688 } 2689 } catch (RemoteException e) { 2690 } 2691 } 2692 2693 boolean isNextTransitionForward() { 2694 int transit = mWindowManager.getPendingAppTransition(); 2695 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2696 || transit == AppTransition.TRANSIT_TASK_OPEN 2697 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2698 } 2699 2700 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2701 String processName, String abiOverride, int uid, Runnable crashHandler) { 2702 synchronized(this) { 2703 ApplicationInfo info = new ApplicationInfo(); 2704 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2705 // For isolated processes, the former contains the parent's uid and the latter the 2706 // actual uid of the isolated process. 2707 // In the special case introduced by this method (which is, starting an isolated 2708 // process directly from the SystemServer without an actual parent app process) the 2709 // closest thing to a parent's uid is SYSTEM_UID. 2710 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2711 // the |isolated| logic in the ProcessRecord constructor. 2712 info.uid = Process.SYSTEM_UID; 2713 info.processName = processName; 2714 info.className = entryPoint; 2715 info.packageName = "android"; 2716 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2717 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2718 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2719 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2720 crashHandler); 2721 return proc != null ? proc.pid : 0; 2722 } 2723 } 2724 2725 final ProcessRecord startProcessLocked(String processName, 2726 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2727 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2728 boolean isolated, boolean keepIfLarge) { 2729 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2730 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2731 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2732 null /* crashHandler */); 2733 } 2734 2735 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2736 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2737 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2738 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2739 long startTime = SystemClock.elapsedRealtime(); 2740 ProcessRecord app; 2741 if (!isolated) { 2742 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2743 checkTime(startTime, "startProcess: after getProcessRecord"); 2744 } else { 2745 // If this is an isolated process, it can't re-use an existing process. 2746 app = null; 2747 } 2748 // We don't have to do anything more if: 2749 // (1) There is an existing application record; and 2750 // (2) The caller doesn't think it is dead, OR there is no thread 2751 // object attached to it so we know it couldn't have crashed; and 2752 // (3) There is a pid assigned to it, so it is either starting or 2753 // already running. 2754 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2755 + " app=" + app + " knownToBeDead=" + knownToBeDead 2756 + " thread=" + (app != null ? app.thread : null) 2757 + " pid=" + (app != null ? app.pid : -1)); 2758 if (app != null && app.pid > 0) { 2759 if (!knownToBeDead || app.thread == null) { 2760 // We already have the app running, or are waiting for it to 2761 // come up (we have a pid but not yet its thread), so keep it. 2762 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2763 // If this is a new package in the process, add the package to the list 2764 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2765 checkTime(startTime, "startProcess: done, added package to proc"); 2766 return app; 2767 } 2768 2769 // An application record is attached to a previous process, 2770 // clean it up now. 2771 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2772 checkTime(startTime, "startProcess: bad proc running, killing"); 2773 Process.killProcessGroup(app.info.uid, app.pid); 2774 handleAppDiedLocked(app, true, true); 2775 checkTime(startTime, "startProcess: done killing old proc"); 2776 } 2777 2778 String hostingNameStr = hostingName != null 2779 ? hostingName.flattenToShortString() : null; 2780 2781 if (!isolated) { 2782 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2783 // If we are in the background, then check to see if this process 2784 // is bad. If so, we will just silently fail. 2785 if (mBadProcesses.get(info.processName, info.uid) != null) { 2786 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2787 + "/" + info.processName); 2788 return null; 2789 } 2790 } else { 2791 // When the user is explicitly starting a process, then clear its 2792 // crash count so that we won't make it bad until they see at 2793 // least one crash dialog again, and make the process good again 2794 // if it had been bad. 2795 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2796 + "/" + info.processName); 2797 mProcessCrashTimes.remove(info.processName, info.uid); 2798 if (mBadProcesses.get(info.processName, info.uid) != null) { 2799 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2800 UserHandle.getUserId(info.uid), info.uid, 2801 info.processName); 2802 mBadProcesses.remove(info.processName, info.uid); 2803 if (app != null) { 2804 app.bad = false; 2805 } 2806 } 2807 } 2808 } 2809 2810 if (app == null) { 2811 checkTime(startTime, "startProcess: creating new process record"); 2812 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2813 if (app == null) { 2814 Slog.w(TAG, "Failed making new process record for " 2815 + processName + "/" + info.uid + " isolated=" + isolated); 2816 return null; 2817 } 2818 app.crashHandler = crashHandler; 2819 mProcessNames.put(processName, app.uid, app); 2820 if (isolated) { 2821 mIsolatedProcesses.put(app.uid, app); 2822 } 2823 checkTime(startTime, "startProcess: done creating new process record"); 2824 } else { 2825 // If this is a new package in the process, add the package to the list 2826 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2827 checkTime(startTime, "startProcess: added package to existing proc"); 2828 } 2829 2830 // If the system is not ready yet, then hold off on starting this 2831 // process until it is. 2832 if (!mProcessesReady 2833 && !isAllowedWhileBooting(info) 2834 && !allowWhileBooting) { 2835 if (!mProcessesOnHold.contains(app)) { 2836 mProcessesOnHold.add(app); 2837 } 2838 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2839 checkTime(startTime, "startProcess: returning with proc on hold"); 2840 return app; 2841 } 2842 2843 checkTime(startTime, "startProcess: stepping in to startProcess"); 2844 startProcessLocked( 2845 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2846 checkTime(startTime, "startProcess: done starting proc!"); 2847 return (app.pid != 0) ? app : null; 2848 } 2849 2850 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2851 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2852 } 2853 2854 private final void startProcessLocked(ProcessRecord app, 2855 String hostingType, String hostingNameStr) { 2856 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2857 null /* entryPoint */, null /* entryPointArgs */); 2858 } 2859 2860 private final void startProcessLocked(ProcessRecord app, String hostingType, 2861 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2862 long startTime = SystemClock.elapsedRealtime(); 2863 if (app.pid > 0 && app.pid != MY_PID) { 2864 checkTime(startTime, "startProcess: removing from pids map"); 2865 synchronized (mPidsSelfLocked) { 2866 mPidsSelfLocked.remove(app.pid); 2867 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2868 } 2869 checkTime(startTime, "startProcess: done removing from pids map"); 2870 app.setPid(0); 2871 } 2872 2873 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2874 "startProcessLocked removing on hold: " + app); 2875 mProcessesOnHold.remove(app); 2876 2877 checkTime(startTime, "startProcess: starting to update cpu stats"); 2878 updateCpuStats(); 2879 checkTime(startTime, "startProcess: done updating cpu stats"); 2880 2881 try { 2882 int uid = app.uid; 2883 2884 int[] gids = null; 2885 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2886 if (!app.isolated) { 2887 int[] permGids = null; 2888 try { 2889 checkTime(startTime, "startProcess: getting gids from package manager"); 2890 final PackageManager pm = mContext.getPackageManager(); 2891 permGids = pm.getPackageGids(app.info.packageName); 2892 2893 if (Environment.isExternalStorageEmulated()) { 2894 checkTime(startTime, "startProcess: checking external storage perm"); 2895 if (pm.checkPermission( 2896 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2897 app.info.packageName) == PERMISSION_GRANTED) { 2898 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2899 } else { 2900 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2901 } 2902 } 2903 } catch (PackageManager.NameNotFoundException e) { 2904 Slog.w(TAG, "Unable to retrieve gids", e); 2905 } 2906 2907 /* 2908 * Add shared application and profile GIDs so applications can share some 2909 * resources like shared libraries and access user-wide resources 2910 */ 2911 if (permGids == null) { 2912 gids = new int[2]; 2913 } else { 2914 gids = new int[permGids.length + 2]; 2915 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2916 } 2917 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2918 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2919 } 2920 checkTime(startTime, "startProcess: building args"); 2921 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2922 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2923 && mTopComponent != null 2924 && app.processName.equals(mTopComponent.getPackageName())) { 2925 uid = 0; 2926 } 2927 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2928 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2929 uid = 0; 2930 } 2931 } 2932 int debugFlags = 0; 2933 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2934 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2935 // Also turn on CheckJNI for debuggable apps. It's quite 2936 // awkward to turn on otherwise. 2937 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2938 } 2939 // Run the app in safe mode if its manifest requests so or the 2940 // system is booted in safe mode. 2941 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2942 mSafeMode == true) { 2943 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2944 } 2945 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2946 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2947 } 2948 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2949 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2950 } 2951 if ("1".equals(SystemProperties.get("debug.assert"))) { 2952 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2953 } 2954 2955 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2956 if (requiredAbi == null) { 2957 requiredAbi = Build.SUPPORTED_ABIS[0]; 2958 } 2959 2960 String instructionSet = null; 2961 if (app.info.primaryCpuAbi != null) { 2962 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2963 } 2964 2965 // Start the process. It will either succeed and return a result containing 2966 // the PID of the new process, or else throw a RuntimeException. 2967 boolean isActivityProcess = (entryPoint == null); 2968 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2969 checkTime(startTime, "startProcess: asking zygote to start proc"); 2970 Process.ProcessStartResult startResult = Process.start(entryPoint, 2971 app.processName, uid, uid, gids, debugFlags, mountExternal, 2972 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2973 app.info.dataDir, entryPointArgs); 2974 checkTime(startTime, "startProcess: returned from zygote!"); 2975 2976 if (app.isolated) { 2977 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2978 } 2979 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2980 checkTime(startTime, "startProcess: done updating battery stats"); 2981 2982 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2983 UserHandle.getUserId(uid), startResult.pid, uid, 2984 app.processName, hostingType, 2985 hostingNameStr != null ? hostingNameStr : ""); 2986 2987 if (app.persistent) { 2988 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2989 } 2990 2991 checkTime(startTime, "startProcess: building log message"); 2992 StringBuilder buf = mStringBuilder; 2993 buf.setLength(0); 2994 buf.append("Start proc "); 2995 buf.append(app.processName); 2996 if (!isActivityProcess) { 2997 buf.append(" ["); 2998 buf.append(entryPoint); 2999 buf.append("]"); 3000 } 3001 buf.append(" for "); 3002 buf.append(hostingType); 3003 if (hostingNameStr != null) { 3004 buf.append(" "); 3005 buf.append(hostingNameStr); 3006 } 3007 buf.append(": pid="); 3008 buf.append(startResult.pid); 3009 buf.append(" uid="); 3010 buf.append(uid); 3011 buf.append(" gids={"); 3012 if (gids != null) { 3013 for (int gi=0; gi<gids.length; gi++) { 3014 if (gi != 0) buf.append(", "); 3015 buf.append(gids[gi]); 3016 3017 } 3018 } 3019 buf.append("}"); 3020 if (requiredAbi != null) { 3021 buf.append(" abi="); 3022 buf.append(requiredAbi); 3023 } 3024 Slog.i(TAG, buf.toString()); 3025 app.setPid(startResult.pid); 3026 app.usingWrapper = startResult.usingWrapper; 3027 app.removed = false; 3028 app.killed = false; 3029 app.killedByAm = false; 3030 checkTime(startTime, "startProcess: starting to update pids map"); 3031 synchronized (mPidsSelfLocked) { 3032 this.mPidsSelfLocked.put(startResult.pid, app); 3033 if (isActivityProcess) { 3034 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3035 msg.obj = app; 3036 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3037 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3038 } 3039 } 3040 checkTime(startTime, "startProcess: done updating pids map"); 3041 } catch (RuntimeException e) { 3042 // XXX do better error recovery. 3043 app.setPid(0); 3044 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3045 if (app.isolated) { 3046 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3047 } 3048 Slog.e(TAG, "Failure starting process " + app.processName, e); 3049 } 3050 } 3051 3052 void updateUsageStats(ActivityRecord component, boolean resumed) { 3053 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3054 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3055 if (resumed) { 3056 if (mUsageStatsService != null) { 3057 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3058 UsageEvents.Event.MOVE_TO_FOREGROUND); 3059 } 3060 synchronized (stats) { 3061 stats.noteActivityResumedLocked(component.app.uid); 3062 } 3063 } else { 3064 if (mUsageStatsService != null) { 3065 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3066 UsageEvents.Event.MOVE_TO_BACKGROUND); 3067 } 3068 synchronized (stats) { 3069 stats.noteActivityPausedLocked(component.app.uid); 3070 } 3071 } 3072 } 3073 3074 Intent getHomeIntent() { 3075 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3076 intent.setComponent(mTopComponent); 3077 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3078 intent.addCategory(Intent.CATEGORY_HOME); 3079 } 3080 return intent; 3081 } 3082 3083 boolean startHomeActivityLocked(int userId) { 3084 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3085 && mTopAction == null) { 3086 // We are running in factory test mode, but unable to find 3087 // the factory test app, so just sit around displaying the 3088 // error message and don't try to start anything. 3089 return false; 3090 } 3091 Intent intent = getHomeIntent(); 3092 ActivityInfo aInfo = 3093 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3094 if (aInfo != null) { 3095 intent.setComponent(new ComponentName( 3096 aInfo.applicationInfo.packageName, aInfo.name)); 3097 // Don't do this if the home app is currently being 3098 // instrumented. 3099 aInfo = new ActivityInfo(aInfo); 3100 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3101 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3102 aInfo.applicationInfo.uid, true); 3103 if (app == null || app.instrumentationClass == null) { 3104 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3105 mStackSupervisor.startHomeActivity(intent, aInfo); 3106 } 3107 } 3108 3109 return true; 3110 } 3111 3112 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3113 ActivityInfo ai = null; 3114 ComponentName comp = intent.getComponent(); 3115 try { 3116 if (comp != null) { 3117 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3118 } else { 3119 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3120 intent, 3121 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3122 flags, userId); 3123 3124 if (info != null) { 3125 ai = info.activityInfo; 3126 } 3127 } 3128 } catch (RemoteException e) { 3129 // ignore 3130 } 3131 3132 return ai; 3133 } 3134 3135 /** 3136 * Starts the "new version setup screen" if appropriate. 3137 */ 3138 void startSetupActivityLocked() { 3139 // Only do this once per boot. 3140 if (mCheckedForSetup) { 3141 return; 3142 } 3143 3144 // We will show this screen if the current one is a different 3145 // version than the last one shown, and we are not running in 3146 // low-level factory test mode. 3147 final ContentResolver resolver = mContext.getContentResolver(); 3148 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3149 Settings.Global.getInt(resolver, 3150 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3151 mCheckedForSetup = true; 3152 3153 // See if we should be showing the platform update setup UI. 3154 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3155 List<ResolveInfo> ris = mContext.getPackageManager() 3156 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3157 3158 // We don't allow third party apps to replace this. 3159 ResolveInfo ri = null; 3160 for (int i=0; ris != null && i<ris.size(); i++) { 3161 if ((ris.get(i).activityInfo.applicationInfo.flags 3162 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3163 ri = ris.get(i); 3164 break; 3165 } 3166 } 3167 3168 if (ri != null) { 3169 String vers = ri.activityInfo.metaData != null 3170 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3171 : null; 3172 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3173 vers = ri.activityInfo.applicationInfo.metaData.getString( 3174 Intent.METADATA_SETUP_VERSION); 3175 } 3176 String lastVers = Settings.Secure.getString( 3177 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3178 if (vers != null && !vers.equals(lastVers)) { 3179 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3180 intent.setComponent(new ComponentName( 3181 ri.activityInfo.packageName, ri.activityInfo.name)); 3182 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3183 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3184 null); 3185 } 3186 } 3187 } 3188 } 3189 3190 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3191 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3192 } 3193 3194 void enforceNotIsolatedCaller(String caller) { 3195 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3196 throw new SecurityException("Isolated process not allowed to call " + caller); 3197 } 3198 } 3199 3200 void enforceShellRestriction(String restriction, int userHandle) { 3201 if (Binder.getCallingUid() == Process.SHELL_UID) { 3202 if (userHandle < 0 3203 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3204 throw new SecurityException("Shell does not have permission to access user " 3205 + userHandle); 3206 } 3207 } 3208 } 3209 3210 @Override 3211 public int getFrontActivityScreenCompatMode() { 3212 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3213 synchronized (this) { 3214 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3215 } 3216 } 3217 3218 @Override 3219 public void setFrontActivityScreenCompatMode(int mode) { 3220 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3221 "setFrontActivityScreenCompatMode"); 3222 synchronized (this) { 3223 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3224 } 3225 } 3226 3227 @Override 3228 public int getPackageScreenCompatMode(String packageName) { 3229 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3230 synchronized (this) { 3231 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3232 } 3233 } 3234 3235 @Override 3236 public void setPackageScreenCompatMode(String packageName, int mode) { 3237 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3238 "setPackageScreenCompatMode"); 3239 synchronized (this) { 3240 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3241 } 3242 } 3243 3244 @Override 3245 public boolean getPackageAskScreenCompat(String packageName) { 3246 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3247 synchronized (this) { 3248 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3249 } 3250 } 3251 3252 @Override 3253 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3254 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3255 "setPackageAskScreenCompat"); 3256 synchronized (this) { 3257 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3258 } 3259 } 3260 3261 private void dispatchProcessesChanged() { 3262 int N; 3263 synchronized (this) { 3264 N = mPendingProcessChanges.size(); 3265 if (mActiveProcessChanges.length < N) { 3266 mActiveProcessChanges = new ProcessChangeItem[N]; 3267 } 3268 mPendingProcessChanges.toArray(mActiveProcessChanges); 3269 mAvailProcessChanges.addAll(mPendingProcessChanges); 3270 mPendingProcessChanges.clear(); 3271 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3272 } 3273 3274 int i = mProcessObservers.beginBroadcast(); 3275 while (i > 0) { 3276 i--; 3277 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3278 if (observer != null) { 3279 try { 3280 for (int j=0; j<N; j++) { 3281 ProcessChangeItem item = mActiveProcessChanges[j]; 3282 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3283 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3284 + item.pid + " uid=" + item.uid + ": " 3285 + item.foregroundActivities); 3286 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3287 item.foregroundActivities); 3288 } 3289 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3290 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3291 + item.pid + " uid=" + item.uid + ": " + item.processState); 3292 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3293 } 3294 } 3295 } catch (RemoteException e) { 3296 } 3297 } 3298 } 3299 mProcessObservers.finishBroadcast(); 3300 } 3301 3302 private void dispatchProcessDied(int pid, int uid) { 3303 int i = mProcessObservers.beginBroadcast(); 3304 while (i > 0) { 3305 i--; 3306 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3307 if (observer != null) { 3308 try { 3309 observer.onProcessDied(pid, uid); 3310 } catch (RemoteException e) { 3311 } 3312 } 3313 } 3314 mProcessObservers.finishBroadcast(); 3315 } 3316 3317 @Override 3318 public final int startActivity(IApplicationThread caller, String callingPackage, 3319 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3320 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3321 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3322 resultWho, requestCode, startFlags, profilerInfo, options, 3323 UserHandle.getCallingUserId()); 3324 } 3325 3326 @Override 3327 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3328 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3329 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3330 enforceNotIsolatedCaller("startActivity"); 3331 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3332 false, ALLOW_FULL_ONLY, "startActivity", null); 3333 // TODO: Switch to user app stacks here. 3334 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3335 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3336 profilerInfo, null, null, options, userId, null, null); 3337 } 3338 3339 @Override 3340 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3341 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3342 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3343 3344 // This is very dangerous -- it allows you to perform a start activity (including 3345 // permission grants) as any app that may launch one of your own activities. So 3346 // we will only allow this to be done from activities that are part of the core framework, 3347 // and then only when they are running as the system. 3348 final ActivityRecord sourceRecord; 3349 final int targetUid; 3350 final String targetPackage; 3351 synchronized (this) { 3352 if (resultTo == null) { 3353 throw new SecurityException("Must be called from an activity"); 3354 } 3355 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3356 if (sourceRecord == null) { 3357 throw new SecurityException("Called with bad activity token: " + resultTo); 3358 } 3359 if (!sourceRecord.info.packageName.equals("android")) { 3360 throw new SecurityException( 3361 "Must be called from an activity that is declared in the android package"); 3362 } 3363 if (sourceRecord.app == null) { 3364 throw new SecurityException("Called without a process attached to activity"); 3365 } 3366 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3367 // This is still okay, as long as this activity is running under the 3368 // uid of the original calling activity. 3369 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3370 throw new SecurityException( 3371 "Calling activity in uid " + sourceRecord.app.uid 3372 + " must be system uid or original calling uid " 3373 + sourceRecord.launchedFromUid); 3374 } 3375 } 3376 targetUid = sourceRecord.launchedFromUid; 3377 targetPackage = sourceRecord.launchedFromPackage; 3378 } 3379 3380 if (userId == UserHandle.USER_NULL) { 3381 userId = UserHandle.getUserId(sourceRecord.app.uid); 3382 } 3383 3384 // TODO: Switch to user app stacks here. 3385 try { 3386 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3387 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3388 null, null, options, userId, null, null); 3389 return ret; 3390 } catch (SecurityException e) { 3391 // XXX need to figure out how to propagate to original app. 3392 // A SecurityException here is generally actually a fault of the original 3393 // calling activity (such as a fairly granting permissions), so propagate it 3394 // back to them. 3395 /* 3396 StringBuilder msg = new StringBuilder(); 3397 msg.append("While launching"); 3398 msg.append(intent.toString()); 3399 msg.append(": "); 3400 msg.append(e.getMessage()); 3401 */ 3402 throw e; 3403 } 3404 } 3405 3406 @Override 3407 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3408 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3409 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3410 enforceNotIsolatedCaller("startActivityAndWait"); 3411 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3412 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3413 WaitResult res = new WaitResult(); 3414 // TODO: Switch to user app stacks here. 3415 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3416 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3417 options, userId, null, null); 3418 return res; 3419 } 3420 3421 @Override 3422 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3423 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3424 int startFlags, Configuration config, Bundle options, int userId) { 3425 enforceNotIsolatedCaller("startActivityWithConfig"); 3426 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3427 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3428 // TODO: Switch to user app stacks here. 3429 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3430 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3431 null, null, config, options, userId, null, null); 3432 return ret; 3433 } 3434 3435 @Override 3436 public int startActivityIntentSender(IApplicationThread caller, 3437 IntentSender intent, Intent fillInIntent, String resolvedType, 3438 IBinder resultTo, String resultWho, int requestCode, 3439 int flagsMask, int flagsValues, Bundle options) { 3440 enforceNotIsolatedCaller("startActivityIntentSender"); 3441 // Refuse possible leaked file descriptors 3442 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3443 throw new IllegalArgumentException("File descriptors passed in Intent"); 3444 } 3445 3446 IIntentSender sender = intent.getTarget(); 3447 if (!(sender instanceof PendingIntentRecord)) { 3448 throw new IllegalArgumentException("Bad PendingIntent object"); 3449 } 3450 3451 PendingIntentRecord pir = (PendingIntentRecord)sender; 3452 3453 synchronized (this) { 3454 // If this is coming from the currently resumed activity, it is 3455 // effectively saying that app switches are allowed at this point. 3456 final ActivityStack stack = getFocusedStack(); 3457 if (stack.mResumedActivity != null && 3458 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3459 mAppSwitchesAllowedTime = 0; 3460 } 3461 } 3462 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3463 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3464 return ret; 3465 } 3466 3467 @Override 3468 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3469 Intent intent, String resolvedType, IVoiceInteractionSession session, 3470 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3471 Bundle options, int userId) { 3472 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3473 != PackageManager.PERMISSION_GRANTED) { 3474 String msg = "Permission Denial: startVoiceActivity() from pid=" 3475 + Binder.getCallingPid() 3476 + ", uid=" + Binder.getCallingUid() 3477 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3478 Slog.w(TAG, msg); 3479 throw new SecurityException(msg); 3480 } 3481 if (session == null || interactor == null) { 3482 throw new NullPointerException("null session or interactor"); 3483 } 3484 userId = handleIncomingUser(callingPid, callingUid, userId, 3485 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3486 // TODO: Switch to user app stacks here. 3487 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3488 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3489 null, options, userId, null, null); 3490 } 3491 3492 @Override 3493 public boolean startNextMatchingActivity(IBinder callingActivity, 3494 Intent intent, Bundle options) { 3495 // Refuse possible leaked file descriptors 3496 if (intent != null && intent.hasFileDescriptors() == true) { 3497 throw new IllegalArgumentException("File descriptors passed in Intent"); 3498 } 3499 3500 synchronized (this) { 3501 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3502 if (r == null) { 3503 ActivityOptions.abort(options); 3504 return false; 3505 } 3506 if (r.app == null || r.app.thread == null) { 3507 // The caller is not running... d'oh! 3508 ActivityOptions.abort(options); 3509 return false; 3510 } 3511 intent = new Intent(intent); 3512 // The caller is not allowed to change the data. 3513 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3514 // And we are resetting to find the next component... 3515 intent.setComponent(null); 3516 3517 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3518 3519 ActivityInfo aInfo = null; 3520 try { 3521 List<ResolveInfo> resolves = 3522 AppGlobals.getPackageManager().queryIntentActivities( 3523 intent, r.resolvedType, 3524 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3525 UserHandle.getCallingUserId()); 3526 3527 // Look for the original activity in the list... 3528 final int N = resolves != null ? resolves.size() : 0; 3529 for (int i=0; i<N; i++) { 3530 ResolveInfo rInfo = resolves.get(i); 3531 if (rInfo.activityInfo.packageName.equals(r.packageName) 3532 && rInfo.activityInfo.name.equals(r.info.name)) { 3533 // We found the current one... the next matching is 3534 // after it. 3535 i++; 3536 if (i<N) { 3537 aInfo = resolves.get(i).activityInfo; 3538 } 3539 if (debug) { 3540 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3541 + "/" + r.info.name); 3542 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3543 + "/" + aInfo.name); 3544 } 3545 break; 3546 } 3547 } 3548 } catch (RemoteException e) { 3549 } 3550 3551 if (aInfo == null) { 3552 // Nobody who is next! 3553 ActivityOptions.abort(options); 3554 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3555 return false; 3556 } 3557 3558 intent.setComponent(new ComponentName( 3559 aInfo.applicationInfo.packageName, aInfo.name)); 3560 intent.setFlags(intent.getFlags()&~( 3561 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3562 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3563 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3564 Intent.FLAG_ACTIVITY_NEW_TASK)); 3565 3566 // Okay now we need to start the new activity, replacing the 3567 // currently running activity. This is a little tricky because 3568 // we want to start the new one as if the current one is finished, 3569 // but not finish the current one first so that there is no flicker. 3570 // And thus... 3571 final boolean wasFinishing = r.finishing; 3572 r.finishing = true; 3573 3574 // Propagate reply information over to the new activity. 3575 final ActivityRecord resultTo = r.resultTo; 3576 final String resultWho = r.resultWho; 3577 final int requestCode = r.requestCode; 3578 r.resultTo = null; 3579 if (resultTo != null) { 3580 resultTo.removeResultsLocked(r, resultWho, requestCode); 3581 } 3582 3583 final long origId = Binder.clearCallingIdentity(); 3584 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3585 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3586 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3587 -1, r.launchedFromUid, 0, options, false, null, null, null); 3588 Binder.restoreCallingIdentity(origId); 3589 3590 r.finishing = wasFinishing; 3591 if (res != ActivityManager.START_SUCCESS) { 3592 return false; 3593 } 3594 return true; 3595 } 3596 } 3597 3598 @Override 3599 public final int startActivityFromRecents(int taskId, Bundle options) { 3600 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3601 String msg = "Permission Denial: startActivityFromRecents called without " + 3602 START_TASKS_FROM_RECENTS; 3603 Slog.w(TAG, msg); 3604 throw new SecurityException(msg); 3605 } 3606 return startActivityFromRecentsInner(taskId, options); 3607 } 3608 3609 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3610 final TaskRecord task; 3611 final int callingUid; 3612 final String callingPackage; 3613 final Intent intent; 3614 final int userId; 3615 synchronized (this) { 3616 task = recentTaskForIdLocked(taskId); 3617 if (task == null) { 3618 throw new IllegalArgumentException("Task " + taskId + " not found."); 3619 } 3620 callingUid = task.mCallingUid; 3621 callingPackage = task.mCallingPackage; 3622 intent = task.intent; 3623 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3624 userId = task.userId; 3625 } 3626 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3627 options, userId, null, task); 3628 } 3629 3630 final int startActivityInPackage(int uid, String callingPackage, 3631 Intent intent, String resolvedType, IBinder resultTo, 3632 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3633 IActivityContainer container, TaskRecord inTask) { 3634 3635 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3636 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3637 3638 // TODO: Switch to user app stacks here. 3639 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3640 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3641 null, null, null, options, userId, container, inTask); 3642 return ret; 3643 } 3644 3645 @Override 3646 public final int startActivities(IApplicationThread caller, String callingPackage, 3647 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3648 int userId) { 3649 enforceNotIsolatedCaller("startActivities"); 3650 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3651 false, ALLOW_FULL_ONLY, "startActivity", null); 3652 // TODO: Switch to user app stacks here. 3653 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3654 resolvedTypes, resultTo, options, userId); 3655 return ret; 3656 } 3657 3658 final int startActivitiesInPackage(int uid, String callingPackage, 3659 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3660 Bundle options, int userId) { 3661 3662 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3663 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3664 // TODO: Switch to user app stacks here. 3665 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3666 resultTo, options, userId); 3667 return ret; 3668 } 3669 3670 //explicitly remove thd old information in mRecentTasks when removing existing user. 3671 private void removeRecentTasksForUserLocked(int userId) { 3672 if(userId <= 0) { 3673 Slog.i(TAG, "Can't remove recent task on user " + userId); 3674 return; 3675 } 3676 3677 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3678 TaskRecord tr = mRecentTasks.get(i); 3679 if (tr.userId == userId) { 3680 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3681 + " when finishing user" + userId); 3682 mRecentTasks.remove(i); 3683 tr.removedFromRecents(); 3684 } 3685 } 3686 3687 // Remove tasks from persistent storage. 3688 notifyTaskPersisterLocked(null, true); 3689 } 3690 3691 // Sort by taskId 3692 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3693 @Override 3694 public int compare(TaskRecord lhs, TaskRecord rhs) { 3695 return rhs.taskId - lhs.taskId; 3696 } 3697 }; 3698 3699 // Extract the affiliates of the chain containing mRecentTasks[start]. 3700 private int processNextAffiliateChainLocked(int start) { 3701 final TaskRecord startTask = mRecentTasks.get(start); 3702 final int affiliateId = startTask.mAffiliatedTaskId; 3703 3704 // Quick identification of isolated tasks. I.e. those not launched behind. 3705 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3706 startTask.mNextAffiliate == null) { 3707 // There is still a slim chance that there are other tasks that point to this task 3708 // and that the chain is so messed up that this task no longer points to them but 3709 // the gain of this optimization outweighs the risk. 3710 startTask.inRecents = true; 3711 return start + 1; 3712 } 3713 3714 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3715 mTmpRecents.clear(); 3716 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3717 final TaskRecord task = mRecentTasks.get(i); 3718 if (task.mAffiliatedTaskId == affiliateId) { 3719 mRecentTasks.remove(i); 3720 mTmpRecents.add(task); 3721 } 3722 } 3723 3724 // Sort them all by taskId. That is the order they were create in and that order will 3725 // always be correct. 3726 Collections.sort(mTmpRecents, mTaskRecordComparator); 3727 3728 // Go through and fix up the linked list. 3729 // The first one is the end of the chain and has no next. 3730 final TaskRecord first = mTmpRecents.get(0); 3731 first.inRecents = true; 3732 if (first.mNextAffiliate != null) { 3733 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3734 first.setNextAffiliate(null); 3735 notifyTaskPersisterLocked(first, false); 3736 } 3737 // Everything in the middle is doubly linked from next to prev. 3738 final int tmpSize = mTmpRecents.size(); 3739 for (int i = 0; i < tmpSize - 1; ++i) { 3740 final TaskRecord next = mTmpRecents.get(i); 3741 final TaskRecord prev = mTmpRecents.get(i + 1); 3742 if (next.mPrevAffiliate != prev) { 3743 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3744 " setting prev=" + prev); 3745 next.setPrevAffiliate(prev); 3746 notifyTaskPersisterLocked(next, false); 3747 } 3748 if (prev.mNextAffiliate != next) { 3749 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3750 " setting next=" + next); 3751 prev.setNextAffiliate(next); 3752 notifyTaskPersisterLocked(prev, false); 3753 } 3754 prev.inRecents = true; 3755 } 3756 // The last one is the beginning of the list and has no prev. 3757 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3758 if (last.mPrevAffiliate != null) { 3759 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3760 last.setPrevAffiliate(null); 3761 notifyTaskPersisterLocked(last, false); 3762 } 3763 3764 // Insert the group back into mRecentTasks at start. 3765 mRecentTasks.addAll(start, mTmpRecents); 3766 3767 // Let the caller know where we left off. 3768 return start + tmpSize; 3769 } 3770 3771 /** 3772 * Update the recent tasks lists: make sure tasks should still be here (their 3773 * applications / activities still exist), update their availability, fixup ordering 3774 * of affiliations. 3775 */ 3776 void cleanupRecentTasksLocked(int userId) { 3777 if (mRecentTasks == null) { 3778 // Happens when called from the packagemanager broadcast before boot. 3779 return; 3780 } 3781 3782 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3783 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3784 final IPackageManager pm = AppGlobals.getPackageManager(); 3785 final ActivityInfo dummyAct = new ActivityInfo(); 3786 final ApplicationInfo dummyApp = new ApplicationInfo(); 3787 3788 int N = mRecentTasks.size(); 3789 3790 int[] users = userId == UserHandle.USER_ALL 3791 ? getUsersLocked() : new int[] { userId }; 3792 for (int user : users) { 3793 for (int i = 0; i < N; i++) { 3794 TaskRecord task = mRecentTasks.get(i); 3795 if (task.userId != user) { 3796 // Only look at tasks for the user ID of interest. 3797 continue; 3798 } 3799 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3800 // This situation is broken, and we should just get rid of it now. 3801 mRecentTasks.remove(i); 3802 task.removedFromRecents(); 3803 i--; 3804 N--; 3805 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3806 continue; 3807 } 3808 // Check whether this activity is currently available. 3809 if (task.realActivity != null) { 3810 ActivityInfo ai = availActCache.get(task.realActivity); 3811 if (ai == null) { 3812 try { 3813 ai = pm.getActivityInfo(task.realActivity, 3814 PackageManager.GET_UNINSTALLED_PACKAGES 3815 | PackageManager.GET_DISABLED_COMPONENTS, user); 3816 } catch (RemoteException e) { 3817 // Will never happen. 3818 continue; 3819 } 3820 if (ai == null) { 3821 ai = dummyAct; 3822 } 3823 availActCache.put(task.realActivity, ai); 3824 } 3825 if (ai == dummyAct) { 3826 // This could be either because the activity no longer exists, or the 3827 // app is temporarily gone. For the former we want to remove the recents 3828 // entry; for the latter we want to mark it as unavailable. 3829 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3830 if (app == null) { 3831 try { 3832 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3833 PackageManager.GET_UNINSTALLED_PACKAGES 3834 | PackageManager.GET_DISABLED_COMPONENTS, user); 3835 } catch (RemoteException e) { 3836 // Will never happen. 3837 continue; 3838 } 3839 if (app == null) { 3840 app = dummyApp; 3841 } 3842 availAppCache.put(task.realActivity.getPackageName(), app); 3843 } 3844 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3845 // Doesn't exist any more! Good-bye. 3846 mRecentTasks.remove(i); 3847 task.removedFromRecents(); 3848 i--; 3849 N--; 3850 Slog.w(TAG, "Removing no longer valid recent: " + task); 3851 continue; 3852 } else { 3853 // Otherwise just not available for now. 3854 if (task.isAvailable) { 3855 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3856 + task); 3857 } 3858 task.isAvailable = false; 3859 } 3860 } else { 3861 if (!ai.enabled || !ai.applicationInfo.enabled 3862 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3863 if (task.isAvailable) { 3864 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3865 + task + " (enabled=" + ai.enabled + "/" 3866 + ai.applicationInfo.enabled + " flags=" 3867 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3868 } 3869 task.isAvailable = false; 3870 } else { 3871 if (!task.isAvailable) { 3872 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3873 + task); 3874 } 3875 task.isAvailable = true; 3876 } 3877 } 3878 } 3879 } 3880 } 3881 3882 // Verify the affiliate chain for each task. 3883 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3884 } 3885 3886 mTmpRecents.clear(); 3887 // mRecentTasks is now in sorted, affiliated order. 3888 } 3889 3890 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3891 int N = mRecentTasks.size(); 3892 TaskRecord top = task; 3893 int topIndex = taskIndex; 3894 while (top.mNextAffiliate != null && topIndex > 0) { 3895 top = top.mNextAffiliate; 3896 topIndex--; 3897 } 3898 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3899 + topIndex + " from intial " + taskIndex); 3900 // Find the end of the chain, doing a sanity check along the way. 3901 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3902 int endIndex = topIndex; 3903 TaskRecord prev = top; 3904 while (endIndex < N) { 3905 TaskRecord cur = mRecentTasks.get(endIndex); 3906 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3907 + endIndex + " " + cur); 3908 if (cur == top) { 3909 // Verify start of the chain. 3910 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3911 Slog.wtf(TAG, "Bad chain @" + endIndex 3912 + ": first task has next affiliate: " + prev); 3913 sane = false; 3914 break; 3915 } 3916 } else { 3917 // Verify middle of the chain's next points back to the one before. 3918 if (cur.mNextAffiliate != prev 3919 || cur.mNextAffiliateTaskId != prev.taskId) { 3920 Slog.wtf(TAG, "Bad chain @" + endIndex 3921 + ": middle task " + cur + " @" + endIndex 3922 + " has bad next affiliate " 3923 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3924 + ", expected " + prev); 3925 sane = false; 3926 break; 3927 } 3928 } 3929 if (cur.mPrevAffiliateTaskId == -1) { 3930 // Chain ends here. 3931 if (cur.mPrevAffiliate != null) { 3932 Slog.wtf(TAG, "Bad chain @" + endIndex 3933 + ": last task " + cur + " has previous affiliate " 3934 + cur.mPrevAffiliate); 3935 sane = false; 3936 } 3937 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3938 break; 3939 } else { 3940 // Verify middle of the chain's prev points to a valid item. 3941 if (cur.mPrevAffiliate == null) { 3942 Slog.wtf(TAG, "Bad chain @" + endIndex 3943 + ": task " + cur + " has previous affiliate " 3944 + cur.mPrevAffiliate + " but should be id " 3945 + cur.mPrevAffiliate); 3946 sane = false; 3947 break; 3948 } 3949 } 3950 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3951 Slog.wtf(TAG, "Bad chain @" + endIndex 3952 + ": task " + cur + " has affiliated id " 3953 + cur.mAffiliatedTaskId + " but should be " 3954 + task.mAffiliatedTaskId); 3955 sane = false; 3956 break; 3957 } 3958 prev = cur; 3959 endIndex++; 3960 if (endIndex >= N) { 3961 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3962 + ": last task " + prev); 3963 sane = false; 3964 break; 3965 } 3966 } 3967 if (sane) { 3968 if (endIndex < taskIndex) { 3969 Slog.wtf(TAG, "Bad chain @" + endIndex 3970 + ": did not extend to task " + task + " @" + taskIndex); 3971 sane = false; 3972 } 3973 } 3974 if (sane) { 3975 // All looks good, we can just move all of the affiliated tasks 3976 // to the top. 3977 for (int i=topIndex; i<=endIndex; i++) { 3978 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3979 + " from " + i + " to " + (i-topIndex)); 3980 TaskRecord cur = mRecentTasks.remove(i); 3981 mRecentTasks.add(i-topIndex, cur); 3982 } 3983 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3984 + " to " + endIndex); 3985 return true; 3986 } 3987 3988 // Whoops, couldn't do it. 3989 return false; 3990 } 3991 3992 final void addRecentTaskLocked(TaskRecord task) { 3993 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3994 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3995 3996 int N = mRecentTasks.size(); 3997 // Quick case: check if the top-most recent task is the same. 3998 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3999 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4000 return; 4001 } 4002 // Another quick case: check if this is part of a set of affiliated 4003 // tasks that are at the top. 4004 if (isAffiliated && N > 0 && task.inRecents 4005 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4006 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4007 + " at top when adding " + task); 4008 return; 4009 } 4010 // Another quick case: never add voice sessions. 4011 if (task.voiceSession != null) { 4012 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4013 return; 4014 } 4015 4016 boolean needAffiliationFix = false; 4017 4018 // Slightly less quick case: the task is already in recents, so all we need 4019 // to do is move it. 4020 if (task.inRecents) { 4021 int taskIndex = mRecentTasks.indexOf(task); 4022 if (taskIndex >= 0) { 4023 if (!isAffiliated) { 4024 // Simple case: this is not an affiliated task, so we just move it to the front. 4025 mRecentTasks.remove(taskIndex); 4026 mRecentTasks.add(0, task); 4027 notifyTaskPersisterLocked(task, false); 4028 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4029 + " from " + taskIndex); 4030 return; 4031 } else { 4032 // More complicated: need to keep all affiliated tasks together. 4033 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4034 // All went well. 4035 return; 4036 } 4037 4038 // Uh oh... something bad in the affiliation chain, try to rebuild 4039 // everything and then go through our general path of adding a new task. 4040 needAffiliationFix = true; 4041 } 4042 } else { 4043 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4044 needAffiliationFix = true; 4045 } 4046 } 4047 4048 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4049 trimRecentsForTaskLocked(task, true); 4050 4051 N = mRecentTasks.size(); 4052 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4053 final TaskRecord tr = mRecentTasks.remove(N - 1); 4054 tr.removedFromRecents(); 4055 N--; 4056 } 4057 task.inRecents = true; 4058 if (!isAffiliated || needAffiliationFix) { 4059 // If this is a simple non-affiliated task, or we had some failure trying to 4060 // handle it as part of an affilated task, then just place it at the top. 4061 mRecentTasks.add(0, task); 4062 } else if (isAffiliated) { 4063 // If this is a new affiliated task, then move all of the affiliated tasks 4064 // to the front and insert this new one. 4065 TaskRecord other = task.mNextAffiliate; 4066 if (other == null) { 4067 other = task.mPrevAffiliate; 4068 } 4069 if (other != null) { 4070 int otherIndex = mRecentTasks.indexOf(other); 4071 if (otherIndex >= 0) { 4072 // Insert new task at appropriate location. 4073 int taskIndex; 4074 if (other == task.mNextAffiliate) { 4075 // We found the index of our next affiliation, which is who is 4076 // before us in the list, so add after that point. 4077 taskIndex = otherIndex+1; 4078 } else { 4079 // We found the index of our previous affiliation, which is who is 4080 // after us in the list, so add at their position. 4081 taskIndex = otherIndex; 4082 } 4083 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4084 + taskIndex + ": " + task); 4085 mRecentTasks.add(taskIndex, task); 4086 4087 // Now move everything to the front. 4088 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4089 // All went well. 4090 return; 4091 } 4092 4093 // Uh oh... something bad in the affiliation chain, try to rebuild 4094 // everything and then go through our general path of adding a new task. 4095 needAffiliationFix = true; 4096 } else { 4097 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4098 + other); 4099 needAffiliationFix = true; 4100 } 4101 } else { 4102 if (DEBUG_RECENTS) Slog.d(TAG, 4103 "addRecent: adding affiliated task without next/prev:" + task); 4104 needAffiliationFix = true; 4105 } 4106 } 4107 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4108 4109 if (needAffiliationFix) { 4110 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4111 cleanupRecentTasksLocked(task.userId); 4112 } 4113 } 4114 4115 /** 4116 * If needed, remove oldest existing entries in recents that are for the same kind 4117 * of task as the given one. 4118 */ 4119 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4120 int N = mRecentTasks.size(); 4121 final Intent intent = task.intent; 4122 final boolean document = intent != null && intent.isDocument(); 4123 4124 int maxRecents = task.maxRecents - 1; 4125 for (int i=0; i<N; i++) { 4126 final TaskRecord tr = mRecentTasks.get(i); 4127 if (task != tr) { 4128 if (task.userId != tr.userId) { 4129 continue; 4130 } 4131 if (i > MAX_RECENT_BITMAPS) { 4132 tr.freeLastThumbnail(); 4133 } 4134 final Intent trIntent = tr.intent; 4135 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4136 (intent == null || !intent.filterEquals(trIntent))) { 4137 continue; 4138 } 4139 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4140 if (document && trIsDocument) { 4141 // These are the same document activity (not necessarily the same doc). 4142 if (maxRecents > 0) { 4143 --maxRecents; 4144 continue; 4145 } 4146 // Hit the maximum number of documents for this task. Fall through 4147 // and remove this document from recents. 4148 } else if (document || trIsDocument) { 4149 // Only one of these is a document. Not the droid we're looking for. 4150 continue; 4151 } 4152 } 4153 4154 if (!doTrim) { 4155 // If the caller is not actually asking for a trim, just tell them we reached 4156 // a point where the trim would happen. 4157 return i; 4158 } 4159 4160 // Either task and tr are the same or, their affinities match or their intents match 4161 // and neither of them is a document, or they are documents using the same activity 4162 // and their maxRecents has been reached. 4163 tr.disposeThumbnail(); 4164 mRecentTasks.remove(i); 4165 if (task != tr) { 4166 tr.removedFromRecents(); 4167 } 4168 i--; 4169 N--; 4170 if (task.intent == null) { 4171 // If the new recent task we are adding is not fully 4172 // specified, then replace it with the existing recent task. 4173 task = tr; 4174 } 4175 notifyTaskPersisterLocked(tr, false); 4176 } 4177 4178 return -1; 4179 } 4180 4181 @Override 4182 public void reportActivityFullyDrawn(IBinder token) { 4183 synchronized (this) { 4184 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4185 if (r == null) { 4186 return; 4187 } 4188 r.reportFullyDrawnLocked(); 4189 } 4190 } 4191 4192 @Override 4193 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4194 synchronized (this) { 4195 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4196 if (r == null) { 4197 return; 4198 } 4199 final long origId = Binder.clearCallingIdentity(); 4200 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4201 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4202 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4203 if (config != null) { 4204 r.frozenBeforeDestroy = true; 4205 if (!updateConfigurationLocked(config, r, false, false)) { 4206 mStackSupervisor.resumeTopActivitiesLocked(); 4207 } 4208 } 4209 Binder.restoreCallingIdentity(origId); 4210 } 4211 } 4212 4213 @Override 4214 public int getRequestedOrientation(IBinder token) { 4215 synchronized (this) { 4216 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4217 if (r == null) { 4218 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4219 } 4220 return mWindowManager.getAppOrientation(r.appToken); 4221 } 4222 } 4223 4224 /** 4225 * This is the internal entry point for handling Activity.finish(). 4226 * 4227 * @param token The Binder token referencing the Activity we want to finish. 4228 * @param resultCode Result code, if any, from this Activity. 4229 * @param resultData Result data (Intent), if any, from this Activity. 4230 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4231 * the root Activity in the task. 4232 * 4233 * @return Returns true if the activity successfully finished, or false if it is still running. 4234 */ 4235 @Override 4236 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4237 boolean finishTask) { 4238 // Refuse possible leaked file descriptors 4239 if (resultData != null && resultData.hasFileDescriptors() == true) { 4240 throw new IllegalArgumentException("File descriptors passed in Intent"); 4241 } 4242 4243 synchronized(this) { 4244 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4245 if (r == null) { 4246 return true; 4247 } 4248 // Keep track of the root activity of the task before we finish it 4249 TaskRecord tr = r.task; 4250 ActivityRecord rootR = tr.getRootActivity(); 4251 if (rootR == null) { 4252 Slog.w(TAG, "Finishing task with all activities already finished"); 4253 } 4254 // Do not allow task to finish in Lock Task mode. 4255 if (tr == mStackSupervisor.mLockTaskModeTask) { 4256 if (rootR == r) { 4257 Slog.i(TAG, "Not finishing task in lock task mode"); 4258 mStackSupervisor.showLockTaskToast(); 4259 return false; 4260 } 4261 } 4262 if (mController != null) { 4263 // Find the first activity that is not finishing. 4264 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4265 if (next != null) { 4266 // ask watcher if this is allowed 4267 boolean resumeOK = true; 4268 try { 4269 resumeOK = mController.activityResuming(next.packageName); 4270 } catch (RemoteException e) { 4271 mController = null; 4272 Watchdog.getInstance().setActivityController(null); 4273 } 4274 4275 if (!resumeOK) { 4276 Slog.i(TAG, "Not finishing activity because controller resumed"); 4277 return false; 4278 } 4279 } 4280 } 4281 final long origId = Binder.clearCallingIdentity(); 4282 try { 4283 boolean res; 4284 if (finishTask && r == rootR) { 4285 // If requested, remove the task that is associated to this activity only if it 4286 // was the root activity in the task. The result code and data is ignored 4287 // because we don't support returning them across task boundaries. 4288 res = removeTaskByIdLocked(tr.taskId, false); 4289 if (!res) { 4290 Slog.i(TAG, "Removing task failed to finish activity"); 4291 } 4292 } else { 4293 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4294 resultData, "app-request", true); 4295 if (!res) { 4296 Slog.i(TAG, "Failed to finish by app-request"); 4297 } 4298 } 4299 return res; 4300 } finally { 4301 Binder.restoreCallingIdentity(origId); 4302 } 4303 } 4304 } 4305 4306 @Override 4307 public final void finishHeavyWeightApp() { 4308 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4309 != PackageManager.PERMISSION_GRANTED) { 4310 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4311 + Binder.getCallingPid() 4312 + ", uid=" + Binder.getCallingUid() 4313 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4314 Slog.w(TAG, msg); 4315 throw new SecurityException(msg); 4316 } 4317 4318 synchronized(this) { 4319 if (mHeavyWeightProcess == null) { 4320 return; 4321 } 4322 4323 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4324 mHeavyWeightProcess.activities); 4325 for (int i=0; i<activities.size(); i++) { 4326 ActivityRecord r = activities.get(i); 4327 if (!r.finishing) { 4328 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4329 null, "finish-heavy", true); 4330 } 4331 } 4332 4333 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4334 mHeavyWeightProcess.userId, 0)); 4335 mHeavyWeightProcess = null; 4336 } 4337 } 4338 4339 @Override 4340 public void crashApplication(int uid, int initialPid, String packageName, 4341 String message) { 4342 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4343 != PackageManager.PERMISSION_GRANTED) { 4344 String msg = "Permission Denial: crashApplication() from pid=" 4345 + Binder.getCallingPid() 4346 + ", uid=" + Binder.getCallingUid() 4347 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4348 Slog.w(TAG, msg); 4349 throw new SecurityException(msg); 4350 } 4351 4352 synchronized(this) { 4353 ProcessRecord proc = null; 4354 4355 // Figure out which process to kill. We don't trust that initialPid 4356 // still has any relation to current pids, so must scan through the 4357 // list. 4358 synchronized (mPidsSelfLocked) { 4359 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4360 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4361 if (p.uid != uid) { 4362 continue; 4363 } 4364 if (p.pid == initialPid) { 4365 proc = p; 4366 break; 4367 } 4368 if (p.pkgList.containsKey(packageName)) { 4369 proc = p; 4370 } 4371 } 4372 } 4373 4374 if (proc == null) { 4375 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4376 + " initialPid=" + initialPid 4377 + " packageName=" + packageName); 4378 return; 4379 } 4380 4381 if (proc.thread != null) { 4382 if (proc.pid == Process.myPid()) { 4383 Log.w(TAG, "crashApplication: trying to crash self!"); 4384 return; 4385 } 4386 long ident = Binder.clearCallingIdentity(); 4387 try { 4388 proc.thread.scheduleCrash(message); 4389 } catch (RemoteException e) { 4390 } 4391 Binder.restoreCallingIdentity(ident); 4392 } 4393 } 4394 } 4395 4396 @Override 4397 public final void finishSubActivity(IBinder token, String resultWho, 4398 int requestCode) { 4399 synchronized(this) { 4400 final long origId = Binder.clearCallingIdentity(); 4401 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4402 if (r != null) { 4403 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4404 } 4405 Binder.restoreCallingIdentity(origId); 4406 } 4407 } 4408 4409 @Override 4410 public boolean finishActivityAffinity(IBinder token) { 4411 synchronized(this) { 4412 final long origId = Binder.clearCallingIdentity(); 4413 try { 4414 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4415 4416 ActivityRecord rootR = r.task.getRootActivity(); 4417 // Do not allow task to finish in Lock Task mode. 4418 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4419 if (rootR == r) { 4420 mStackSupervisor.showLockTaskToast(); 4421 return false; 4422 } 4423 } 4424 boolean res = false; 4425 if (r != null) { 4426 res = r.task.stack.finishActivityAffinityLocked(r); 4427 } 4428 return res; 4429 } finally { 4430 Binder.restoreCallingIdentity(origId); 4431 } 4432 } 4433 } 4434 4435 @Override 4436 public void finishVoiceTask(IVoiceInteractionSession session) { 4437 synchronized(this) { 4438 final long origId = Binder.clearCallingIdentity(); 4439 try { 4440 mStackSupervisor.finishVoiceTask(session); 4441 } finally { 4442 Binder.restoreCallingIdentity(origId); 4443 } 4444 } 4445 4446 } 4447 4448 @Override 4449 public boolean releaseActivityInstance(IBinder token) { 4450 synchronized(this) { 4451 final long origId = Binder.clearCallingIdentity(); 4452 try { 4453 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4454 if (r.task == null || r.task.stack == null) { 4455 return false; 4456 } 4457 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4458 } finally { 4459 Binder.restoreCallingIdentity(origId); 4460 } 4461 } 4462 } 4463 4464 @Override 4465 public void releaseSomeActivities(IApplicationThread appInt) { 4466 synchronized(this) { 4467 final long origId = Binder.clearCallingIdentity(); 4468 try { 4469 ProcessRecord app = getRecordForAppLocked(appInt); 4470 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4471 } finally { 4472 Binder.restoreCallingIdentity(origId); 4473 } 4474 } 4475 } 4476 4477 @Override 4478 public boolean willActivityBeVisible(IBinder token) { 4479 synchronized(this) { 4480 ActivityStack stack = ActivityRecord.getStackLocked(token); 4481 if (stack != null) { 4482 return stack.willActivityBeVisibleLocked(token); 4483 } 4484 return false; 4485 } 4486 } 4487 4488 @Override 4489 public void overridePendingTransition(IBinder token, String packageName, 4490 int enterAnim, int exitAnim) { 4491 synchronized(this) { 4492 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4493 if (self == null) { 4494 return; 4495 } 4496 4497 final long origId = Binder.clearCallingIdentity(); 4498 4499 if (self.state == ActivityState.RESUMED 4500 || self.state == ActivityState.PAUSING) { 4501 mWindowManager.overridePendingAppTransition(packageName, 4502 enterAnim, exitAnim, null); 4503 } 4504 4505 Binder.restoreCallingIdentity(origId); 4506 } 4507 } 4508 4509 /** 4510 * Main function for removing an existing process from the activity manager 4511 * as a result of that process going away. Clears out all connections 4512 * to the process. 4513 */ 4514 private final void handleAppDiedLocked(ProcessRecord app, 4515 boolean restarting, boolean allowRestart) { 4516 int pid = app.pid; 4517 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4518 if (!kept && !restarting) { 4519 removeLruProcessLocked(app); 4520 if (pid > 0) { 4521 ProcessList.remove(pid); 4522 } 4523 } 4524 4525 if (mProfileProc == app) { 4526 clearProfilerLocked(); 4527 } 4528 4529 // Remove this application's activities from active lists. 4530 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4531 4532 app.activities.clear(); 4533 4534 if (app.instrumentationClass != null) { 4535 Slog.w(TAG, "Crash of app " + app.processName 4536 + " running instrumentation " + app.instrumentationClass); 4537 Bundle info = new Bundle(); 4538 info.putString("shortMsg", "Process crashed."); 4539 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4540 } 4541 4542 if (!restarting) { 4543 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4544 // If there was nothing to resume, and we are not already 4545 // restarting this process, but there is a visible activity that 4546 // is hosted by the process... then make sure all visible 4547 // activities are running, taking care of restarting this 4548 // process. 4549 if (hasVisibleActivities) { 4550 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4551 } 4552 } 4553 } 4554 } 4555 4556 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4557 IBinder threadBinder = thread.asBinder(); 4558 // Find the application record. 4559 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4560 ProcessRecord rec = mLruProcesses.get(i); 4561 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4562 return i; 4563 } 4564 } 4565 return -1; 4566 } 4567 4568 final ProcessRecord getRecordForAppLocked( 4569 IApplicationThread thread) { 4570 if (thread == null) { 4571 return null; 4572 } 4573 4574 int appIndex = getLRURecordIndexForAppLocked(thread); 4575 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4576 } 4577 4578 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4579 // If there are no longer any background processes running, 4580 // and the app that died was not running instrumentation, 4581 // then tell everyone we are now low on memory. 4582 boolean haveBg = false; 4583 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4584 ProcessRecord rec = mLruProcesses.get(i); 4585 if (rec.thread != null 4586 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4587 haveBg = true; 4588 break; 4589 } 4590 } 4591 4592 if (!haveBg) { 4593 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4594 if (doReport) { 4595 long now = SystemClock.uptimeMillis(); 4596 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4597 doReport = false; 4598 } else { 4599 mLastMemUsageReportTime = now; 4600 } 4601 } 4602 final ArrayList<ProcessMemInfo> memInfos 4603 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4604 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4605 long now = SystemClock.uptimeMillis(); 4606 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4607 ProcessRecord rec = mLruProcesses.get(i); 4608 if (rec == dyingProc || rec.thread == null) { 4609 continue; 4610 } 4611 if (doReport) { 4612 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4613 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4614 } 4615 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4616 // The low memory report is overriding any current 4617 // state for a GC request. Make sure to do 4618 // heavy/important/visible/foreground processes first. 4619 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4620 rec.lastRequestedGc = 0; 4621 } else { 4622 rec.lastRequestedGc = rec.lastLowMemory; 4623 } 4624 rec.reportLowMemory = true; 4625 rec.lastLowMemory = now; 4626 mProcessesToGc.remove(rec); 4627 addProcessToGcListLocked(rec); 4628 } 4629 } 4630 if (doReport) { 4631 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4632 mHandler.sendMessage(msg); 4633 } 4634 scheduleAppGcsLocked(); 4635 } 4636 } 4637 4638 final void appDiedLocked(ProcessRecord app) { 4639 appDiedLocked(app, app.pid, app.thread); 4640 } 4641 4642 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4643 // First check if this ProcessRecord is actually active for the pid. 4644 synchronized (mPidsSelfLocked) { 4645 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4646 if (curProc != app) { 4647 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4648 return; 4649 } 4650 } 4651 4652 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4653 synchronized (stats) { 4654 stats.noteProcessDiedLocked(app.info.uid, pid); 4655 } 4656 4657 Process.killProcessQuiet(pid); 4658 Process.killProcessGroup(app.info.uid, pid); 4659 app.killed = true; 4660 4661 // Clean up already done if the process has been re-started. 4662 if (app.pid == pid && app.thread != null && 4663 app.thread.asBinder() == thread.asBinder()) { 4664 boolean doLowMem = app.instrumentationClass == null; 4665 boolean doOomAdj = doLowMem; 4666 if (!app.killedByAm) { 4667 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4668 + ") has died"); 4669 mAllowLowerMemLevel = true; 4670 } else { 4671 // Note that we always want to do oom adj to update our state with the 4672 // new number of procs. 4673 mAllowLowerMemLevel = false; 4674 doLowMem = false; 4675 } 4676 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4677 if (DEBUG_CLEANUP) Slog.v( 4678 TAG, "Dying app: " + app + ", pid: " + pid 4679 + ", thread: " + thread.asBinder()); 4680 handleAppDiedLocked(app, false, true); 4681 4682 if (doOomAdj) { 4683 updateOomAdjLocked(); 4684 } 4685 if (doLowMem) { 4686 doLowMemReportIfNeededLocked(app); 4687 } 4688 } else if (app.pid != pid) { 4689 // A new process has already been started. 4690 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4691 + ") has died and restarted (pid " + app.pid + ")."); 4692 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4693 } else if (DEBUG_PROCESSES) { 4694 Slog.d(TAG, "Received spurious death notification for thread " 4695 + thread.asBinder()); 4696 } 4697 } 4698 4699 /** 4700 * If a stack trace dump file is configured, dump process stack traces. 4701 * @param clearTraces causes the dump file to be erased prior to the new 4702 * traces being written, if true; when false, the new traces will be 4703 * appended to any existing file content. 4704 * @param firstPids of dalvik VM processes to dump stack traces for first 4705 * @param lastPids of dalvik VM processes to dump stack traces for last 4706 * @param nativeProcs optional list of native process names to dump stack crawls 4707 * @return file containing stack traces, or null if no dump file is configured 4708 */ 4709 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4710 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4711 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4712 if (tracesPath == null || tracesPath.length() == 0) { 4713 return null; 4714 } 4715 4716 File tracesFile = new File(tracesPath); 4717 try { 4718 File tracesDir = tracesFile.getParentFile(); 4719 if (!tracesDir.exists()) { 4720 tracesDir.mkdirs(); 4721 if (!SELinux.restorecon(tracesDir)) { 4722 return null; 4723 } 4724 } 4725 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4726 4727 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4728 tracesFile.createNewFile(); 4729 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4730 } catch (IOException e) { 4731 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4732 return null; 4733 } 4734 4735 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4736 return tracesFile; 4737 } 4738 4739 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4740 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4741 // Use a FileObserver to detect when traces finish writing. 4742 // The order of traces is considered important to maintain for legibility. 4743 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4744 @Override 4745 public synchronized void onEvent(int event, String path) { notify(); } 4746 }; 4747 4748 try { 4749 observer.startWatching(); 4750 4751 // First collect all of the stacks of the most important pids. 4752 if (firstPids != null) { 4753 try { 4754 int num = firstPids.size(); 4755 for (int i = 0; i < num; i++) { 4756 synchronized (observer) { 4757 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4758 observer.wait(200); // Wait for write-close, give up after 200msec 4759 } 4760 } 4761 } catch (InterruptedException e) { 4762 Slog.wtf(TAG, e); 4763 } 4764 } 4765 4766 // Next collect the stacks of the native pids 4767 if (nativeProcs != null) { 4768 int[] pids = Process.getPidsForCommands(nativeProcs); 4769 if (pids != null) { 4770 for (int pid : pids) { 4771 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4772 } 4773 } 4774 } 4775 4776 // Lastly, measure CPU usage. 4777 if (processCpuTracker != null) { 4778 processCpuTracker.init(); 4779 System.gc(); 4780 processCpuTracker.update(); 4781 try { 4782 synchronized (processCpuTracker) { 4783 processCpuTracker.wait(500); // measure over 1/2 second. 4784 } 4785 } catch (InterruptedException e) { 4786 } 4787 processCpuTracker.update(); 4788 4789 // We'll take the stack crawls of just the top apps using CPU. 4790 final int N = processCpuTracker.countWorkingStats(); 4791 int numProcs = 0; 4792 for (int i=0; i<N && numProcs<5; i++) { 4793 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4794 if (lastPids.indexOfKey(stats.pid) >= 0) { 4795 numProcs++; 4796 try { 4797 synchronized (observer) { 4798 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4799 observer.wait(200); // Wait for write-close, give up after 200msec 4800 } 4801 } catch (InterruptedException e) { 4802 Slog.wtf(TAG, e); 4803 } 4804 4805 } 4806 } 4807 } 4808 } finally { 4809 observer.stopWatching(); 4810 } 4811 } 4812 4813 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4814 if (true || IS_USER_BUILD) { 4815 return; 4816 } 4817 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4818 if (tracesPath == null || tracesPath.length() == 0) { 4819 return; 4820 } 4821 4822 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4823 StrictMode.allowThreadDiskWrites(); 4824 try { 4825 final File tracesFile = new File(tracesPath); 4826 final File tracesDir = tracesFile.getParentFile(); 4827 final File tracesTmp = new File(tracesDir, "__tmp__"); 4828 try { 4829 if (!tracesDir.exists()) { 4830 tracesDir.mkdirs(); 4831 if (!SELinux.restorecon(tracesDir.getPath())) { 4832 return; 4833 } 4834 } 4835 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4836 4837 if (tracesFile.exists()) { 4838 tracesTmp.delete(); 4839 tracesFile.renameTo(tracesTmp); 4840 } 4841 StringBuilder sb = new StringBuilder(); 4842 Time tobj = new Time(); 4843 tobj.set(System.currentTimeMillis()); 4844 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4845 sb.append(": "); 4846 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4847 sb.append(" since "); 4848 sb.append(msg); 4849 FileOutputStream fos = new FileOutputStream(tracesFile); 4850 fos.write(sb.toString().getBytes()); 4851 if (app == null) { 4852 fos.write("\n*** No application process!".getBytes()); 4853 } 4854 fos.close(); 4855 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4856 } catch (IOException e) { 4857 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4858 return; 4859 } 4860 4861 if (app != null) { 4862 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4863 firstPids.add(app.pid); 4864 dumpStackTraces(tracesPath, firstPids, null, null, null); 4865 } 4866 4867 File lastTracesFile = null; 4868 File curTracesFile = null; 4869 for (int i=9; i>=0; i--) { 4870 String name = String.format(Locale.US, "slow%02d.txt", i); 4871 curTracesFile = new File(tracesDir, name); 4872 if (curTracesFile.exists()) { 4873 if (lastTracesFile != null) { 4874 curTracesFile.renameTo(lastTracesFile); 4875 } else { 4876 curTracesFile.delete(); 4877 } 4878 } 4879 lastTracesFile = curTracesFile; 4880 } 4881 tracesFile.renameTo(curTracesFile); 4882 if (tracesTmp.exists()) { 4883 tracesTmp.renameTo(tracesFile); 4884 } 4885 } finally { 4886 StrictMode.setThreadPolicy(oldPolicy); 4887 } 4888 } 4889 4890 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4891 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4892 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4893 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4894 4895 if (mController != null) { 4896 try { 4897 // 0 == continue, -1 = kill process immediately 4898 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4899 if (res < 0 && app.pid != MY_PID) { 4900 app.kill("anr", true); 4901 } 4902 } catch (RemoteException e) { 4903 mController = null; 4904 Watchdog.getInstance().setActivityController(null); 4905 } 4906 } 4907 4908 long anrTime = SystemClock.uptimeMillis(); 4909 if (MONITOR_CPU_USAGE) { 4910 updateCpuStatsNow(); 4911 } 4912 4913 synchronized (this) { 4914 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4915 if (mShuttingDown) { 4916 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4917 return; 4918 } else if (app.notResponding) { 4919 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4920 return; 4921 } else if (app.crashing) { 4922 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4923 return; 4924 } 4925 4926 // In case we come through here for the same app before completing 4927 // this one, mark as anring now so we will bail out. 4928 app.notResponding = true; 4929 4930 // Log the ANR to the event log. 4931 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4932 app.processName, app.info.flags, annotation); 4933 4934 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4935 firstPids.add(app.pid); 4936 4937 int parentPid = app.pid; 4938 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4939 if (parentPid != app.pid) firstPids.add(parentPid); 4940 4941 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4942 4943 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4944 ProcessRecord r = mLruProcesses.get(i); 4945 if (r != null && r.thread != null) { 4946 int pid = r.pid; 4947 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4948 if (r.persistent) { 4949 firstPids.add(pid); 4950 } else { 4951 lastPids.put(pid, Boolean.TRUE); 4952 } 4953 } 4954 } 4955 } 4956 } 4957 4958 // Log the ANR to the main log. 4959 StringBuilder info = new StringBuilder(); 4960 info.setLength(0); 4961 info.append("ANR in ").append(app.processName); 4962 if (activity != null && activity.shortComponentName != null) { 4963 info.append(" (").append(activity.shortComponentName).append(")"); 4964 } 4965 info.append("\n"); 4966 info.append("PID: ").append(app.pid).append("\n"); 4967 if (annotation != null) { 4968 info.append("Reason: ").append(annotation).append("\n"); 4969 } 4970 if (parent != null && parent != activity) { 4971 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4972 } 4973 4974 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4975 4976 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4977 NATIVE_STACKS_OF_INTEREST); 4978 4979 String cpuInfo = null; 4980 if (MONITOR_CPU_USAGE) { 4981 updateCpuStatsNow(); 4982 synchronized (mProcessCpuTracker) { 4983 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4984 } 4985 info.append(processCpuTracker.printCurrentLoad()); 4986 info.append(cpuInfo); 4987 } 4988 4989 info.append(processCpuTracker.printCurrentState(anrTime)); 4990 4991 Slog.e(TAG, info.toString()); 4992 if (tracesFile == null) { 4993 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4994 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4995 } 4996 4997 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4998 cpuInfo, tracesFile, null); 4999 5000 if (mController != null) { 5001 try { 5002 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5003 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5004 if (res != 0) { 5005 if (res < 0 && app.pid != MY_PID) { 5006 app.kill("anr", true); 5007 } else { 5008 synchronized (this) { 5009 mServices.scheduleServiceTimeoutLocked(app); 5010 } 5011 } 5012 return; 5013 } 5014 } catch (RemoteException e) { 5015 mController = null; 5016 Watchdog.getInstance().setActivityController(null); 5017 } 5018 } 5019 5020 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5021 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5022 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5023 5024 synchronized (this) { 5025 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5026 app.kill("bg anr", true); 5027 return; 5028 } 5029 5030 // Set the app's notResponding state, and look up the errorReportReceiver 5031 makeAppNotRespondingLocked(app, 5032 activity != null ? activity.shortComponentName : null, 5033 annotation != null ? "ANR " + annotation : "ANR", 5034 info.toString()); 5035 5036 // Bring up the infamous App Not Responding dialog 5037 Message msg = Message.obtain(); 5038 HashMap<String, Object> map = new HashMap<String, Object>(); 5039 msg.what = SHOW_NOT_RESPONDING_MSG; 5040 msg.obj = map; 5041 msg.arg1 = aboveSystem ? 1 : 0; 5042 map.put("app", app); 5043 if (activity != null) { 5044 map.put("activity", activity); 5045 } 5046 5047 mHandler.sendMessage(msg); 5048 } 5049 } 5050 5051 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5052 if (!mLaunchWarningShown) { 5053 mLaunchWarningShown = true; 5054 mHandler.post(new Runnable() { 5055 @Override 5056 public void run() { 5057 synchronized (ActivityManagerService.this) { 5058 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5059 d.show(); 5060 mHandler.postDelayed(new Runnable() { 5061 @Override 5062 public void run() { 5063 synchronized (ActivityManagerService.this) { 5064 d.dismiss(); 5065 mLaunchWarningShown = false; 5066 } 5067 } 5068 }, 4000); 5069 } 5070 } 5071 }); 5072 } 5073 } 5074 5075 @Override 5076 public boolean clearApplicationUserData(final String packageName, 5077 final IPackageDataObserver observer, int userId) { 5078 enforceNotIsolatedCaller("clearApplicationUserData"); 5079 int uid = Binder.getCallingUid(); 5080 int pid = Binder.getCallingPid(); 5081 userId = handleIncomingUser(pid, uid, 5082 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5083 long callingId = Binder.clearCallingIdentity(); 5084 try { 5085 IPackageManager pm = AppGlobals.getPackageManager(); 5086 int pkgUid = -1; 5087 synchronized(this) { 5088 try { 5089 pkgUid = pm.getPackageUid(packageName, userId); 5090 } catch (RemoteException e) { 5091 } 5092 if (pkgUid == -1) { 5093 Slog.w(TAG, "Invalid packageName: " + packageName); 5094 if (observer != null) { 5095 try { 5096 observer.onRemoveCompleted(packageName, false); 5097 } catch (RemoteException e) { 5098 Slog.i(TAG, "Observer no longer exists."); 5099 } 5100 } 5101 return false; 5102 } 5103 if (uid == pkgUid || checkComponentPermission( 5104 android.Manifest.permission.CLEAR_APP_USER_DATA, 5105 pid, uid, -1, true) 5106 == PackageManager.PERMISSION_GRANTED) { 5107 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5108 } else { 5109 throw new SecurityException("PID " + pid + " does not have permission " 5110 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5111 + " of package " + packageName); 5112 } 5113 5114 // Remove all tasks match the cleared application package and user 5115 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5116 final TaskRecord tr = mRecentTasks.get(i); 5117 final String taskPackageName = 5118 tr.getBaseIntent().getComponent().getPackageName(); 5119 if (tr.userId != userId) continue; 5120 if (!taskPackageName.equals(packageName)) continue; 5121 removeTaskByIdLocked(tr.taskId, false); 5122 } 5123 } 5124 5125 try { 5126 // Clear application user data 5127 pm.clearApplicationUserData(packageName, observer, userId); 5128 5129 synchronized(this) { 5130 // Remove all permissions granted from/to this package 5131 removeUriPermissionsForPackageLocked(packageName, userId, true); 5132 } 5133 5134 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5135 Uri.fromParts("package", packageName, null)); 5136 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5137 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5138 null, null, 0, null, null, null, false, false, userId); 5139 } catch (RemoteException e) { 5140 } 5141 } finally { 5142 Binder.restoreCallingIdentity(callingId); 5143 } 5144 return true; 5145 } 5146 5147 @Override 5148 public void killBackgroundProcesses(final String packageName, int userId) { 5149 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5150 != PackageManager.PERMISSION_GRANTED && 5151 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5152 != PackageManager.PERMISSION_GRANTED) { 5153 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5154 + Binder.getCallingPid() 5155 + ", uid=" + Binder.getCallingUid() 5156 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5157 Slog.w(TAG, msg); 5158 throw new SecurityException(msg); 5159 } 5160 5161 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5162 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5163 long callingId = Binder.clearCallingIdentity(); 5164 try { 5165 IPackageManager pm = AppGlobals.getPackageManager(); 5166 synchronized(this) { 5167 int appId = -1; 5168 try { 5169 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5170 } catch (RemoteException e) { 5171 } 5172 if (appId == -1) { 5173 Slog.w(TAG, "Invalid packageName: " + packageName); 5174 return; 5175 } 5176 killPackageProcessesLocked(packageName, appId, userId, 5177 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5178 } 5179 } finally { 5180 Binder.restoreCallingIdentity(callingId); 5181 } 5182 } 5183 5184 @Override 5185 public void killAllBackgroundProcesses() { 5186 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5187 != PackageManager.PERMISSION_GRANTED) { 5188 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5189 + Binder.getCallingPid() 5190 + ", uid=" + Binder.getCallingUid() 5191 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5192 Slog.w(TAG, msg); 5193 throw new SecurityException(msg); 5194 } 5195 5196 long callingId = Binder.clearCallingIdentity(); 5197 try { 5198 synchronized(this) { 5199 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5200 final int NP = mProcessNames.getMap().size(); 5201 for (int ip=0; ip<NP; ip++) { 5202 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5203 final int NA = apps.size(); 5204 for (int ia=0; ia<NA; ia++) { 5205 ProcessRecord app = apps.valueAt(ia); 5206 if (app.persistent) { 5207 // we don't kill persistent processes 5208 continue; 5209 } 5210 if (app.removed) { 5211 procs.add(app); 5212 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5213 app.removed = true; 5214 procs.add(app); 5215 } 5216 } 5217 } 5218 5219 int N = procs.size(); 5220 for (int i=0; i<N; i++) { 5221 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5222 } 5223 mAllowLowerMemLevel = true; 5224 updateOomAdjLocked(); 5225 doLowMemReportIfNeededLocked(null); 5226 } 5227 } finally { 5228 Binder.restoreCallingIdentity(callingId); 5229 } 5230 } 5231 5232 @Override 5233 public void forceStopPackage(final String packageName, int userId) { 5234 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5235 != PackageManager.PERMISSION_GRANTED) { 5236 String msg = "Permission Denial: forceStopPackage() from pid=" 5237 + Binder.getCallingPid() 5238 + ", uid=" + Binder.getCallingUid() 5239 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5240 Slog.w(TAG, msg); 5241 throw new SecurityException(msg); 5242 } 5243 final int callingPid = Binder.getCallingPid(); 5244 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5245 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5246 long callingId = Binder.clearCallingIdentity(); 5247 try { 5248 IPackageManager pm = AppGlobals.getPackageManager(); 5249 synchronized(this) { 5250 int[] users = userId == UserHandle.USER_ALL 5251 ? getUsersLocked() : new int[] { userId }; 5252 for (int user : users) { 5253 int pkgUid = -1; 5254 try { 5255 pkgUid = pm.getPackageUid(packageName, user); 5256 } catch (RemoteException e) { 5257 } 5258 if (pkgUid == -1) { 5259 Slog.w(TAG, "Invalid packageName: " + packageName); 5260 continue; 5261 } 5262 try { 5263 pm.setPackageStoppedState(packageName, true, user); 5264 } catch (RemoteException e) { 5265 } catch (IllegalArgumentException e) { 5266 Slog.w(TAG, "Failed trying to unstop package " 5267 + packageName + ": " + e); 5268 } 5269 if (isUserRunningLocked(user, false)) { 5270 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5271 } 5272 } 5273 } 5274 } finally { 5275 Binder.restoreCallingIdentity(callingId); 5276 } 5277 } 5278 5279 @Override 5280 public void addPackageDependency(String packageName) { 5281 synchronized (this) { 5282 int callingPid = Binder.getCallingPid(); 5283 if (callingPid == Process.myPid()) { 5284 // Yeah, um, no. 5285 Slog.w(TAG, "Can't addPackageDependency on system process"); 5286 return; 5287 } 5288 ProcessRecord proc; 5289 synchronized (mPidsSelfLocked) { 5290 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5291 } 5292 if (proc != null) { 5293 if (proc.pkgDeps == null) { 5294 proc.pkgDeps = new ArraySet<String>(1); 5295 } 5296 proc.pkgDeps.add(packageName); 5297 } 5298 } 5299 } 5300 5301 /* 5302 * The pkg name and app id have to be specified. 5303 */ 5304 @Override 5305 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5306 if (pkg == null) { 5307 return; 5308 } 5309 // Make sure the uid is valid. 5310 if (appid < 0) { 5311 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5312 return; 5313 } 5314 int callerUid = Binder.getCallingUid(); 5315 // Only the system server can kill an application 5316 if (callerUid == Process.SYSTEM_UID) { 5317 // Post an aysnc message to kill the application 5318 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5319 msg.arg1 = appid; 5320 msg.arg2 = 0; 5321 Bundle bundle = new Bundle(); 5322 bundle.putString("pkg", pkg); 5323 bundle.putString("reason", reason); 5324 msg.obj = bundle; 5325 mHandler.sendMessage(msg); 5326 } else { 5327 throw new SecurityException(callerUid + " cannot kill pkg: " + 5328 pkg); 5329 } 5330 } 5331 5332 @Override 5333 public void closeSystemDialogs(String reason) { 5334 enforceNotIsolatedCaller("closeSystemDialogs"); 5335 5336 final int pid = Binder.getCallingPid(); 5337 final int uid = Binder.getCallingUid(); 5338 final long origId = Binder.clearCallingIdentity(); 5339 try { 5340 synchronized (this) { 5341 // Only allow this from foreground processes, so that background 5342 // applications can't abuse it to prevent system UI from being shown. 5343 if (uid >= Process.FIRST_APPLICATION_UID) { 5344 ProcessRecord proc; 5345 synchronized (mPidsSelfLocked) { 5346 proc = mPidsSelfLocked.get(pid); 5347 } 5348 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5349 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5350 + " from background process " + proc); 5351 return; 5352 } 5353 } 5354 closeSystemDialogsLocked(reason); 5355 } 5356 } finally { 5357 Binder.restoreCallingIdentity(origId); 5358 } 5359 } 5360 5361 void closeSystemDialogsLocked(String reason) { 5362 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5363 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5364 | Intent.FLAG_RECEIVER_FOREGROUND); 5365 if (reason != null) { 5366 intent.putExtra("reason", reason); 5367 } 5368 mWindowManager.closeSystemDialogs(reason); 5369 5370 mStackSupervisor.closeSystemDialogsLocked(); 5371 5372 broadcastIntentLocked(null, null, intent, null, 5373 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5374 Process.SYSTEM_UID, UserHandle.USER_ALL); 5375 } 5376 5377 @Override 5378 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5379 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5380 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5381 for (int i=pids.length-1; i>=0; i--) { 5382 ProcessRecord proc; 5383 int oomAdj; 5384 synchronized (this) { 5385 synchronized (mPidsSelfLocked) { 5386 proc = mPidsSelfLocked.get(pids[i]); 5387 oomAdj = proc != null ? proc.setAdj : 0; 5388 } 5389 } 5390 infos[i] = new Debug.MemoryInfo(); 5391 Debug.getMemoryInfo(pids[i], infos[i]); 5392 if (proc != null) { 5393 synchronized (this) { 5394 if (proc.thread != null && proc.setAdj == oomAdj) { 5395 // Record this for posterity if the process has been stable. 5396 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5397 infos[i].getTotalUss(), false, proc.pkgList); 5398 } 5399 } 5400 } 5401 } 5402 return infos; 5403 } 5404 5405 @Override 5406 public long[] getProcessPss(int[] pids) { 5407 enforceNotIsolatedCaller("getProcessPss"); 5408 long[] pss = new long[pids.length]; 5409 for (int i=pids.length-1; i>=0; i--) { 5410 ProcessRecord proc; 5411 int oomAdj; 5412 synchronized (this) { 5413 synchronized (mPidsSelfLocked) { 5414 proc = mPidsSelfLocked.get(pids[i]); 5415 oomAdj = proc != null ? proc.setAdj : 0; 5416 } 5417 } 5418 long[] tmpUss = new long[1]; 5419 pss[i] = Debug.getPss(pids[i], tmpUss); 5420 if (proc != null) { 5421 synchronized (this) { 5422 if (proc.thread != null && proc.setAdj == oomAdj) { 5423 // Record this for posterity if the process has been stable. 5424 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5425 } 5426 } 5427 } 5428 } 5429 return pss; 5430 } 5431 5432 @Override 5433 public void killApplicationProcess(String processName, int uid) { 5434 if (processName == null) { 5435 return; 5436 } 5437 5438 int callerUid = Binder.getCallingUid(); 5439 // Only the system server can kill an application 5440 if (callerUid == Process.SYSTEM_UID) { 5441 synchronized (this) { 5442 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5443 if (app != null && app.thread != null) { 5444 try { 5445 app.thread.scheduleSuicide(); 5446 } catch (RemoteException e) { 5447 // If the other end already died, then our work here is done. 5448 } 5449 } else { 5450 Slog.w(TAG, "Process/uid not found attempting kill of " 5451 + processName + " / " + uid); 5452 } 5453 } 5454 } else { 5455 throw new SecurityException(callerUid + " cannot kill app process: " + 5456 processName); 5457 } 5458 } 5459 5460 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5461 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5462 false, true, false, false, UserHandle.getUserId(uid), reason); 5463 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5464 Uri.fromParts("package", packageName, null)); 5465 if (!mProcessesReady) { 5466 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5467 | Intent.FLAG_RECEIVER_FOREGROUND); 5468 } 5469 intent.putExtra(Intent.EXTRA_UID, uid); 5470 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5471 broadcastIntentLocked(null, null, intent, 5472 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5473 false, false, 5474 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5475 } 5476 5477 private void forceStopUserLocked(int userId, String reason) { 5478 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5479 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5480 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5481 | Intent.FLAG_RECEIVER_FOREGROUND); 5482 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5483 broadcastIntentLocked(null, null, intent, 5484 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5485 false, false, 5486 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5487 } 5488 5489 private final boolean killPackageProcessesLocked(String packageName, int appId, 5490 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5491 boolean doit, boolean evenPersistent, String reason) { 5492 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5493 5494 // Remove all processes this package may have touched: all with the 5495 // same UID (except for the system or root user), and all whose name 5496 // matches the package name. 5497 final int NP = mProcessNames.getMap().size(); 5498 for (int ip=0; ip<NP; ip++) { 5499 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5500 final int NA = apps.size(); 5501 for (int ia=0; ia<NA; ia++) { 5502 ProcessRecord app = apps.valueAt(ia); 5503 if (app.persistent && !evenPersistent) { 5504 // we don't kill persistent processes 5505 continue; 5506 } 5507 if (app.removed) { 5508 if (doit) { 5509 procs.add(app); 5510 } 5511 continue; 5512 } 5513 5514 // Skip process if it doesn't meet our oom adj requirement. 5515 if (app.setAdj < minOomAdj) { 5516 continue; 5517 } 5518 5519 // If no package is specified, we call all processes under the 5520 // give user id. 5521 if (packageName == null) { 5522 if (app.userId != userId) { 5523 continue; 5524 } 5525 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5526 continue; 5527 } 5528 // Package has been specified, we want to hit all processes 5529 // that match it. We need to qualify this by the processes 5530 // that are running under the specified app and user ID. 5531 } else { 5532 final boolean isDep = app.pkgDeps != null 5533 && app.pkgDeps.contains(packageName); 5534 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5535 continue; 5536 } 5537 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5538 continue; 5539 } 5540 if (!app.pkgList.containsKey(packageName) && !isDep) { 5541 continue; 5542 } 5543 } 5544 5545 // Process has passed all conditions, kill it! 5546 if (!doit) { 5547 return true; 5548 } 5549 app.removed = true; 5550 procs.add(app); 5551 } 5552 } 5553 5554 int N = procs.size(); 5555 for (int i=0; i<N; i++) { 5556 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5557 } 5558 updateOomAdjLocked(); 5559 return N > 0; 5560 } 5561 5562 private final boolean forceStopPackageLocked(String name, int appId, 5563 boolean callerWillRestart, boolean purgeCache, boolean doit, 5564 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5565 int i; 5566 int N; 5567 5568 if (userId == UserHandle.USER_ALL && name == null) { 5569 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5570 } 5571 5572 if (appId < 0 && name != null) { 5573 try { 5574 appId = UserHandle.getAppId( 5575 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5576 } catch (RemoteException e) { 5577 } 5578 } 5579 5580 if (doit) { 5581 if (name != null) { 5582 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5583 + " user=" + userId + ": " + reason); 5584 } else { 5585 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5586 } 5587 5588 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5589 for (int ip=pmap.size()-1; ip>=0; ip--) { 5590 SparseArray<Long> ba = pmap.valueAt(ip); 5591 for (i=ba.size()-1; i>=0; i--) { 5592 boolean remove = false; 5593 final int entUid = ba.keyAt(i); 5594 if (name != null) { 5595 if (userId == UserHandle.USER_ALL) { 5596 if (UserHandle.getAppId(entUid) == appId) { 5597 remove = true; 5598 } 5599 } else { 5600 if (entUid == UserHandle.getUid(userId, appId)) { 5601 remove = true; 5602 } 5603 } 5604 } else if (UserHandle.getUserId(entUid) == userId) { 5605 remove = true; 5606 } 5607 if (remove) { 5608 ba.removeAt(i); 5609 } 5610 } 5611 if (ba.size() == 0) { 5612 pmap.removeAt(ip); 5613 } 5614 } 5615 } 5616 5617 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5618 -100, callerWillRestart, true, doit, evenPersistent, 5619 name == null ? ("stop user " + userId) : ("stop " + name)); 5620 5621 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5622 if (!doit) { 5623 return true; 5624 } 5625 didSomething = true; 5626 } 5627 5628 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5629 if (!doit) { 5630 return true; 5631 } 5632 didSomething = true; 5633 } 5634 5635 if (name == null) { 5636 // Remove all sticky broadcasts from this user. 5637 mStickyBroadcasts.remove(userId); 5638 } 5639 5640 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5641 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5642 userId, providers)) { 5643 if (!doit) { 5644 return true; 5645 } 5646 didSomething = true; 5647 } 5648 N = providers.size(); 5649 for (i=0; i<N; i++) { 5650 removeDyingProviderLocked(null, providers.get(i), true); 5651 } 5652 5653 // Remove transient permissions granted from/to this package/user 5654 removeUriPermissionsForPackageLocked(name, userId, false); 5655 5656 if (name == null || uninstalling) { 5657 // Remove pending intents. For now we only do this when force 5658 // stopping users, because we have some problems when doing this 5659 // for packages -- app widgets are not currently cleaned up for 5660 // such packages, so they can be left with bad pending intents. 5661 if (mIntentSenderRecords.size() > 0) { 5662 Iterator<WeakReference<PendingIntentRecord>> it 5663 = mIntentSenderRecords.values().iterator(); 5664 while (it.hasNext()) { 5665 WeakReference<PendingIntentRecord> wpir = it.next(); 5666 if (wpir == null) { 5667 it.remove(); 5668 continue; 5669 } 5670 PendingIntentRecord pir = wpir.get(); 5671 if (pir == null) { 5672 it.remove(); 5673 continue; 5674 } 5675 if (name == null) { 5676 // Stopping user, remove all objects for the user. 5677 if (pir.key.userId != userId) { 5678 // Not the same user, skip it. 5679 continue; 5680 } 5681 } else { 5682 if (UserHandle.getAppId(pir.uid) != appId) { 5683 // Different app id, skip it. 5684 continue; 5685 } 5686 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5687 // Different user, skip it. 5688 continue; 5689 } 5690 if (!pir.key.packageName.equals(name)) { 5691 // Different package, skip it. 5692 continue; 5693 } 5694 } 5695 if (!doit) { 5696 return true; 5697 } 5698 didSomething = true; 5699 it.remove(); 5700 pir.canceled = true; 5701 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5702 pir.key.activity.pendingResults.remove(pir.ref); 5703 } 5704 } 5705 } 5706 } 5707 5708 if (doit) { 5709 if (purgeCache && name != null) { 5710 AttributeCache ac = AttributeCache.instance(); 5711 if (ac != null) { 5712 ac.removePackage(name); 5713 } 5714 } 5715 if (mBooted) { 5716 mStackSupervisor.resumeTopActivitiesLocked(); 5717 mStackSupervisor.scheduleIdleLocked(); 5718 } 5719 } 5720 5721 return didSomething; 5722 } 5723 5724 private final boolean removeProcessLocked(ProcessRecord app, 5725 boolean callerWillRestart, boolean allowRestart, String reason) { 5726 final String name = app.processName; 5727 final int uid = app.uid; 5728 if (DEBUG_PROCESSES) Slog.d( 5729 TAG, "Force removing proc " + app.toShortString() + " (" + name 5730 + "/" + uid + ")"); 5731 5732 mProcessNames.remove(name, uid); 5733 mIsolatedProcesses.remove(app.uid); 5734 if (mHeavyWeightProcess == app) { 5735 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5736 mHeavyWeightProcess.userId, 0)); 5737 mHeavyWeightProcess = null; 5738 } 5739 boolean needRestart = false; 5740 if (app.pid > 0 && app.pid != MY_PID) { 5741 int pid = app.pid; 5742 synchronized (mPidsSelfLocked) { 5743 mPidsSelfLocked.remove(pid); 5744 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5745 } 5746 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5747 if (app.isolated) { 5748 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5749 } 5750 app.kill(reason, true); 5751 handleAppDiedLocked(app, true, allowRestart); 5752 removeLruProcessLocked(app); 5753 5754 if (app.persistent && !app.isolated) { 5755 if (!callerWillRestart) { 5756 addAppLocked(app.info, false, null /* ABI override */); 5757 } else { 5758 needRestart = true; 5759 } 5760 } 5761 } else { 5762 mRemovedProcesses.add(app); 5763 } 5764 5765 return needRestart; 5766 } 5767 5768 private final void processStartTimedOutLocked(ProcessRecord app) { 5769 final int pid = app.pid; 5770 boolean gone = false; 5771 synchronized (mPidsSelfLocked) { 5772 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5773 if (knownApp != null && knownApp.thread == null) { 5774 mPidsSelfLocked.remove(pid); 5775 gone = true; 5776 } 5777 } 5778 5779 if (gone) { 5780 Slog.w(TAG, "Process " + app + " failed to attach"); 5781 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5782 pid, app.uid, app.processName); 5783 mProcessNames.remove(app.processName, app.uid); 5784 mIsolatedProcesses.remove(app.uid); 5785 if (mHeavyWeightProcess == app) { 5786 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5787 mHeavyWeightProcess.userId, 0)); 5788 mHeavyWeightProcess = null; 5789 } 5790 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5791 if (app.isolated) { 5792 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5793 } 5794 // Take care of any launching providers waiting for this process. 5795 checkAppInLaunchingProvidersLocked(app, true); 5796 // Take care of any services that are waiting for the process. 5797 mServices.processStartTimedOutLocked(app); 5798 app.kill("start timeout", true); 5799 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5800 Slog.w(TAG, "Unattached app died before backup, skipping"); 5801 try { 5802 IBackupManager bm = IBackupManager.Stub.asInterface( 5803 ServiceManager.getService(Context.BACKUP_SERVICE)); 5804 bm.agentDisconnected(app.info.packageName); 5805 } catch (RemoteException e) { 5806 // Can't happen; the backup manager is local 5807 } 5808 } 5809 if (isPendingBroadcastProcessLocked(pid)) { 5810 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5811 skipPendingBroadcastLocked(pid); 5812 } 5813 } else { 5814 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5815 } 5816 } 5817 5818 private final boolean attachApplicationLocked(IApplicationThread thread, 5819 int pid) { 5820 5821 // Find the application record that is being attached... either via 5822 // the pid if we are running in multiple processes, or just pull the 5823 // next app record if we are emulating process with anonymous threads. 5824 ProcessRecord app; 5825 if (pid != MY_PID && pid >= 0) { 5826 synchronized (mPidsSelfLocked) { 5827 app = mPidsSelfLocked.get(pid); 5828 } 5829 } else { 5830 app = null; 5831 } 5832 5833 if (app == null) { 5834 Slog.w(TAG, "No pending application record for pid " + pid 5835 + " (IApplicationThread " + thread + "); dropping process"); 5836 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5837 if (pid > 0 && pid != MY_PID) { 5838 Process.killProcessQuiet(pid); 5839 //TODO: Process.killProcessGroup(app.info.uid, pid); 5840 } else { 5841 try { 5842 thread.scheduleExit(); 5843 } catch (Exception e) { 5844 // Ignore exceptions. 5845 } 5846 } 5847 return false; 5848 } 5849 5850 // If this application record is still attached to a previous 5851 // process, clean it up now. 5852 if (app.thread != null) { 5853 handleAppDiedLocked(app, true, true); 5854 } 5855 5856 // Tell the process all about itself. 5857 5858 if (localLOGV) Slog.v( 5859 TAG, "Binding process pid " + pid + " to record " + app); 5860 5861 final String processName = app.processName; 5862 try { 5863 AppDeathRecipient adr = new AppDeathRecipient( 5864 app, pid, thread); 5865 thread.asBinder().linkToDeath(adr, 0); 5866 app.deathRecipient = adr; 5867 } catch (RemoteException e) { 5868 app.resetPackageList(mProcessStats); 5869 startProcessLocked(app, "link fail", processName); 5870 return false; 5871 } 5872 5873 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5874 5875 app.makeActive(thread, mProcessStats); 5876 app.curAdj = app.setAdj = -100; 5877 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5878 app.forcingToForeground = null; 5879 updateProcessForegroundLocked(app, false, false); 5880 app.hasShownUi = false; 5881 app.debugging = false; 5882 app.cached = false; 5883 app.killedByAm = false; 5884 5885 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5886 5887 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5888 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5889 5890 if (!normalMode) { 5891 Slog.i(TAG, "Launching preboot mode app: " + app); 5892 } 5893 5894 if (localLOGV) Slog.v( 5895 TAG, "New app record " + app 5896 + " thread=" + thread.asBinder() + " pid=" + pid); 5897 try { 5898 int testMode = IApplicationThread.DEBUG_OFF; 5899 if (mDebugApp != null && mDebugApp.equals(processName)) { 5900 testMode = mWaitForDebugger 5901 ? IApplicationThread.DEBUG_WAIT 5902 : IApplicationThread.DEBUG_ON; 5903 app.debugging = true; 5904 if (mDebugTransient) { 5905 mDebugApp = mOrigDebugApp; 5906 mWaitForDebugger = mOrigWaitForDebugger; 5907 } 5908 } 5909 String profileFile = app.instrumentationProfileFile; 5910 ParcelFileDescriptor profileFd = null; 5911 int samplingInterval = 0; 5912 boolean profileAutoStop = false; 5913 if (mProfileApp != null && mProfileApp.equals(processName)) { 5914 mProfileProc = app; 5915 profileFile = mProfileFile; 5916 profileFd = mProfileFd; 5917 samplingInterval = mSamplingInterval; 5918 profileAutoStop = mAutoStopProfiler; 5919 } 5920 boolean enableOpenGlTrace = false; 5921 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5922 enableOpenGlTrace = true; 5923 mOpenGlTraceApp = null; 5924 } 5925 5926 // If the app is being launched for restore or full backup, set it up specially 5927 boolean isRestrictedBackupMode = false; 5928 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5929 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5930 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5931 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5932 } 5933 5934 ensurePackageDexOpt(app.instrumentationInfo != null 5935 ? app.instrumentationInfo.packageName 5936 : app.info.packageName); 5937 if (app.instrumentationClass != null) { 5938 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5939 } 5940 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5941 + processName + " with config " + mConfiguration); 5942 ApplicationInfo appInfo = app.instrumentationInfo != null 5943 ? app.instrumentationInfo : app.info; 5944 app.compat = compatibilityInfoForPackageLocked(appInfo); 5945 if (profileFd != null) { 5946 profileFd = profileFd.dup(); 5947 } 5948 ProfilerInfo profilerInfo = profileFile == null ? null 5949 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5950 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5951 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5952 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5953 isRestrictedBackupMode || !normalMode, app.persistent, 5954 new Configuration(mConfiguration), app.compat, 5955 getCommonServicesLocked(app.isolated), 5956 mCoreSettingsObserver.getCoreSettingsLocked()); 5957 updateLruProcessLocked(app, false, null); 5958 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5959 } catch (Exception e) { 5960 // todo: Yikes! What should we do? For now we will try to 5961 // start another process, but that could easily get us in 5962 // an infinite loop of restarting processes... 5963 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5964 5965 app.resetPackageList(mProcessStats); 5966 app.unlinkDeathRecipient(); 5967 startProcessLocked(app, "bind fail", processName); 5968 return false; 5969 } 5970 5971 // Remove this record from the list of starting applications. 5972 mPersistentStartingProcesses.remove(app); 5973 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5974 "Attach application locked removing on hold: " + app); 5975 mProcessesOnHold.remove(app); 5976 5977 boolean badApp = false; 5978 boolean didSomething = false; 5979 5980 // See if the top visible activity is waiting to run in this process... 5981 if (normalMode) { 5982 try { 5983 if (mStackSupervisor.attachApplicationLocked(app)) { 5984 didSomething = true; 5985 } 5986 } catch (Exception e) { 5987 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5988 badApp = true; 5989 } 5990 } 5991 5992 // Find any services that should be running in this process... 5993 if (!badApp) { 5994 try { 5995 didSomething |= mServices.attachApplicationLocked(app, processName); 5996 } catch (Exception e) { 5997 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5998 badApp = true; 5999 } 6000 } 6001 6002 // Check if a next-broadcast receiver is in this process... 6003 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6004 try { 6005 didSomething |= sendPendingBroadcastsLocked(app); 6006 } catch (Exception e) { 6007 // If the app died trying to launch the receiver we declare it 'bad' 6008 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6009 badApp = true; 6010 } 6011 } 6012 6013 // Check whether the next backup agent is in this process... 6014 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6015 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6016 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6017 try { 6018 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6019 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6020 mBackupTarget.backupMode); 6021 } catch (Exception e) { 6022 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6023 badApp = true; 6024 } 6025 } 6026 6027 if (badApp) { 6028 app.kill("error during init", true); 6029 handleAppDiedLocked(app, false, true); 6030 return false; 6031 } 6032 6033 if (!didSomething) { 6034 updateOomAdjLocked(); 6035 } 6036 6037 return true; 6038 } 6039 6040 @Override 6041 public final void attachApplication(IApplicationThread thread) { 6042 synchronized (this) { 6043 int callingPid = Binder.getCallingPid(); 6044 final long origId = Binder.clearCallingIdentity(); 6045 attachApplicationLocked(thread, callingPid); 6046 Binder.restoreCallingIdentity(origId); 6047 } 6048 } 6049 6050 @Override 6051 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6052 final long origId = Binder.clearCallingIdentity(); 6053 synchronized (this) { 6054 ActivityStack stack = ActivityRecord.getStackLocked(token); 6055 if (stack != null) { 6056 ActivityRecord r = 6057 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6058 if (stopProfiling) { 6059 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6060 try { 6061 mProfileFd.close(); 6062 } catch (IOException e) { 6063 } 6064 clearProfilerLocked(); 6065 } 6066 } 6067 } 6068 } 6069 Binder.restoreCallingIdentity(origId); 6070 } 6071 6072 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6073 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6074 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6075 } 6076 6077 void enableScreenAfterBoot() { 6078 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6079 SystemClock.uptimeMillis()); 6080 mWindowManager.enableScreenAfterBoot(); 6081 6082 synchronized (this) { 6083 updateEventDispatchingLocked(); 6084 } 6085 } 6086 6087 @Override 6088 public void showBootMessage(final CharSequence msg, final boolean always) { 6089 enforceNotIsolatedCaller("showBootMessage"); 6090 mWindowManager.showBootMessage(msg, always); 6091 } 6092 6093 @Override 6094 public void keyguardWaitingForActivityDrawn() { 6095 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6096 final long token = Binder.clearCallingIdentity(); 6097 try { 6098 synchronized (this) { 6099 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6100 mWindowManager.keyguardWaitingForActivityDrawn(); 6101 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6102 mLockScreenShown = LOCK_SCREEN_LEAVING; 6103 updateSleepIfNeededLocked(); 6104 } 6105 } 6106 } finally { 6107 Binder.restoreCallingIdentity(token); 6108 } 6109 } 6110 6111 final void finishBooting() { 6112 synchronized (this) { 6113 if (!mBootAnimationComplete) { 6114 mCallFinishBooting = true; 6115 return; 6116 } 6117 mCallFinishBooting = false; 6118 } 6119 6120 ArraySet<String> completedIsas = new ArraySet<String>(); 6121 for (String abi : Build.SUPPORTED_ABIS) { 6122 Process.establishZygoteConnectionForAbi(abi); 6123 final String instructionSet = VMRuntime.getInstructionSet(abi); 6124 if (!completedIsas.contains(instructionSet)) { 6125 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6126 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6127 } 6128 completedIsas.add(instructionSet); 6129 } 6130 } 6131 6132 IntentFilter pkgFilter = new IntentFilter(); 6133 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6134 pkgFilter.addDataScheme("package"); 6135 mContext.registerReceiver(new BroadcastReceiver() { 6136 @Override 6137 public void onReceive(Context context, Intent intent) { 6138 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6139 if (pkgs != null) { 6140 for (String pkg : pkgs) { 6141 synchronized (ActivityManagerService.this) { 6142 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6143 0, "finished booting")) { 6144 setResultCode(Activity.RESULT_OK); 6145 return; 6146 } 6147 } 6148 } 6149 } 6150 } 6151 }, pkgFilter); 6152 6153 // Let system services know. 6154 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6155 6156 synchronized (this) { 6157 // Ensure that any processes we had put on hold are now started 6158 // up. 6159 final int NP = mProcessesOnHold.size(); 6160 if (NP > 0) { 6161 ArrayList<ProcessRecord> procs = 6162 new ArrayList<ProcessRecord>(mProcessesOnHold); 6163 for (int ip=0; ip<NP; ip++) { 6164 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6165 + procs.get(ip)); 6166 startProcessLocked(procs.get(ip), "on-hold", null); 6167 } 6168 } 6169 6170 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6171 // Start looking for apps that are abusing wake locks. 6172 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6173 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6174 // Tell anyone interested that we are done booting! 6175 SystemProperties.set("sys.boot_completed", "1"); 6176 6177 // And trigger dev.bootcomplete if we are not showing encryption progress 6178 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6179 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6180 SystemProperties.set("dev.bootcomplete", "1"); 6181 } 6182 for (int i=0; i<mStartedUsers.size(); i++) { 6183 UserStartedState uss = mStartedUsers.valueAt(i); 6184 if (uss.mState == UserStartedState.STATE_BOOTING) { 6185 uss.mState = UserStartedState.STATE_RUNNING; 6186 final int userId = mStartedUsers.keyAt(i); 6187 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6188 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6189 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6190 broadcastIntentLocked(null, null, intent, null, 6191 new IIntentReceiver.Stub() { 6192 @Override 6193 public void performReceive(Intent intent, int resultCode, 6194 String data, Bundle extras, boolean ordered, 6195 boolean sticky, int sendingUser) { 6196 synchronized (ActivityManagerService.this) { 6197 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6198 true, false); 6199 } 6200 } 6201 }, 6202 0, null, null, 6203 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6204 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6205 userId); 6206 } 6207 } 6208 scheduleStartProfilesLocked(); 6209 } 6210 } 6211 } 6212 6213 @Override 6214 public void bootAnimationComplete() { 6215 final boolean callFinishBooting; 6216 synchronized (this) { 6217 callFinishBooting = mCallFinishBooting; 6218 mBootAnimationComplete = true; 6219 } 6220 if (callFinishBooting) { 6221 finishBooting(); 6222 } 6223 } 6224 6225 final void ensureBootCompleted() { 6226 boolean booting; 6227 boolean enableScreen; 6228 synchronized (this) { 6229 booting = mBooting; 6230 mBooting = false; 6231 enableScreen = !mBooted; 6232 mBooted = true; 6233 } 6234 6235 if (booting) { 6236 finishBooting(); 6237 } 6238 6239 if (enableScreen) { 6240 enableScreenAfterBoot(); 6241 } 6242 } 6243 6244 @Override 6245 public final void activityResumed(IBinder token) { 6246 final long origId = Binder.clearCallingIdentity(); 6247 synchronized(this) { 6248 ActivityStack stack = ActivityRecord.getStackLocked(token); 6249 if (stack != null) { 6250 ActivityRecord.activityResumedLocked(token); 6251 } 6252 } 6253 Binder.restoreCallingIdentity(origId); 6254 } 6255 6256 @Override 6257 public final void activityPaused(IBinder token) { 6258 final long origId = Binder.clearCallingIdentity(); 6259 synchronized(this) { 6260 ActivityStack stack = ActivityRecord.getStackLocked(token); 6261 if (stack != null) { 6262 stack.activityPausedLocked(token, false); 6263 } 6264 } 6265 Binder.restoreCallingIdentity(origId); 6266 } 6267 6268 @Override 6269 public final void activityStopped(IBinder token, Bundle icicle, 6270 PersistableBundle persistentState, CharSequence description) { 6271 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6272 6273 // Refuse possible leaked file descriptors 6274 if (icicle != null && icicle.hasFileDescriptors()) { 6275 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6276 } 6277 6278 final long origId = Binder.clearCallingIdentity(); 6279 6280 synchronized (this) { 6281 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6282 if (r != null) { 6283 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6284 } 6285 } 6286 6287 trimApplications(); 6288 6289 Binder.restoreCallingIdentity(origId); 6290 } 6291 6292 @Override 6293 public final void activityDestroyed(IBinder token) { 6294 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6295 synchronized (this) { 6296 ActivityStack stack = ActivityRecord.getStackLocked(token); 6297 if (stack != null) { 6298 stack.activityDestroyedLocked(token); 6299 } 6300 } 6301 } 6302 6303 @Override 6304 public final void backgroundResourcesReleased(IBinder token) { 6305 final long origId = Binder.clearCallingIdentity(); 6306 try { 6307 synchronized (this) { 6308 ActivityStack stack = ActivityRecord.getStackLocked(token); 6309 if (stack != null) { 6310 stack.backgroundResourcesReleased(); 6311 } 6312 } 6313 } finally { 6314 Binder.restoreCallingIdentity(origId); 6315 } 6316 } 6317 6318 @Override 6319 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6320 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6321 } 6322 6323 @Override 6324 public final void notifyEnterAnimationComplete(IBinder token) { 6325 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6326 } 6327 6328 @Override 6329 public String getCallingPackage(IBinder token) { 6330 synchronized (this) { 6331 ActivityRecord r = getCallingRecordLocked(token); 6332 return r != null ? r.info.packageName : null; 6333 } 6334 } 6335 6336 @Override 6337 public ComponentName getCallingActivity(IBinder token) { 6338 synchronized (this) { 6339 ActivityRecord r = getCallingRecordLocked(token); 6340 return r != null ? r.intent.getComponent() : null; 6341 } 6342 } 6343 6344 private ActivityRecord getCallingRecordLocked(IBinder token) { 6345 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6346 if (r == null) { 6347 return null; 6348 } 6349 return r.resultTo; 6350 } 6351 6352 @Override 6353 public ComponentName getActivityClassForToken(IBinder token) { 6354 synchronized(this) { 6355 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6356 if (r == null) { 6357 return null; 6358 } 6359 return r.intent.getComponent(); 6360 } 6361 } 6362 6363 @Override 6364 public String getPackageForToken(IBinder token) { 6365 synchronized(this) { 6366 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6367 if (r == null) { 6368 return null; 6369 } 6370 return r.packageName; 6371 } 6372 } 6373 6374 @Override 6375 public IIntentSender getIntentSender(int type, 6376 String packageName, IBinder token, String resultWho, 6377 int requestCode, Intent[] intents, String[] resolvedTypes, 6378 int flags, Bundle options, int userId) { 6379 enforceNotIsolatedCaller("getIntentSender"); 6380 // Refuse possible leaked file descriptors 6381 if (intents != null) { 6382 if (intents.length < 1) { 6383 throw new IllegalArgumentException("Intents array length must be >= 1"); 6384 } 6385 for (int i=0; i<intents.length; i++) { 6386 Intent intent = intents[i]; 6387 if (intent != null) { 6388 if (intent.hasFileDescriptors()) { 6389 throw new IllegalArgumentException("File descriptors passed in Intent"); 6390 } 6391 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6392 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6393 throw new IllegalArgumentException( 6394 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6395 } 6396 intents[i] = new Intent(intent); 6397 } 6398 } 6399 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6400 throw new IllegalArgumentException( 6401 "Intent array length does not match resolvedTypes length"); 6402 } 6403 } 6404 if (options != null) { 6405 if (options.hasFileDescriptors()) { 6406 throw new IllegalArgumentException("File descriptors passed in options"); 6407 } 6408 } 6409 6410 synchronized(this) { 6411 int callingUid = Binder.getCallingUid(); 6412 int origUserId = userId; 6413 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6414 type == ActivityManager.INTENT_SENDER_BROADCAST, 6415 ALLOW_NON_FULL, "getIntentSender", null); 6416 if (origUserId == UserHandle.USER_CURRENT) { 6417 // We don't want to evaluate this until the pending intent is 6418 // actually executed. However, we do want to always do the 6419 // security checking for it above. 6420 userId = UserHandle.USER_CURRENT; 6421 } 6422 try { 6423 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6424 int uid = AppGlobals.getPackageManager() 6425 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6426 if (!UserHandle.isSameApp(callingUid, uid)) { 6427 String msg = "Permission Denial: getIntentSender() from pid=" 6428 + Binder.getCallingPid() 6429 + ", uid=" + Binder.getCallingUid() 6430 + ", (need uid=" + uid + ")" 6431 + " is not allowed to send as package " + packageName; 6432 Slog.w(TAG, msg); 6433 throw new SecurityException(msg); 6434 } 6435 } 6436 6437 return getIntentSenderLocked(type, packageName, callingUid, userId, 6438 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6439 6440 } catch (RemoteException e) { 6441 throw new SecurityException(e); 6442 } 6443 } 6444 } 6445 6446 IIntentSender getIntentSenderLocked(int type, String packageName, 6447 int callingUid, int userId, IBinder token, String resultWho, 6448 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6449 Bundle options) { 6450 if (DEBUG_MU) 6451 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6452 ActivityRecord activity = null; 6453 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6454 activity = ActivityRecord.isInStackLocked(token); 6455 if (activity == null) { 6456 return null; 6457 } 6458 if (activity.finishing) { 6459 return null; 6460 } 6461 } 6462 6463 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6464 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6465 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6466 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6467 |PendingIntent.FLAG_UPDATE_CURRENT); 6468 6469 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6470 type, packageName, activity, resultWho, 6471 requestCode, intents, resolvedTypes, flags, options, userId); 6472 WeakReference<PendingIntentRecord> ref; 6473 ref = mIntentSenderRecords.get(key); 6474 PendingIntentRecord rec = ref != null ? ref.get() : null; 6475 if (rec != null) { 6476 if (!cancelCurrent) { 6477 if (updateCurrent) { 6478 if (rec.key.requestIntent != null) { 6479 rec.key.requestIntent.replaceExtras(intents != null ? 6480 intents[intents.length - 1] : null); 6481 } 6482 if (intents != null) { 6483 intents[intents.length-1] = rec.key.requestIntent; 6484 rec.key.allIntents = intents; 6485 rec.key.allResolvedTypes = resolvedTypes; 6486 } else { 6487 rec.key.allIntents = null; 6488 rec.key.allResolvedTypes = null; 6489 } 6490 } 6491 return rec; 6492 } 6493 rec.canceled = true; 6494 mIntentSenderRecords.remove(key); 6495 } 6496 if (noCreate) { 6497 return rec; 6498 } 6499 rec = new PendingIntentRecord(this, key, callingUid); 6500 mIntentSenderRecords.put(key, rec.ref); 6501 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6502 if (activity.pendingResults == null) { 6503 activity.pendingResults 6504 = new HashSet<WeakReference<PendingIntentRecord>>(); 6505 } 6506 activity.pendingResults.add(rec.ref); 6507 } 6508 return rec; 6509 } 6510 6511 @Override 6512 public void cancelIntentSender(IIntentSender sender) { 6513 if (!(sender instanceof PendingIntentRecord)) { 6514 return; 6515 } 6516 synchronized(this) { 6517 PendingIntentRecord rec = (PendingIntentRecord)sender; 6518 try { 6519 int uid = AppGlobals.getPackageManager() 6520 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6521 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6522 String msg = "Permission Denial: cancelIntentSender() from pid=" 6523 + Binder.getCallingPid() 6524 + ", uid=" + Binder.getCallingUid() 6525 + " is not allowed to cancel packges " 6526 + rec.key.packageName; 6527 Slog.w(TAG, msg); 6528 throw new SecurityException(msg); 6529 } 6530 } catch (RemoteException e) { 6531 throw new SecurityException(e); 6532 } 6533 cancelIntentSenderLocked(rec, true); 6534 } 6535 } 6536 6537 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6538 rec.canceled = true; 6539 mIntentSenderRecords.remove(rec.key); 6540 if (cleanActivity && rec.key.activity != null) { 6541 rec.key.activity.pendingResults.remove(rec.ref); 6542 } 6543 } 6544 6545 @Override 6546 public String getPackageForIntentSender(IIntentSender pendingResult) { 6547 if (!(pendingResult instanceof PendingIntentRecord)) { 6548 return null; 6549 } 6550 try { 6551 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6552 return res.key.packageName; 6553 } catch (ClassCastException e) { 6554 } 6555 return null; 6556 } 6557 6558 @Override 6559 public int getUidForIntentSender(IIntentSender sender) { 6560 if (sender instanceof PendingIntentRecord) { 6561 try { 6562 PendingIntentRecord res = (PendingIntentRecord)sender; 6563 return res.uid; 6564 } catch (ClassCastException e) { 6565 } 6566 } 6567 return -1; 6568 } 6569 6570 @Override 6571 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6572 if (!(pendingResult instanceof PendingIntentRecord)) { 6573 return false; 6574 } 6575 try { 6576 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6577 if (res.key.allIntents == null) { 6578 return false; 6579 } 6580 for (int i=0; i<res.key.allIntents.length; i++) { 6581 Intent intent = res.key.allIntents[i]; 6582 if (intent.getPackage() != null && intent.getComponent() != null) { 6583 return false; 6584 } 6585 } 6586 return true; 6587 } catch (ClassCastException e) { 6588 } 6589 return false; 6590 } 6591 6592 @Override 6593 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6594 if (!(pendingResult instanceof PendingIntentRecord)) { 6595 return false; 6596 } 6597 try { 6598 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6599 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6600 return true; 6601 } 6602 return false; 6603 } catch (ClassCastException e) { 6604 } 6605 return false; 6606 } 6607 6608 @Override 6609 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6610 if (!(pendingResult instanceof PendingIntentRecord)) { 6611 return null; 6612 } 6613 try { 6614 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6615 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6616 } catch (ClassCastException e) { 6617 } 6618 return null; 6619 } 6620 6621 @Override 6622 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6623 if (!(pendingResult instanceof PendingIntentRecord)) { 6624 return null; 6625 } 6626 try { 6627 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6628 Intent intent = res.key.requestIntent; 6629 if (intent != null) { 6630 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6631 || res.lastTagPrefix.equals(prefix))) { 6632 return res.lastTag; 6633 } 6634 res.lastTagPrefix = prefix; 6635 StringBuilder sb = new StringBuilder(128); 6636 if (prefix != null) { 6637 sb.append(prefix); 6638 } 6639 if (intent.getAction() != null) { 6640 sb.append(intent.getAction()); 6641 } else if (intent.getComponent() != null) { 6642 intent.getComponent().appendShortString(sb); 6643 } else { 6644 sb.append("?"); 6645 } 6646 return res.lastTag = sb.toString(); 6647 } 6648 } catch (ClassCastException e) { 6649 } 6650 return null; 6651 } 6652 6653 @Override 6654 public void setProcessLimit(int max) { 6655 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6656 "setProcessLimit()"); 6657 synchronized (this) { 6658 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6659 mProcessLimitOverride = max; 6660 } 6661 trimApplications(); 6662 } 6663 6664 @Override 6665 public int getProcessLimit() { 6666 synchronized (this) { 6667 return mProcessLimitOverride; 6668 } 6669 } 6670 6671 void foregroundTokenDied(ForegroundToken token) { 6672 synchronized (ActivityManagerService.this) { 6673 synchronized (mPidsSelfLocked) { 6674 ForegroundToken cur 6675 = mForegroundProcesses.get(token.pid); 6676 if (cur != token) { 6677 return; 6678 } 6679 mForegroundProcesses.remove(token.pid); 6680 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6681 if (pr == null) { 6682 return; 6683 } 6684 pr.forcingToForeground = null; 6685 updateProcessForegroundLocked(pr, false, false); 6686 } 6687 updateOomAdjLocked(); 6688 } 6689 } 6690 6691 @Override 6692 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6693 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6694 "setProcessForeground()"); 6695 synchronized(this) { 6696 boolean changed = false; 6697 6698 synchronized (mPidsSelfLocked) { 6699 ProcessRecord pr = mPidsSelfLocked.get(pid); 6700 if (pr == null && isForeground) { 6701 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6702 return; 6703 } 6704 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6705 if (oldToken != null) { 6706 oldToken.token.unlinkToDeath(oldToken, 0); 6707 mForegroundProcesses.remove(pid); 6708 if (pr != null) { 6709 pr.forcingToForeground = null; 6710 } 6711 changed = true; 6712 } 6713 if (isForeground && token != null) { 6714 ForegroundToken newToken = new ForegroundToken() { 6715 @Override 6716 public void binderDied() { 6717 foregroundTokenDied(this); 6718 } 6719 }; 6720 newToken.pid = pid; 6721 newToken.token = token; 6722 try { 6723 token.linkToDeath(newToken, 0); 6724 mForegroundProcesses.put(pid, newToken); 6725 pr.forcingToForeground = token; 6726 changed = true; 6727 } catch (RemoteException e) { 6728 // If the process died while doing this, we will later 6729 // do the cleanup with the process death link. 6730 } 6731 } 6732 } 6733 6734 if (changed) { 6735 updateOomAdjLocked(); 6736 } 6737 } 6738 } 6739 6740 // ========================================================= 6741 // PERMISSIONS 6742 // ========================================================= 6743 6744 static class PermissionController extends IPermissionController.Stub { 6745 ActivityManagerService mActivityManagerService; 6746 PermissionController(ActivityManagerService activityManagerService) { 6747 mActivityManagerService = activityManagerService; 6748 } 6749 6750 @Override 6751 public boolean checkPermission(String permission, int pid, int uid) { 6752 return mActivityManagerService.checkPermission(permission, pid, 6753 uid) == PackageManager.PERMISSION_GRANTED; 6754 } 6755 } 6756 6757 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6758 @Override 6759 public int checkComponentPermission(String permission, int pid, int uid, 6760 int owningUid, boolean exported) { 6761 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6762 owningUid, exported); 6763 } 6764 6765 @Override 6766 public Object getAMSLock() { 6767 return ActivityManagerService.this; 6768 } 6769 } 6770 6771 /** 6772 * This can be called with or without the global lock held. 6773 */ 6774 int checkComponentPermission(String permission, int pid, int uid, 6775 int owningUid, boolean exported) { 6776 if (pid == MY_PID) { 6777 return PackageManager.PERMISSION_GRANTED; 6778 } 6779 return ActivityManager.checkComponentPermission(permission, uid, 6780 owningUid, exported); 6781 } 6782 6783 /** 6784 * As the only public entry point for permissions checking, this method 6785 * can enforce the semantic that requesting a check on a null global 6786 * permission is automatically denied. (Internally a null permission 6787 * string is used when calling {@link #checkComponentPermission} in cases 6788 * when only uid-based security is needed.) 6789 * 6790 * This can be called with or without the global lock held. 6791 */ 6792 @Override 6793 public int checkPermission(String permission, int pid, int uid) { 6794 if (permission == null) { 6795 return PackageManager.PERMISSION_DENIED; 6796 } 6797 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6798 } 6799 6800 @Override 6801 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6802 if (permission == null) { 6803 return PackageManager.PERMISSION_DENIED; 6804 } 6805 6806 // We might be performing an operation on behalf of an indirect binder 6807 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6808 // client identity accordingly before proceeding. 6809 Identity tlsIdentity = sCallerIdentity.get(); 6810 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6811 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6812 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6813 uid = tlsIdentity.uid; 6814 pid = tlsIdentity.pid; 6815 } 6816 6817 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6818 } 6819 6820 /** 6821 * Binder IPC calls go through the public entry point. 6822 * This can be called with or without the global lock held. 6823 */ 6824 int checkCallingPermission(String permission) { 6825 return checkPermission(permission, 6826 Binder.getCallingPid(), 6827 UserHandle.getAppId(Binder.getCallingUid())); 6828 } 6829 6830 /** 6831 * This can be called with or without the global lock held. 6832 */ 6833 void enforceCallingPermission(String permission, String func) { 6834 if (checkCallingPermission(permission) 6835 == PackageManager.PERMISSION_GRANTED) { 6836 return; 6837 } 6838 6839 String msg = "Permission Denial: " + func + " from pid=" 6840 + Binder.getCallingPid() 6841 + ", uid=" + Binder.getCallingUid() 6842 + " requires " + permission; 6843 Slog.w(TAG, msg); 6844 throw new SecurityException(msg); 6845 } 6846 6847 /** 6848 * Determine if UID is holding permissions required to access {@link Uri} in 6849 * the given {@link ProviderInfo}. Final permission checking is always done 6850 * in {@link ContentProvider}. 6851 */ 6852 private final boolean checkHoldingPermissionsLocked( 6853 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6854 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6855 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6856 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6857 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6858 != PERMISSION_GRANTED) { 6859 return false; 6860 } 6861 } 6862 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6863 } 6864 6865 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6866 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6867 if (pi.applicationInfo.uid == uid) { 6868 return true; 6869 } else if (!pi.exported) { 6870 return false; 6871 } 6872 6873 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6874 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6875 try { 6876 // check if target holds top-level <provider> permissions 6877 if (!readMet && pi.readPermission != null && considerUidPermissions 6878 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6879 readMet = true; 6880 } 6881 if (!writeMet && pi.writePermission != null && considerUidPermissions 6882 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6883 writeMet = true; 6884 } 6885 6886 // track if unprotected read/write is allowed; any denied 6887 // <path-permission> below removes this ability 6888 boolean allowDefaultRead = pi.readPermission == null; 6889 boolean allowDefaultWrite = pi.writePermission == null; 6890 6891 // check if target holds any <path-permission> that match uri 6892 final PathPermission[] pps = pi.pathPermissions; 6893 if (pps != null) { 6894 final String path = grantUri.uri.getPath(); 6895 int i = pps.length; 6896 while (i > 0 && (!readMet || !writeMet)) { 6897 i--; 6898 PathPermission pp = pps[i]; 6899 if (pp.match(path)) { 6900 if (!readMet) { 6901 final String pprperm = pp.getReadPermission(); 6902 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6903 + pprperm + " for " + pp.getPath() 6904 + ": match=" + pp.match(path) 6905 + " check=" + pm.checkUidPermission(pprperm, uid)); 6906 if (pprperm != null) { 6907 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6908 == PERMISSION_GRANTED) { 6909 readMet = true; 6910 } else { 6911 allowDefaultRead = false; 6912 } 6913 } 6914 } 6915 if (!writeMet) { 6916 final String ppwperm = pp.getWritePermission(); 6917 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6918 + ppwperm + " for " + pp.getPath() 6919 + ": match=" + pp.match(path) 6920 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6921 if (ppwperm != null) { 6922 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6923 == PERMISSION_GRANTED) { 6924 writeMet = true; 6925 } else { 6926 allowDefaultWrite = false; 6927 } 6928 } 6929 } 6930 } 6931 } 6932 } 6933 6934 // grant unprotected <provider> read/write, if not blocked by 6935 // <path-permission> above 6936 if (allowDefaultRead) readMet = true; 6937 if (allowDefaultWrite) writeMet = true; 6938 6939 } catch (RemoteException e) { 6940 return false; 6941 } 6942 6943 return readMet && writeMet; 6944 } 6945 6946 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6947 ProviderInfo pi = null; 6948 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6949 if (cpr != null) { 6950 pi = cpr.info; 6951 } else { 6952 try { 6953 pi = AppGlobals.getPackageManager().resolveContentProvider( 6954 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6955 } catch (RemoteException ex) { 6956 } 6957 } 6958 return pi; 6959 } 6960 6961 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6962 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6963 if (targetUris != null) { 6964 return targetUris.get(grantUri); 6965 } 6966 return null; 6967 } 6968 6969 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6970 String targetPkg, int targetUid, GrantUri grantUri) { 6971 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6972 if (targetUris == null) { 6973 targetUris = Maps.newArrayMap(); 6974 mGrantedUriPermissions.put(targetUid, targetUris); 6975 } 6976 6977 UriPermission perm = targetUris.get(grantUri); 6978 if (perm == null) { 6979 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6980 targetUris.put(grantUri, perm); 6981 } 6982 6983 return perm; 6984 } 6985 6986 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6987 final int modeFlags) { 6988 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6989 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6990 : UriPermission.STRENGTH_OWNED; 6991 6992 // Root gets to do everything. 6993 if (uid == 0) { 6994 return true; 6995 } 6996 6997 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6998 if (perms == null) return false; 6999 7000 // First look for exact match 7001 final UriPermission exactPerm = perms.get(grantUri); 7002 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7003 return true; 7004 } 7005 7006 // No exact match, look for prefixes 7007 final int N = perms.size(); 7008 for (int i = 0; i < N; i++) { 7009 final UriPermission perm = perms.valueAt(i); 7010 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7011 && perm.getStrength(modeFlags) >= minStrength) { 7012 return true; 7013 } 7014 } 7015 7016 return false; 7017 } 7018 7019 /** 7020 * @param uri This uri must NOT contain an embedded userId. 7021 * @param userId The userId in which the uri is to be resolved. 7022 */ 7023 @Override 7024 public int checkUriPermission(Uri uri, int pid, int uid, 7025 final int modeFlags, int userId, IBinder callerToken) { 7026 enforceNotIsolatedCaller("checkUriPermission"); 7027 7028 // Another redirected-binder-call permissions check as in 7029 // {@link checkPermissionWithToken}. 7030 Identity tlsIdentity = sCallerIdentity.get(); 7031 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7032 uid = tlsIdentity.uid; 7033 pid = tlsIdentity.pid; 7034 } 7035 7036 // Our own process gets to do everything. 7037 if (pid == MY_PID) { 7038 return PackageManager.PERMISSION_GRANTED; 7039 } 7040 synchronized (this) { 7041 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7042 ? PackageManager.PERMISSION_GRANTED 7043 : PackageManager.PERMISSION_DENIED; 7044 } 7045 } 7046 7047 /** 7048 * Check if the targetPkg can be granted permission to access uri by 7049 * the callingUid using the given modeFlags. Throws a security exception 7050 * if callingUid is not allowed to do this. Returns the uid of the target 7051 * if the URI permission grant should be performed; returns -1 if it is not 7052 * needed (for example targetPkg already has permission to access the URI). 7053 * If you already know the uid of the target, you can supply it in 7054 * lastTargetUid else set that to -1. 7055 */ 7056 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7057 final int modeFlags, int lastTargetUid) { 7058 if (!Intent.isAccessUriMode(modeFlags)) { 7059 return -1; 7060 } 7061 7062 if (targetPkg != null) { 7063 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7064 "Checking grant " + targetPkg + " permission to " + grantUri); 7065 } 7066 7067 final IPackageManager pm = AppGlobals.getPackageManager(); 7068 7069 // If this is not a content: uri, we can't do anything with it. 7070 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7071 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7072 "Can't grant URI permission for non-content URI: " + grantUri); 7073 return -1; 7074 } 7075 7076 final String authority = grantUri.uri.getAuthority(); 7077 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7078 if (pi == null) { 7079 Slog.w(TAG, "No content provider found for permission check: " + 7080 grantUri.uri.toSafeString()); 7081 return -1; 7082 } 7083 7084 int targetUid = lastTargetUid; 7085 if (targetUid < 0 && targetPkg != null) { 7086 try { 7087 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7088 if (targetUid < 0) { 7089 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7090 "Can't grant URI permission no uid for: " + targetPkg); 7091 return -1; 7092 } 7093 } catch (RemoteException ex) { 7094 return -1; 7095 } 7096 } 7097 7098 if (targetUid >= 0) { 7099 // First... does the target actually need this permission? 7100 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7101 // No need to grant the target this permission. 7102 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7103 "Target " + targetPkg + " already has full permission to " + grantUri); 7104 return -1; 7105 } 7106 } else { 7107 // First... there is no target package, so can anyone access it? 7108 boolean allowed = pi.exported; 7109 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7110 if (pi.readPermission != null) { 7111 allowed = false; 7112 } 7113 } 7114 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7115 if (pi.writePermission != null) { 7116 allowed = false; 7117 } 7118 } 7119 if (allowed) { 7120 return -1; 7121 } 7122 } 7123 7124 /* There is a special cross user grant if: 7125 * - The target is on another user. 7126 * - Apps on the current user can access the uri without any uid permissions. 7127 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7128 * grant uri permissions. 7129 */ 7130 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7131 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7132 modeFlags, false /*without considering the uid permissions*/); 7133 7134 // Second... is the provider allowing granting of URI permissions? 7135 if (!specialCrossUserGrant) { 7136 if (!pi.grantUriPermissions) { 7137 throw new SecurityException("Provider " + pi.packageName 7138 + "/" + pi.name 7139 + " does not allow granting of Uri permissions (uri " 7140 + grantUri + ")"); 7141 } 7142 if (pi.uriPermissionPatterns != null) { 7143 final int N = pi.uriPermissionPatterns.length; 7144 boolean allowed = false; 7145 for (int i=0; i<N; i++) { 7146 if (pi.uriPermissionPatterns[i] != null 7147 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7148 allowed = true; 7149 break; 7150 } 7151 } 7152 if (!allowed) { 7153 throw new SecurityException("Provider " + pi.packageName 7154 + "/" + pi.name 7155 + " does not allow granting of permission to path of Uri " 7156 + grantUri); 7157 } 7158 } 7159 } 7160 7161 // Third... does the caller itself have permission to access 7162 // this uri? 7163 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7164 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7165 // Require they hold a strong enough Uri permission 7166 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7167 throw new SecurityException("Uid " + callingUid 7168 + " does not have permission to uri " + grantUri); 7169 } 7170 } 7171 } 7172 return targetUid; 7173 } 7174 7175 /** 7176 * @param uri This uri must NOT contain an embedded userId. 7177 * @param userId The userId in which the uri is to be resolved. 7178 */ 7179 @Override 7180 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7181 final int modeFlags, int userId) { 7182 enforceNotIsolatedCaller("checkGrantUriPermission"); 7183 synchronized(this) { 7184 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7185 new GrantUri(userId, uri, false), modeFlags, -1); 7186 } 7187 } 7188 7189 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7190 final int modeFlags, UriPermissionOwner owner) { 7191 if (!Intent.isAccessUriMode(modeFlags)) { 7192 return; 7193 } 7194 7195 // So here we are: the caller has the assumed permission 7196 // to the uri, and the target doesn't. Let's now give this to 7197 // the target. 7198 7199 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7200 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7201 7202 final String authority = grantUri.uri.getAuthority(); 7203 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7204 if (pi == null) { 7205 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7206 return; 7207 } 7208 7209 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7210 grantUri.prefix = true; 7211 } 7212 final UriPermission perm = findOrCreateUriPermissionLocked( 7213 pi.packageName, targetPkg, targetUid, grantUri); 7214 perm.grantModes(modeFlags, owner); 7215 } 7216 7217 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7218 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7219 if (targetPkg == null) { 7220 throw new NullPointerException("targetPkg"); 7221 } 7222 int targetUid; 7223 final IPackageManager pm = AppGlobals.getPackageManager(); 7224 try { 7225 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7226 } catch (RemoteException ex) { 7227 return; 7228 } 7229 7230 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7231 targetUid); 7232 if (targetUid < 0) { 7233 return; 7234 } 7235 7236 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7237 owner); 7238 } 7239 7240 static class NeededUriGrants extends ArrayList<GrantUri> { 7241 final String targetPkg; 7242 final int targetUid; 7243 final int flags; 7244 7245 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7246 this.targetPkg = targetPkg; 7247 this.targetUid = targetUid; 7248 this.flags = flags; 7249 } 7250 } 7251 7252 /** 7253 * Like checkGrantUriPermissionLocked, but takes an Intent. 7254 */ 7255 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7256 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7257 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7258 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7259 + " clip=" + (intent != null ? intent.getClipData() : null) 7260 + " from " + intent + "; flags=0x" 7261 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7262 7263 if (targetPkg == null) { 7264 throw new NullPointerException("targetPkg"); 7265 } 7266 7267 if (intent == null) { 7268 return null; 7269 } 7270 Uri data = intent.getData(); 7271 ClipData clip = intent.getClipData(); 7272 if (data == null && clip == null) { 7273 return null; 7274 } 7275 // Default userId for uris in the intent (if they don't specify it themselves) 7276 int contentUserHint = intent.getContentUserHint(); 7277 if (contentUserHint == UserHandle.USER_CURRENT) { 7278 contentUserHint = UserHandle.getUserId(callingUid); 7279 } 7280 final IPackageManager pm = AppGlobals.getPackageManager(); 7281 int targetUid; 7282 if (needed != null) { 7283 targetUid = needed.targetUid; 7284 } else { 7285 try { 7286 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7287 } catch (RemoteException ex) { 7288 return null; 7289 } 7290 if (targetUid < 0) { 7291 if (DEBUG_URI_PERMISSION) { 7292 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7293 + " on user " + targetUserId); 7294 } 7295 return null; 7296 } 7297 } 7298 if (data != null) { 7299 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7300 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7301 targetUid); 7302 if (targetUid > 0) { 7303 if (needed == null) { 7304 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7305 } 7306 needed.add(grantUri); 7307 } 7308 } 7309 if (clip != null) { 7310 for (int i=0; i<clip.getItemCount(); i++) { 7311 Uri uri = clip.getItemAt(i).getUri(); 7312 if (uri != null) { 7313 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7314 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7315 targetUid); 7316 if (targetUid > 0) { 7317 if (needed == null) { 7318 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7319 } 7320 needed.add(grantUri); 7321 } 7322 } else { 7323 Intent clipIntent = clip.getItemAt(i).getIntent(); 7324 if (clipIntent != null) { 7325 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7326 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7327 if (newNeeded != null) { 7328 needed = newNeeded; 7329 } 7330 } 7331 } 7332 } 7333 } 7334 7335 return needed; 7336 } 7337 7338 /** 7339 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7340 */ 7341 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7342 UriPermissionOwner owner) { 7343 if (needed != null) { 7344 for (int i=0; i<needed.size(); i++) { 7345 GrantUri grantUri = needed.get(i); 7346 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7347 grantUri, needed.flags, owner); 7348 } 7349 } 7350 } 7351 7352 void grantUriPermissionFromIntentLocked(int callingUid, 7353 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7354 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7355 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7356 if (needed == null) { 7357 return; 7358 } 7359 7360 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7361 } 7362 7363 /** 7364 * @param uri This uri must NOT contain an embedded userId. 7365 * @param userId The userId in which the uri is to be resolved. 7366 */ 7367 @Override 7368 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7369 final int modeFlags, int userId) { 7370 enforceNotIsolatedCaller("grantUriPermission"); 7371 GrantUri grantUri = new GrantUri(userId, uri, false); 7372 synchronized(this) { 7373 final ProcessRecord r = getRecordForAppLocked(caller); 7374 if (r == null) { 7375 throw new SecurityException("Unable to find app for caller " 7376 + caller 7377 + " when granting permission to uri " + grantUri); 7378 } 7379 if (targetPkg == null) { 7380 throw new IllegalArgumentException("null target"); 7381 } 7382 if (grantUri == null) { 7383 throw new IllegalArgumentException("null uri"); 7384 } 7385 7386 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7387 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7388 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7389 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7390 7391 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7392 UserHandle.getUserId(r.uid)); 7393 } 7394 } 7395 7396 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7397 if (perm.modeFlags == 0) { 7398 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7399 perm.targetUid); 7400 if (perms != null) { 7401 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7402 "Removing " + perm.targetUid + " permission to " + perm.uri); 7403 7404 perms.remove(perm.uri); 7405 if (perms.isEmpty()) { 7406 mGrantedUriPermissions.remove(perm.targetUid); 7407 } 7408 } 7409 } 7410 } 7411 7412 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7413 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7414 7415 final IPackageManager pm = AppGlobals.getPackageManager(); 7416 final String authority = grantUri.uri.getAuthority(); 7417 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7418 if (pi == null) { 7419 Slog.w(TAG, "No content provider found for permission revoke: " 7420 + grantUri.toSafeString()); 7421 return; 7422 } 7423 7424 // Does the caller have this permission on the URI? 7425 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7426 // If they don't have direct access to the URI, then revoke any 7427 // ownerless URI permissions that have been granted to them. 7428 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7429 if (perms != null) { 7430 boolean persistChanged = false; 7431 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7432 final UriPermission perm = it.next(); 7433 if (perm.uri.sourceUserId == grantUri.sourceUserId 7434 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7435 if (DEBUG_URI_PERMISSION) 7436 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7437 " permission to " + perm.uri); 7438 persistChanged |= perm.revokeModes( 7439 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7440 if (perm.modeFlags == 0) { 7441 it.remove(); 7442 } 7443 } 7444 } 7445 if (perms.isEmpty()) { 7446 mGrantedUriPermissions.remove(callingUid); 7447 } 7448 if (persistChanged) { 7449 schedulePersistUriGrants(); 7450 } 7451 } 7452 return; 7453 } 7454 7455 boolean persistChanged = false; 7456 7457 // Go through all of the permissions and remove any that match. 7458 int N = mGrantedUriPermissions.size(); 7459 for (int i = 0; i < N; i++) { 7460 final int targetUid = mGrantedUriPermissions.keyAt(i); 7461 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7462 7463 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7464 final UriPermission perm = it.next(); 7465 if (perm.uri.sourceUserId == grantUri.sourceUserId 7466 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7467 if (DEBUG_URI_PERMISSION) 7468 Slog.v(TAG, 7469 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7470 persistChanged |= perm.revokeModes( 7471 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7472 if (perm.modeFlags == 0) { 7473 it.remove(); 7474 } 7475 } 7476 } 7477 7478 if (perms.isEmpty()) { 7479 mGrantedUriPermissions.remove(targetUid); 7480 N--; 7481 i--; 7482 } 7483 } 7484 7485 if (persistChanged) { 7486 schedulePersistUriGrants(); 7487 } 7488 } 7489 7490 /** 7491 * @param uri This uri must NOT contain an embedded userId. 7492 * @param userId The userId in which the uri is to be resolved. 7493 */ 7494 @Override 7495 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7496 int userId) { 7497 enforceNotIsolatedCaller("revokeUriPermission"); 7498 synchronized(this) { 7499 final ProcessRecord r = getRecordForAppLocked(caller); 7500 if (r == null) { 7501 throw new SecurityException("Unable to find app for caller " 7502 + caller 7503 + " when revoking permission to uri " + uri); 7504 } 7505 if (uri == null) { 7506 Slog.w(TAG, "revokeUriPermission: null uri"); 7507 return; 7508 } 7509 7510 if (!Intent.isAccessUriMode(modeFlags)) { 7511 return; 7512 } 7513 7514 final IPackageManager pm = AppGlobals.getPackageManager(); 7515 final String authority = uri.getAuthority(); 7516 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7517 if (pi == null) { 7518 Slog.w(TAG, "No content provider found for permission revoke: " 7519 + uri.toSafeString()); 7520 return; 7521 } 7522 7523 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7524 } 7525 } 7526 7527 /** 7528 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7529 * given package. 7530 * 7531 * @param packageName Package name to match, or {@code null} to apply to all 7532 * packages. 7533 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7534 * to all users. 7535 * @param persistable If persistable grants should be removed. 7536 */ 7537 private void removeUriPermissionsForPackageLocked( 7538 String packageName, int userHandle, boolean persistable) { 7539 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7540 throw new IllegalArgumentException("Must narrow by either package or user"); 7541 } 7542 7543 boolean persistChanged = false; 7544 7545 int N = mGrantedUriPermissions.size(); 7546 for (int i = 0; i < N; i++) { 7547 final int targetUid = mGrantedUriPermissions.keyAt(i); 7548 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7549 7550 // Only inspect grants matching user 7551 if (userHandle == UserHandle.USER_ALL 7552 || userHandle == UserHandle.getUserId(targetUid)) { 7553 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7554 final UriPermission perm = it.next(); 7555 7556 // Only inspect grants matching package 7557 if (packageName == null || perm.sourcePkg.equals(packageName) 7558 || perm.targetPkg.equals(packageName)) { 7559 persistChanged |= perm.revokeModes(persistable 7560 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7561 7562 // Only remove when no modes remain; any persisted grants 7563 // will keep this alive. 7564 if (perm.modeFlags == 0) { 7565 it.remove(); 7566 } 7567 } 7568 } 7569 7570 if (perms.isEmpty()) { 7571 mGrantedUriPermissions.remove(targetUid); 7572 N--; 7573 i--; 7574 } 7575 } 7576 } 7577 7578 if (persistChanged) { 7579 schedulePersistUriGrants(); 7580 } 7581 } 7582 7583 @Override 7584 public IBinder newUriPermissionOwner(String name) { 7585 enforceNotIsolatedCaller("newUriPermissionOwner"); 7586 synchronized(this) { 7587 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7588 return owner.getExternalTokenLocked(); 7589 } 7590 } 7591 7592 /** 7593 * @param uri This uri must NOT contain an embedded userId. 7594 * @param sourceUserId The userId in which the uri is to be resolved. 7595 * @param targetUserId The userId of the app that receives the grant. 7596 */ 7597 @Override 7598 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7599 final int modeFlags, int sourceUserId, int targetUserId) { 7600 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7601 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7602 synchronized(this) { 7603 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7604 if (owner == null) { 7605 throw new IllegalArgumentException("Unknown owner: " + token); 7606 } 7607 if (fromUid != Binder.getCallingUid()) { 7608 if (Binder.getCallingUid() != Process.myUid()) { 7609 // Only system code can grant URI permissions on behalf 7610 // of other users. 7611 throw new SecurityException("nice try"); 7612 } 7613 } 7614 if (targetPkg == null) { 7615 throw new IllegalArgumentException("null target"); 7616 } 7617 if (uri == null) { 7618 throw new IllegalArgumentException("null uri"); 7619 } 7620 7621 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7622 modeFlags, owner, targetUserId); 7623 } 7624 } 7625 7626 /** 7627 * @param uri This uri must NOT contain an embedded userId. 7628 * @param userId The userId in which the uri is to be resolved. 7629 */ 7630 @Override 7631 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7632 synchronized(this) { 7633 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7634 if (owner == null) { 7635 throw new IllegalArgumentException("Unknown owner: " + token); 7636 } 7637 7638 if (uri == null) { 7639 owner.removeUriPermissionsLocked(mode); 7640 } else { 7641 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7642 } 7643 } 7644 } 7645 7646 private void schedulePersistUriGrants() { 7647 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7648 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7649 10 * DateUtils.SECOND_IN_MILLIS); 7650 } 7651 } 7652 7653 private void writeGrantedUriPermissions() { 7654 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7655 7656 // Snapshot permissions so we can persist without lock 7657 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7658 synchronized (this) { 7659 final int size = mGrantedUriPermissions.size(); 7660 for (int i = 0; i < size; i++) { 7661 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7662 for (UriPermission perm : perms.values()) { 7663 if (perm.persistedModeFlags != 0) { 7664 persist.add(perm.snapshot()); 7665 } 7666 } 7667 } 7668 } 7669 7670 FileOutputStream fos = null; 7671 try { 7672 fos = mGrantFile.startWrite(); 7673 7674 XmlSerializer out = new FastXmlSerializer(); 7675 out.setOutput(fos, "utf-8"); 7676 out.startDocument(null, true); 7677 out.startTag(null, TAG_URI_GRANTS); 7678 for (UriPermission.Snapshot perm : persist) { 7679 out.startTag(null, TAG_URI_GRANT); 7680 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7681 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7682 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7683 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7684 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7685 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7686 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7687 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7688 out.endTag(null, TAG_URI_GRANT); 7689 } 7690 out.endTag(null, TAG_URI_GRANTS); 7691 out.endDocument(); 7692 7693 mGrantFile.finishWrite(fos); 7694 } catch (IOException e) { 7695 if (fos != null) { 7696 mGrantFile.failWrite(fos); 7697 } 7698 } 7699 } 7700 7701 private void readGrantedUriPermissionsLocked() { 7702 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7703 7704 final long now = System.currentTimeMillis(); 7705 7706 FileInputStream fis = null; 7707 try { 7708 fis = mGrantFile.openRead(); 7709 final XmlPullParser in = Xml.newPullParser(); 7710 in.setInput(fis, null); 7711 7712 int type; 7713 while ((type = in.next()) != END_DOCUMENT) { 7714 final String tag = in.getName(); 7715 if (type == START_TAG) { 7716 if (TAG_URI_GRANT.equals(tag)) { 7717 final int sourceUserId; 7718 final int targetUserId; 7719 final int userHandle = readIntAttribute(in, 7720 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7721 if (userHandle != UserHandle.USER_NULL) { 7722 // For backwards compatibility. 7723 sourceUserId = userHandle; 7724 targetUserId = userHandle; 7725 } else { 7726 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7727 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7728 } 7729 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7730 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7731 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7732 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7733 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7734 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7735 7736 // Sanity check that provider still belongs to source package 7737 final ProviderInfo pi = getProviderInfoLocked( 7738 uri.getAuthority(), sourceUserId); 7739 if (pi != null && sourcePkg.equals(pi.packageName)) { 7740 int targetUid = -1; 7741 try { 7742 targetUid = AppGlobals.getPackageManager() 7743 .getPackageUid(targetPkg, targetUserId); 7744 } catch (RemoteException e) { 7745 } 7746 if (targetUid != -1) { 7747 final UriPermission perm = findOrCreateUriPermissionLocked( 7748 sourcePkg, targetPkg, targetUid, 7749 new GrantUri(sourceUserId, uri, prefix)); 7750 perm.initPersistedModes(modeFlags, createdTime); 7751 } 7752 } else { 7753 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7754 + " but instead found " + pi); 7755 } 7756 } 7757 } 7758 } 7759 } catch (FileNotFoundException e) { 7760 // Missing grants is okay 7761 } catch (IOException e) { 7762 Slog.wtf(TAG, "Failed reading Uri grants", e); 7763 } catch (XmlPullParserException e) { 7764 Slog.wtf(TAG, "Failed reading Uri grants", e); 7765 } finally { 7766 IoUtils.closeQuietly(fis); 7767 } 7768 } 7769 7770 /** 7771 * @param uri This uri must NOT contain an embedded userId. 7772 * @param userId The userId in which the uri is to be resolved. 7773 */ 7774 @Override 7775 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7776 enforceNotIsolatedCaller("takePersistableUriPermission"); 7777 7778 Preconditions.checkFlagsArgument(modeFlags, 7779 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7780 7781 synchronized (this) { 7782 final int callingUid = Binder.getCallingUid(); 7783 boolean persistChanged = false; 7784 GrantUri grantUri = new GrantUri(userId, uri, false); 7785 7786 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7787 new GrantUri(userId, uri, false)); 7788 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7789 new GrantUri(userId, uri, true)); 7790 7791 final boolean exactValid = (exactPerm != null) 7792 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7793 final boolean prefixValid = (prefixPerm != null) 7794 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7795 7796 if (!(exactValid || prefixValid)) { 7797 throw new SecurityException("No persistable permission grants found for UID " 7798 + callingUid + " and Uri " + grantUri.toSafeString()); 7799 } 7800 7801 if (exactValid) { 7802 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7803 } 7804 if (prefixValid) { 7805 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7806 } 7807 7808 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7809 7810 if (persistChanged) { 7811 schedulePersistUriGrants(); 7812 } 7813 } 7814 } 7815 7816 /** 7817 * @param uri This uri must NOT contain an embedded userId. 7818 * @param userId The userId in which the uri is to be resolved. 7819 */ 7820 @Override 7821 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7822 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7823 7824 Preconditions.checkFlagsArgument(modeFlags, 7825 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7826 7827 synchronized (this) { 7828 final int callingUid = Binder.getCallingUid(); 7829 boolean persistChanged = false; 7830 7831 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7832 new GrantUri(userId, uri, false)); 7833 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7834 new GrantUri(userId, uri, true)); 7835 if (exactPerm == null && prefixPerm == null) { 7836 throw new SecurityException("No permission grants found for UID " + callingUid 7837 + " and Uri " + uri.toSafeString()); 7838 } 7839 7840 if (exactPerm != null) { 7841 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7842 removeUriPermissionIfNeededLocked(exactPerm); 7843 } 7844 if (prefixPerm != null) { 7845 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7846 removeUriPermissionIfNeededLocked(prefixPerm); 7847 } 7848 7849 if (persistChanged) { 7850 schedulePersistUriGrants(); 7851 } 7852 } 7853 } 7854 7855 /** 7856 * Prune any older {@link UriPermission} for the given UID until outstanding 7857 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7858 * 7859 * @return if any mutations occured that require persisting. 7860 */ 7861 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7862 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7863 if (perms == null) return false; 7864 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7865 7866 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7867 for (UriPermission perm : perms.values()) { 7868 if (perm.persistedModeFlags != 0) { 7869 persisted.add(perm); 7870 } 7871 } 7872 7873 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7874 if (trimCount <= 0) return false; 7875 7876 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7877 for (int i = 0; i < trimCount; i++) { 7878 final UriPermission perm = persisted.get(i); 7879 7880 if (DEBUG_URI_PERMISSION) { 7881 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7882 } 7883 7884 perm.releasePersistableModes(~0); 7885 removeUriPermissionIfNeededLocked(perm); 7886 } 7887 7888 return true; 7889 } 7890 7891 @Override 7892 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7893 String packageName, boolean incoming) { 7894 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7895 Preconditions.checkNotNull(packageName, "packageName"); 7896 7897 final int callingUid = Binder.getCallingUid(); 7898 final IPackageManager pm = AppGlobals.getPackageManager(); 7899 try { 7900 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7901 if (packageUid != callingUid) { 7902 throw new SecurityException( 7903 "Package " + packageName + " does not belong to calling UID " + callingUid); 7904 } 7905 } catch (RemoteException e) { 7906 throw new SecurityException("Failed to verify package name ownership"); 7907 } 7908 7909 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7910 synchronized (this) { 7911 if (incoming) { 7912 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7913 callingUid); 7914 if (perms == null) { 7915 Slog.w(TAG, "No permission grants found for " + packageName); 7916 } else { 7917 for (UriPermission perm : perms.values()) { 7918 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7919 result.add(perm.buildPersistedPublicApiObject()); 7920 } 7921 } 7922 } 7923 } else { 7924 final int size = mGrantedUriPermissions.size(); 7925 for (int i = 0; i < size; i++) { 7926 final ArrayMap<GrantUri, UriPermission> perms = 7927 mGrantedUriPermissions.valueAt(i); 7928 for (UriPermission perm : perms.values()) { 7929 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7930 result.add(perm.buildPersistedPublicApiObject()); 7931 } 7932 } 7933 } 7934 } 7935 } 7936 return new ParceledListSlice<android.content.UriPermission>(result); 7937 } 7938 7939 @Override 7940 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7941 synchronized (this) { 7942 ProcessRecord app = 7943 who != null ? getRecordForAppLocked(who) : null; 7944 if (app == null) return; 7945 7946 Message msg = Message.obtain(); 7947 msg.what = WAIT_FOR_DEBUGGER_MSG; 7948 msg.obj = app; 7949 msg.arg1 = waiting ? 1 : 0; 7950 mHandler.sendMessage(msg); 7951 } 7952 } 7953 7954 @Override 7955 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7956 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7957 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7958 outInfo.availMem = Process.getFreeMemory(); 7959 outInfo.totalMem = Process.getTotalMemory(); 7960 outInfo.threshold = homeAppMem; 7961 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7962 outInfo.hiddenAppThreshold = cachedAppMem; 7963 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7964 ProcessList.SERVICE_ADJ); 7965 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7966 ProcessList.VISIBLE_APP_ADJ); 7967 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7968 ProcessList.FOREGROUND_APP_ADJ); 7969 } 7970 7971 // ========================================================= 7972 // TASK MANAGEMENT 7973 // ========================================================= 7974 7975 @Override 7976 public List<IAppTask> getAppTasks(String callingPackage) { 7977 int callingUid = Binder.getCallingUid(); 7978 long ident = Binder.clearCallingIdentity(); 7979 7980 synchronized(this) { 7981 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7982 try { 7983 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7984 7985 final int N = mRecentTasks.size(); 7986 for (int i = 0; i < N; i++) { 7987 TaskRecord tr = mRecentTasks.get(i); 7988 // Skip tasks that do not match the caller. We don't need to verify 7989 // callingPackage, because we are also limiting to callingUid and know 7990 // that will limit to the correct security sandbox. 7991 if (tr.effectiveUid != callingUid) { 7992 continue; 7993 } 7994 Intent intent = tr.getBaseIntent(); 7995 if (intent == null || 7996 !callingPackage.equals(intent.getComponent().getPackageName())) { 7997 continue; 7998 } 7999 ActivityManager.RecentTaskInfo taskInfo = 8000 createRecentTaskInfoFromTaskRecord(tr); 8001 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8002 list.add(taskImpl); 8003 } 8004 } finally { 8005 Binder.restoreCallingIdentity(ident); 8006 } 8007 return list; 8008 } 8009 } 8010 8011 @Override 8012 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8013 final int callingUid = Binder.getCallingUid(); 8014 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8015 8016 synchronized(this) { 8017 if (localLOGV) Slog.v( 8018 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8019 8020 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8021 callingUid); 8022 8023 // TODO: Improve with MRU list from all ActivityStacks. 8024 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8025 } 8026 8027 return list; 8028 } 8029 8030 /** 8031 * Creates a new RecentTaskInfo from a TaskRecord. 8032 */ 8033 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8034 // Update the task description to reflect any changes in the task stack 8035 tr.updateTaskDescription(); 8036 8037 // Compose the recent task info 8038 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8039 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8040 rti.persistentId = tr.taskId; 8041 rti.baseIntent = new Intent(tr.getBaseIntent()); 8042 rti.origActivity = tr.origActivity; 8043 rti.description = tr.lastDescription; 8044 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8045 rti.userId = tr.userId; 8046 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8047 rti.firstActiveTime = tr.firstActiveTime; 8048 rti.lastActiveTime = tr.lastActiveTime; 8049 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8050 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8051 return rti; 8052 } 8053 8054 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8055 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8056 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8057 if (!allowed) { 8058 if (checkPermission(android.Manifest.permission.GET_TASKS, 8059 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8060 // Temporary compatibility: some existing apps on the system image may 8061 // still be requesting the old permission and not switched to the new 8062 // one; if so, we'll still allow them full access. This means we need 8063 // to see if they are holding the old permission and are a system app. 8064 try { 8065 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8066 allowed = true; 8067 Slog.w(TAG, caller + ": caller " + callingUid 8068 + " is using old GET_TASKS but privileged; allowing"); 8069 } 8070 } catch (RemoteException e) { 8071 } 8072 } 8073 } 8074 if (!allowed) { 8075 Slog.w(TAG, caller + ": caller " + callingUid 8076 + " does not hold GET_TASKS; limiting output"); 8077 } 8078 return allowed; 8079 } 8080 8081 @Override 8082 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8083 final int callingUid = Binder.getCallingUid(); 8084 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8085 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8086 8087 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8088 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8089 synchronized (this) { 8090 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8091 callingUid); 8092 final boolean detailed = checkCallingPermission( 8093 android.Manifest.permission.GET_DETAILED_TASKS) 8094 == PackageManager.PERMISSION_GRANTED; 8095 8096 final int N = mRecentTasks.size(); 8097 ArrayList<ActivityManager.RecentTaskInfo> res 8098 = new ArrayList<ActivityManager.RecentTaskInfo>( 8099 maxNum < N ? maxNum : N); 8100 8101 final Set<Integer> includedUsers; 8102 if (includeProfiles) { 8103 includedUsers = getProfileIdsLocked(userId); 8104 } else { 8105 includedUsers = new HashSet<Integer>(); 8106 } 8107 includedUsers.add(Integer.valueOf(userId)); 8108 8109 for (int i=0; i<N && maxNum > 0; i++) { 8110 TaskRecord tr = mRecentTasks.get(i); 8111 // Only add calling user or related users recent tasks 8112 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8113 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8114 continue; 8115 } 8116 8117 // Return the entry if desired by the caller. We always return 8118 // the first entry, because callers always expect this to be the 8119 // foreground app. We may filter others if the caller has 8120 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8121 // we should exclude the entry. 8122 8123 if (i == 0 8124 || withExcluded 8125 || (tr.intent == null) 8126 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8127 == 0)) { 8128 if (!allowed) { 8129 // If the caller doesn't have the GET_TASKS permission, then only 8130 // allow them to see a small subset of tasks -- their own and home. 8131 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8132 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8133 continue; 8134 } 8135 } 8136 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8137 if (tr.stack != null && tr.stack.isHomeStack()) { 8138 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8139 continue; 8140 } 8141 } 8142 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8143 // Don't include auto remove tasks that are finished or finishing. 8144 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8145 + tr); 8146 continue; 8147 } 8148 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8149 && !tr.isAvailable) { 8150 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8151 continue; 8152 } 8153 8154 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8155 if (!detailed) { 8156 rti.baseIntent.replaceExtras((Bundle)null); 8157 } 8158 8159 res.add(rti); 8160 maxNum--; 8161 } 8162 } 8163 return res; 8164 } 8165 } 8166 8167 private TaskRecord taskForIdLocked(int id) { 8168 final TaskRecord task = recentTaskForIdLocked(id); 8169 if (task != null) { 8170 return task; 8171 } 8172 8173 // Don't give up. Sometimes it just hasn't made it to recents yet. 8174 return mStackSupervisor.anyTaskForIdLocked(id); 8175 } 8176 8177 private TaskRecord recentTaskForIdLocked(int id) { 8178 final int N = mRecentTasks.size(); 8179 for (int i=0; i<N; i++) { 8180 TaskRecord tr = mRecentTasks.get(i); 8181 if (tr.taskId == id) { 8182 return tr; 8183 } 8184 } 8185 return null; 8186 } 8187 8188 @Override 8189 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8190 synchronized (this) { 8191 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8192 "getTaskThumbnail()"); 8193 TaskRecord tr = recentTaskForIdLocked(id); 8194 if (tr != null) { 8195 return tr.getTaskThumbnailLocked(); 8196 } 8197 } 8198 return null; 8199 } 8200 8201 @Override 8202 public int addAppTask(IBinder activityToken, Intent intent, 8203 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8204 final int callingUid = Binder.getCallingUid(); 8205 final long callingIdent = Binder.clearCallingIdentity(); 8206 8207 try { 8208 synchronized (this) { 8209 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8210 if (r == null) { 8211 throw new IllegalArgumentException("Activity does not exist; token=" 8212 + activityToken); 8213 } 8214 ComponentName comp = intent.getComponent(); 8215 if (comp == null) { 8216 throw new IllegalArgumentException("Intent " + intent 8217 + " must specify explicit component"); 8218 } 8219 if (thumbnail.getWidth() != mThumbnailWidth 8220 || thumbnail.getHeight() != mThumbnailHeight) { 8221 throw new IllegalArgumentException("Bad thumbnail size: got " 8222 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8223 + mThumbnailWidth + "x" + mThumbnailHeight); 8224 } 8225 if (intent.getSelector() != null) { 8226 intent.setSelector(null); 8227 } 8228 if (intent.getSourceBounds() != null) { 8229 intent.setSourceBounds(null); 8230 } 8231 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8232 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8233 // The caller has added this as an auto-remove task... that makes no 8234 // sense, so turn off auto-remove. 8235 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8236 } 8237 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8238 // Must be a new task. 8239 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8240 } 8241 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8242 mLastAddedTaskActivity = null; 8243 } 8244 ActivityInfo ainfo = mLastAddedTaskActivity; 8245 if (ainfo == null) { 8246 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8247 comp, 0, UserHandle.getUserId(callingUid)); 8248 if (ainfo.applicationInfo.uid != callingUid) { 8249 throw new SecurityException( 8250 "Can't add task for another application: target uid=" 8251 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8252 } 8253 } 8254 8255 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8256 intent, description); 8257 8258 int trimIdx = trimRecentsForTaskLocked(task, false); 8259 if (trimIdx >= 0) { 8260 // If this would have caused a trim, then we'll abort because that 8261 // means it would be added at the end of the list but then just removed. 8262 return -1; 8263 } 8264 8265 final int N = mRecentTasks.size(); 8266 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8267 final TaskRecord tr = mRecentTasks.remove(N - 1); 8268 tr.removedFromRecents(); 8269 } 8270 8271 task.inRecents = true; 8272 mRecentTasks.add(task); 8273 r.task.stack.addTask(task, false, false); 8274 8275 task.setLastThumbnail(thumbnail); 8276 task.freeLastThumbnail(); 8277 8278 return task.taskId; 8279 } 8280 } finally { 8281 Binder.restoreCallingIdentity(callingIdent); 8282 } 8283 } 8284 8285 @Override 8286 public Point getAppTaskThumbnailSize() { 8287 synchronized (this) { 8288 return new Point(mThumbnailWidth, mThumbnailHeight); 8289 } 8290 } 8291 8292 @Override 8293 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8294 synchronized (this) { 8295 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8296 if (r != null) { 8297 r.setTaskDescription(td); 8298 r.task.updateTaskDescription(); 8299 } 8300 } 8301 } 8302 8303 @Override 8304 public Bitmap getTaskDescriptionIcon(String filename) { 8305 if (!FileUtils.isValidExtFilename(filename) 8306 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8307 throw new IllegalArgumentException("Bad filename: " + filename); 8308 } 8309 return mTaskPersister.getTaskDescriptionIcon(filename); 8310 } 8311 8312 @Override 8313 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8314 throws RemoteException { 8315 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8316 opts.getCustomInPlaceResId() == 0) { 8317 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8318 "with valid animation"); 8319 } 8320 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8321 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8322 opts.getCustomInPlaceResId()); 8323 mWindowManager.executeAppTransition(); 8324 } 8325 8326 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8327 mRecentTasks.remove(tr); 8328 tr.removedFromRecents(); 8329 ComponentName component = tr.getBaseIntent().getComponent(); 8330 if (component == null) { 8331 Slog.w(TAG, "No component for base intent of task: " + tr); 8332 return; 8333 } 8334 8335 if (!killProcess) { 8336 return; 8337 } 8338 8339 // Determine if the process(es) for this task should be killed. 8340 final String pkg = component.getPackageName(); 8341 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8342 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8343 for (int i = 0; i < pmap.size(); i++) { 8344 8345 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8346 for (int j = 0; j < uids.size(); j++) { 8347 ProcessRecord proc = uids.valueAt(j); 8348 if (proc.userId != tr.userId) { 8349 // Don't kill process for a different user. 8350 continue; 8351 } 8352 if (proc == mHomeProcess) { 8353 // Don't kill the home process along with tasks from the same package. 8354 continue; 8355 } 8356 if (!proc.pkgList.containsKey(pkg)) { 8357 // Don't kill process that is not associated with this task. 8358 continue; 8359 } 8360 8361 for (int k = 0; k < proc.activities.size(); k++) { 8362 TaskRecord otherTask = proc.activities.get(k).task; 8363 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8364 // Don't kill process(es) that has an activity in a different task that is 8365 // also in recents. 8366 return; 8367 } 8368 } 8369 8370 // Add process to kill list. 8371 procsToKill.add(proc); 8372 } 8373 } 8374 8375 // Find any running services associated with this app and stop if needed. 8376 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8377 8378 // Kill the running processes. 8379 for (int i = 0; i < procsToKill.size(); i++) { 8380 ProcessRecord pr = procsToKill.get(i); 8381 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8382 pr.kill("remove task", true); 8383 } else { 8384 pr.waitingToKill = "remove task"; 8385 } 8386 } 8387 } 8388 8389 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8390 // Remove all tasks with activities in the specified package from the list of recent tasks 8391 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8392 TaskRecord tr = mRecentTasks.get(i); 8393 if (tr.userId != userId) continue; 8394 8395 ComponentName cn = tr.intent.getComponent(); 8396 if (cn != null && cn.getPackageName().equals(packageName)) { 8397 // If the package name matches, remove the task. 8398 removeTaskByIdLocked(tr.taskId, true); 8399 } 8400 } 8401 } 8402 8403 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8404 final IPackageManager pm = AppGlobals.getPackageManager(); 8405 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8406 8407 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8408 TaskRecord tr = mRecentTasks.get(i); 8409 if (tr.userId != userId) continue; 8410 8411 ComponentName cn = tr.intent.getComponent(); 8412 if (cn != null && cn.getPackageName().equals(packageName)) { 8413 // Skip if component still exists in the package. 8414 if (componentsKnownToExist.contains(cn)) continue; 8415 8416 try { 8417 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8418 if (info != null) { 8419 componentsKnownToExist.add(cn); 8420 } else { 8421 removeTaskByIdLocked(tr.taskId, false); 8422 } 8423 } catch (RemoteException e) { 8424 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8425 } 8426 } 8427 } 8428 } 8429 8430 /** 8431 * Removes the task with the specified task id. 8432 * 8433 * @param taskId Identifier of the task to be removed. 8434 * @param killProcess Kill any process associated with the task if possible. 8435 * @return Returns true if the given task was found and removed. 8436 */ 8437 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8438 TaskRecord tr = taskForIdLocked(taskId); 8439 if (tr != null) { 8440 tr.removeTaskActivitiesLocked(); 8441 cleanUpRemovedTaskLocked(tr, killProcess); 8442 if (tr.isPersistable) { 8443 notifyTaskPersisterLocked(null, true); 8444 } 8445 return true; 8446 } 8447 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8448 return false; 8449 } 8450 8451 @Override 8452 public boolean removeTask(int taskId) { 8453 synchronized (this) { 8454 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8455 "removeTask()"); 8456 long ident = Binder.clearCallingIdentity(); 8457 try { 8458 return removeTaskByIdLocked(taskId, true); 8459 } finally { 8460 Binder.restoreCallingIdentity(ident); 8461 } 8462 } 8463 } 8464 8465 /** 8466 * TODO: Add mController hook 8467 */ 8468 @Override 8469 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8470 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8471 "moveTaskToFront()"); 8472 8473 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8474 synchronized(this) { 8475 moveTaskToFrontLocked(taskId, flags, options); 8476 } 8477 } 8478 8479 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8480 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8481 Binder.getCallingUid(), -1, -1, "Task to front")) { 8482 ActivityOptions.abort(options); 8483 return; 8484 } 8485 final long origId = Binder.clearCallingIdentity(); 8486 try { 8487 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8488 if (task == null) { 8489 Slog.d(TAG, "Could not find task for id: "+ taskId); 8490 return; 8491 } 8492 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8493 mStackSupervisor.showLockTaskToast(); 8494 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8495 return; 8496 } 8497 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8498 if (prev != null && prev.isRecentsActivity()) { 8499 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8500 } 8501 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8502 } finally { 8503 Binder.restoreCallingIdentity(origId); 8504 } 8505 ActivityOptions.abort(options); 8506 } 8507 8508 @Override 8509 public void moveTaskToBack(int taskId) { 8510 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8511 "moveTaskToBack()"); 8512 8513 synchronized(this) { 8514 TaskRecord tr = taskForIdLocked(taskId); 8515 if (tr != null) { 8516 if (tr == mStackSupervisor.mLockTaskModeTask) { 8517 mStackSupervisor.showLockTaskToast(); 8518 return; 8519 } 8520 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8521 ActivityStack stack = tr.stack; 8522 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8523 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8524 Binder.getCallingUid(), -1, -1, "Task to back")) { 8525 return; 8526 } 8527 } 8528 final long origId = Binder.clearCallingIdentity(); 8529 try { 8530 stack.moveTaskToBackLocked(taskId, null); 8531 } finally { 8532 Binder.restoreCallingIdentity(origId); 8533 } 8534 } 8535 } 8536 } 8537 8538 /** 8539 * Moves an activity, and all of the other activities within the same task, to the bottom 8540 * of the history stack. The activity's order within the task is unchanged. 8541 * 8542 * @param token A reference to the activity we wish to move 8543 * @param nonRoot If false then this only works if the activity is the root 8544 * of a task; if true it will work for any activity in a task. 8545 * @return Returns true if the move completed, false if not. 8546 */ 8547 @Override 8548 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8549 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8550 synchronized(this) { 8551 final long origId = Binder.clearCallingIdentity(); 8552 try { 8553 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8554 if (taskId >= 0) { 8555 if ((mStackSupervisor.mLockTaskModeTask != null) 8556 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8557 mStackSupervisor.showLockTaskToast(); 8558 return false; 8559 } 8560 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8561 } 8562 } finally { 8563 Binder.restoreCallingIdentity(origId); 8564 } 8565 } 8566 return false; 8567 } 8568 8569 @Override 8570 public void moveTaskBackwards(int task) { 8571 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8572 "moveTaskBackwards()"); 8573 8574 synchronized(this) { 8575 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8576 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8577 return; 8578 } 8579 final long origId = Binder.clearCallingIdentity(); 8580 moveTaskBackwardsLocked(task); 8581 Binder.restoreCallingIdentity(origId); 8582 } 8583 } 8584 8585 private final void moveTaskBackwardsLocked(int task) { 8586 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8587 } 8588 8589 @Override 8590 public IBinder getHomeActivityToken() throws RemoteException { 8591 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8592 "getHomeActivityToken()"); 8593 synchronized (this) { 8594 return mStackSupervisor.getHomeActivityToken(); 8595 } 8596 } 8597 8598 @Override 8599 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8600 IActivityContainerCallback callback) throws RemoteException { 8601 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8602 "createActivityContainer()"); 8603 synchronized (this) { 8604 if (parentActivityToken == null) { 8605 throw new IllegalArgumentException("parent token must not be null"); 8606 } 8607 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8608 if (r == null) { 8609 return null; 8610 } 8611 if (callback == null) { 8612 throw new IllegalArgumentException("callback must not be null"); 8613 } 8614 return mStackSupervisor.createActivityContainer(r, callback); 8615 } 8616 } 8617 8618 @Override 8619 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8620 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8621 "deleteActivityContainer()"); 8622 synchronized (this) { 8623 mStackSupervisor.deleteActivityContainer(container); 8624 } 8625 } 8626 8627 @Override 8628 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8629 throws RemoteException { 8630 synchronized (this) { 8631 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8632 if (stack != null) { 8633 return stack.mActivityContainer; 8634 } 8635 return null; 8636 } 8637 } 8638 8639 @Override 8640 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8641 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8642 "moveTaskToStack()"); 8643 if (stackId == HOME_STACK_ID) { 8644 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8645 new RuntimeException("here").fillInStackTrace()); 8646 } 8647 synchronized (this) { 8648 long ident = Binder.clearCallingIdentity(); 8649 try { 8650 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8651 + stackId + " toTop=" + toTop); 8652 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8653 } finally { 8654 Binder.restoreCallingIdentity(ident); 8655 } 8656 } 8657 } 8658 8659 @Override 8660 public void resizeStack(int stackBoxId, Rect bounds) { 8661 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8662 "resizeStackBox()"); 8663 long ident = Binder.clearCallingIdentity(); 8664 try { 8665 mWindowManager.resizeStack(stackBoxId, bounds); 8666 } finally { 8667 Binder.restoreCallingIdentity(ident); 8668 } 8669 } 8670 8671 @Override 8672 public List<StackInfo> getAllStackInfos() { 8673 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8674 "getAllStackInfos()"); 8675 long ident = Binder.clearCallingIdentity(); 8676 try { 8677 synchronized (this) { 8678 return mStackSupervisor.getAllStackInfosLocked(); 8679 } 8680 } finally { 8681 Binder.restoreCallingIdentity(ident); 8682 } 8683 } 8684 8685 @Override 8686 public StackInfo getStackInfo(int stackId) { 8687 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8688 "getStackInfo()"); 8689 long ident = Binder.clearCallingIdentity(); 8690 try { 8691 synchronized (this) { 8692 return mStackSupervisor.getStackInfoLocked(stackId); 8693 } 8694 } finally { 8695 Binder.restoreCallingIdentity(ident); 8696 } 8697 } 8698 8699 @Override 8700 public boolean isInHomeStack(int taskId) { 8701 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8702 "getStackInfo()"); 8703 long ident = Binder.clearCallingIdentity(); 8704 try { 8705 synchronized (this) { 8706 TaskRecord tr = taskForIdLocked(taskId); 8707 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8708 } 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 } 8713 8714 @Override 8715 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8716 synchronized(this) { 8717 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8718 } 8719 } 8720 8721 private boolean isLockTaskAuthorized(String pkg) { 8722 final DevicePolicyManager dpm = (DevicePolicyManager) 8723 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8724 try { 8725 int uid = mContext.getPackageManager().getPackageUid(pkg, 8726 Binder.getCallingUserHandle().getIdentifier()); 8727 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8728 } catch (NameNotFoundException e) { 8729 return false; 8730 } 8731 } 8732 8733 void startLockTaskMode(TaskRecord task) { 8734 final String pkg; 8735 synchronized (this) { 8736 pkg = task.intent.getComponent().getPackageName(); 8737 } 8738 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8739 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8740 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8741 StatusBarManagerInternal.class); 8742 if (statusBarManager != null) { 8743 statusBarManager.showScreenPinningRequest(); 8744 } 8745 return; 8746 } 8747 long ident = Binder.clearCallingIdentity(); 8748 try { 8749 synchronized (this) { 8750 // Since we lost lock on task, make sure it is still there. 8751 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8752 if (task != null) { 8753 if (!isSystemInitiated 8754 && ((mStackSupervisor.getFocusedStack() == null) 8755 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8756 throw new IllegalArgumentException("Invalid task, not in foreground"); 8757 } 8758 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8759 } 8760 } 8761 } finally { 8762 Binder.restoreCallingIdentity(ident); 8763 } 8764 } 8765 8766 @Override 8767 public void startLockTaskMode(int taskId) { 8768 final TaskRecord task; 8769 long ident = Binder.clearCallingIdentity(); 8770 try { 8771 synchronized (this) { 8772 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8773 } 8774 } finally { 8775 Binder.restoreCallingIdentity(ident); 8776 } 8777 if (task != null) { 8778 startLockTaskMode(task); 8779 } 8780 } 8781 8782 @Override 8783 public void startLockTaskMode(IBinder token) { 8784 final TaskRecord task; 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 final ActivityRecord r = ActivityRecord.forToken(token); 8789 if (r == null) { 8790 return; 8791 } 8792 task = r.task; 8793 } 8794 } finally { 8795 Binder.restoreCallingIdentity(ident); 8796 } 8797 if (task != null) { 8798 startLockTaskMode(task); 8799 } 8800 } 8801 8802 @Override 8803 public void startLockTaskModeOnCurrent() throws RemoteException { 8804 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8805 "startLockTaskModeOnCurrent"); 8806 long ident = Binder.clearCallingIdentity(); 8807 try { 8808 ActivityRecord r = null; 8809 synchronized (this) { 8810 r = mStackSupervisor.topRunningActivityLocked(); 8811 } 8812 startLockTaskMode(r.task); 8813 } finally { 8814 Binder.restoreCallingIdentity(ident); 8815 } 8816 } 8817 8818 @Override 8819 public void stopLockTaskMode() { 8820 // Verify that the user matches the package of the intent for the TaskRecord 8821 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8822 // and stopLockTaskMode. 8823 final int callingUid = Binder.getCallingUid(); 8824 if (callingUid != Process.SYSTEM_UID) { 8825 try { 8826 String pkg = 8827 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8828 int uid = mContext.getPackageManager().getPackageUid(pkg, 8829 Binder.getCallingUserHandle().getIdentifier()); 8830 if (uid != callingUid) { 8831 throw new SecurityException("Invalid uid, expected " + uid); 8832 } 8833 } catch (NameNotFoundException e) { 8834 Log.d(TAG, "stopLockTaskMode " + e); 8835 return; 8836 } 8837 } 8838 long ident = Binder.clearCallingIdentity(); 8839 try { 8840 Log.d(TAG, "stopLockTaskMode"); 8841 // Stop lock task 8842 synchronized (this) { 8843 mStackSupervisor.setLockTaskModeLocked(null, false); 8844 } 8845 } finally { 8846 Binder.restoreCallingIdentity(ident); 8847 } 8848 } 8849 8850 @Override 8851 public void stopLockTaskModeOnCurrent() throws RemoteException { 8852 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8853 "stopLockTaskModeOnCurrent"); 8854 long ident = Binder.clearCallingIdentity(); 8855 try { 8856 stopLockTaskMode(); 8857 } finally { 8858 Binder.restoreCallingIdentity(ident); 8859 } 8860 } 8861 8862 @Override 8863 public boolean isInLockTaskMode() { 8864 synchronized (this) { 8865 return mStackSupervisor.isInLockTaskMode(); 8866 } 8867 } 8868 8869 // ========================================================= 8870 // CONTENT PROVIDERS 8871 // ========================================================= 8872 8873 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8874 List<ProviderInfo> providers = null; 8875 try { 8876 providers = AppGlobals.getPackageManager(). 8877 queryContentProviders(app.processName, app.uid, 8878 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8879 } catch (RemoteException ex) { 8880 } 8881 if (DEBUG_MU) 8882 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8883 int userId = app.userId; 8884 if (providers != null) { 8885 int N = providers.size(); 8886 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8887 for (int i=0; i<N; i++) { 8888 ProviderInfo cpi = 8889 (ProviderInfo)providers.get(i); 8890 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8891 cpi.name, cpi.flags); 8892 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8893 // This is a singleton provider, but a user besides the 8894 // default user is asking to initialize a process it runs 8895 // in... well, no, it doesn't actually run in this process, 8896 // it runs in the process of the default user. Get rid of it. 8897 providers.remove(i); 8898 N--; 8899 i--; 8900 continue; 8901 } 8902 8903 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8904 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8905 if (cpr == null) { 8906 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8907 mProviderMap.putProviderByClass(comp, cpr); 8908 } 8909 if (DEBUG_MU) 8910 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8911 app.pubProviders.put(cpi.name, cpr); 8912 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8913 // Don't add this if it is a platform component that is marked 8914 // to run in multiple processes, because this is actually 8915 // part of the framework so doesn't make sense to track as a 8916 // separate apk in the process. 8917 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8918 mProcessStats); 8919 } 8920 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8921 } 8922 } 8923 return providers; 8924 } 8925 8926 /** 8927 * Check if {@link ProcessRecord} has a possible chance at accessing the 8928 * given {@link ProviderInfo}. Final permission checking is always done 8929 * in {@link ContentProvider}. 8930 */ 8931 private final String checkContentProviderPermissionLocked( 8932 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8933 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8934 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8935 boolean checkedGrants = false; 8936 if (checkUser) { 8937 // Looking for cross-user grants before enforcing the typical cross-users permissions 8938 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8939 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8940 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8941 return null; 8942 } 8943 checkedGrants = true; 8944 } 8945 userId = handleIncomingUser(callingPid, callingUid, userId, 8946 false, ALLOW_NON_FULL, 8947 "checkContentProviderPermissionLocked " + cpi.authority, null); 8948 if (userId != tmpTargetUserId) { 8949 // When we actually went to determine the final targer user ID, this ended 8950 // up different than our initial check for the authority. This is because 8951 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8952 // SELF. So we need to re-check the grants again. 8953 checkedGrants = false; 8954 } 8955 } 8956 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8957 cpi.applicationInfo.uid, cpi.exported) 8958 == PackageManager.PERMISSION_GRANTED) { 8959 return null; 8960 } 8961 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8962 cpi.applicationInfo.uid, cpi.exported) 8963 == PackageManager.PERMISSION_GRANTED) { 8964 return null; 8965 } 8966 8967 PathPermission[] pps = cpi.pathPermissions; 8968 if (pps != null) { 8969 int i = pps.length; 8970 while (i > 0) { 8971 i--; 8972 PathPermission pp = pps[i]; 8973 String pprperm = pp.getReadPermission(); 8974 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8975 cpi.applicationInfo.uid, cpi.exported) 8976 == PackageManager.PERMISSION_GRANTED) { 8977 return null; 8978 } 8979 String ppwperm = pp.getWritePermission(); 8980 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8981 cpi.applicationInfo.uid, cpi.exported) 8982 == PackageManager.PERMISSION_GRANTED) { 8983 return null; 8984 } 8985 } 8986 } 8987 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8988 return null; 8989 } 8990 8991 String msg; 8992 if (!cpi.exported) { 8993 msg = "Permission Denial: opening provider " + cpi.name 8994 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8995 + ", uid=" + callingUid + ") that is not exported from uid " 8996 + cpi.applicationInfo.uid; 8997 } else { 8998 msg = "Permission Denial: opening provider " + cpi.name 8999 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9000 + ", uid=" + callingUid + ") requires " 9001 + cpi.readPermission + " or " + cpi.writePermission; 9002 } 9003 Slog.w(TAG, msg); 9004 return msg; 9005 } 9006 9007 /** 9008 * Returns if the ContentProvider has granted a uri to callingUid 9009 */ 9010 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9011 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9012 if (perms != null) { 9013 for (int i=perms.size()-1; i>=0; i--) { 9014 GrantUri grantUri = perms.keyAt(i); 9015 if (grantUri.sourceUserId == userId || !checkUser) { 9016 if (matchesProvider(grantUri.uri, cpi)) { 9017 return true; 9018 } 9019 } 9020 } 9021 } 9022 return false; 9023 } 9024 9025 /** 9026 * Returns true if the uri authority is one of the authorities specified in the provider. 9027 */ 9028 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9029 String uriAuth = uri.getAuthority(); 9030 String cpiAuth = cpi.authority; 9031 if (cpiAuth.indexOf(';') == -1) { 9032 return cpiAuth.equals(uriAuth); 9033 } 9034 String[] cpiAuths = cpiAuth.split(";"); 9035 int length = cpiAuths.length; 9036 for (int i = 0; i < length; i++) { 9037 if (cpiAuths[i].equals(uriAuth)) return true; 9038 } 9039 return false; 9040 } 9041 9042 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9043 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9044 if (r != null) { 9045 for (int i=0; i<r.conProviders.size(); i++) { 9046 ContentProviderConnection conn = r.conProviders.get(i); 9047 if (conn.provider == cpr) { 9048 if (DEBUG_PROVIDER) Slog.v(TAG, 9049 "Adding provider requested by " 9050 + r.processName + " from process " 9051 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9052 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9053 if (stable) { 9054 conn.stableCount++; 9055 conn.numStableIncs++; 9056 } else { 9057 conn.unstableCount++; 9058 conn.numUnstableIncs++; 9059 } 9060 return conn; 9061 } 9062 } 9063 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9064 if (stable) { 9065 conn.stableCount = 1; 9066 conn.numStableIncs = 1; 9067 } else { 9068 conn.unstableCount = 1; 9069 conn.numUnstableIncs = 1; 9070 } 9071 cpr.connections.add(conn); 9072 r.conProviders.add(conn); 9073 return conn; 9074 } 9075 cpr.addExternalProcessHandleLocked(externalProcessToken); 9076 return null; 9077 } 9078 9079 boolean decProviderCountLocked(ContentProviderConnection conn, 9080 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9081 if (conn != null) { 9082 cpr = conn.provider; 9083 if (DEBUG_PROVIDER) Slog.v(TAG, 9084 "Removing provider requested by " 9085 + conn.client.processName + " from process " 9086 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9087 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9088 if (stable) { 9089 conn.stableCount--; 9090 } else { 9091 conn.unstableCount--; 9092 } 9093 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9094 cpr.connections.remove(conn); 9095 conn.client.conProviders.remove(conn); 9096 return true; 9097 } 9098 return false; 9099 } 9100 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9101 return false; 9102 } 9103 9104 private void checkTime(long startTime, String where) { 9105 long now = SystemClock.elapsedRealtime(); 9106 if ((now-startTime) > 1000) { 9107 // If we are taking more than a second, log about it. 9108 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9109 } 9110 } 9111 9112 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9113 String name, IBinder token, boolean stable, int userId) { 9114 ContentProviderRecord cpr; 9115 ContentProviderConnection conn = null; 9116 ProviderInfo cpi = null; 9117 9118 synchronized(this) { 9119 long startTime = SystemClock.elapsedRealtime(); 9120 9121 ProcessRecord r = null; 9122 if (caller != null) { 9123 r = getRecordForAppLocked(caller); 9124 if (r == null) { 9125 throw new SecurityException( 9126 "Unable to find app for caller " + caller 9127 + " (pid=" + Binder.getCallingPid() 9128 + ") when getting content provider " + name); 9129 } 9130 } 9131 9132 boolean checkCrossUser = true; 9133 9134 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9135 9136 // First check if this content provider has been published... 9137 cpr = mProviderMap.getProviderByName(name, userId); 9138 // If that didn't work, check if it exists for user 0 and then 9139 // verify that it's a singleton provider before using it. 9140 if (cpr == null && userId != UserHandle.USER_OWNER) { 9141 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9142 if (cpr != null) { 9143 cpi = cpr.info; 9144 if (isSingleton(cpi.processName, cpi.applicationInfo, 9145 cpi.name, cpi.flags) 9146 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9147 userId = UserHandle.USER_OWNER; 9148 checkCrossUser = false; 9149 } else { 9150 cpr = null; 9151 cpi = null; 9152 } 9153 } 9154 } 9155 9156 boolean providerRunning = cpr != null; 9157 if (providerRunning) { 9158 cpi = cpr.info; 9159 String msg; 9160 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9161 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9162 != null) { 9163 throw new SecurityException(msg); 9164 } 9165 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9166 9167 if (r != null && cpr.canRunHere(r)) { 9168 // This provider has been published or is in the process 9169 // of being published... but it is also allowed to run 9170 // in the caller's process, so don't make a connection 9171 // and just let the caller instantiate its own instance. 9172 ContentProviderHolder holder = cpr.newHolder(null); 9173 // don't give caller the provider object, it needs 9174 // to make its own. 9175 holder.provider = null; 9176 return holder; 9177 } 9178 9179 final long origId = Binder.clearCallingIdentity(); 9180 9181 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9182 9183 // In this case the provider instance already exists, so we can 9184 // return it right away. 9185 conn = incProviderCountLocked(r, cpr, token, stable); 9186 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9187 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9188 // If this is a perceptible app accessing the provider, 9189 // make sure to count it as being accessed and thus 9190 // back up on the LRU list. This is good because 9191 // content providers are often expensive to start. 9192 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9193 updateLruProcessLocked(cpr.proc, false, null); 9194 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9195 } 9196 } 9197 9198 if (cpr.proc != null) { 9199 if (false) { 9200 if (cpr.name.flattenToShortString().equals( 9201 "com.android.providers.calendar/.CalendarProvider2")) { 9202 Slog.v(TAG, "****************** KILLING " 9203 + cpr.name.flattenToShortString()); 9204 Process.killProcess(cpr.proc.pid); 9205 } 9206 } 9207 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9208 boolean success = updateOomAdjLocked(cpr.proc); 9209 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9210 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9211 // NOTE: there is still a race here where a signal could be 9212 // pending on the process even though we managed to update its 9213 // adj level. Not sure what to do about this, but at least 9214 // the race is now smaller. 9215 if (!success) { 9216 // Uh oh... it looks like the provider's process 9217 // has been killed on us. We need to wait for a new 9218 // process to be started, and make sure its death 9219 // doesn't kill our process. 9220 Slog.i(TAG, 9221 "Existing provider " + cpr.name.flattenToShortString() 9222 + " is crashing; detaching " + r); 9223 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9224 checkTime(startTime, "getContentProviderImpl: before appDied"); 9225 appDiedLocked(cpr.proc); 9226 checkTime(startTime, "getContentProviderImpl: after appDied"); 9227 if (!lastRef) { 9228 // This wasn't the last ref our process had on 9229 // the provider... we have now been killed, bail. 9230 return null; 9231 } 9232 providerRunning = false; 9233 conn = null; 9234 } 9235 } 9236 9237 Binder.restoreCallingIdentity(origId); 9238 } 9239 9240 boolean singleton; 9241 if (!providerRunning) { 9242 try { 9243 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9244 cpi = AppGlobals.getPackageManager(). 9245 resolveContentProvider(name, 9246 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9247 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9248 } catch (RemoteException ex) { 9249 } 9250 if (cpi == null) { 9251 return null; 9252 } 9253 // If the provider is a singleton AND 9254 // (it's a call within the same user || the provider is a 9255 // privileged app) 9256 // Then allow connecting to the singleton provider 9257 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9258 cpi.name, cpi.flags) 9259 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9260 if (singleton) { 9261 userId = UserHandle.USER_OWNER; 9262 } 9263 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9264 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9265 9266 String msg; 9267 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9268 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9269 != null) { 9270 throw new SecurityException(msg); 9271 } 9272 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9273 9274 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9275 && !cpi.processName.equals("system")) { 9276 // If this content provider does not run in the system 9277 // process, and the system is not yet ready to run other 9278 // processes, then fail fast instead of hanging. 9279 throw new IllegalArgumentException( 9280 "Attempt to launch content provider before system ready"); 9281 } 9282 9283 // Make sure that the user who owns this provider is running. If not, 9284 // we don't want to allow it to run. 9285 if (!isUserRunningLocked(userId, false)) { 9286 Slog.w(TAG, "Unable to launch app " 9287 + cpi.applicationInfo.packageName + "/" 9288 + cpi.applicationInfo.uid + " for provider " 9289 + name + ": user " + userId + " is stopped"); 9290 return null; 9291 } 9292 9293 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9294 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9295 cpr = mProviderMap.getProviderByClass(comp, userId); 9296 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9297 final boolean firstClass = cpr == null; 9298 if (firstClass) { 9299 final long ident = Binder.clearCallingIdentity(); 9300 try { 9301 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9302 ApplicationInfo ai = 9303 AppGlobals.getPackageManager(). 9304 getApplicationInfo( 9305 cpi.applicationInfo.packageName, 9306 STOCK_PM_FLAGS, userId); 9307 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9308 if (ai == null) { 9309 Slog.w(TAG, "No package info for content provider " 9310 + cpi.name); 9311 return null; 9312 } 9313 ai = getAppInfoForUser(ai, userId); 9314 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9315 } catch (RemoteException ex) { 9316 // pm is in same process, this will never happen. 9317 } finally { 9318 Binder.restoreCallingIdentity(ident); 9319 } 9320 } 9321 9322 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9323 9324 if (r != null && cpr.canRunHere(r)) { 9325 // If this is a multiprocess provider, then just return its 9326 // info and allow the caller to instantiate it. Only do 9327 // this if the provider is the same user as the caller's 9328 // process, or can run as root (so can be in any process). 9329 return cpr.newHolder(null); 9330 } 9331 9332 if (DEBUG_PROVIDER) { 9333 RuntimeException e = new RuntimeException("here"); 9334 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9335 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9336 } 9337 9338 // This is single process, and our app is now connecting to it. 9339 // See if we are already in the process of launching this 9340 // provider. 9341 final int N = mLaunchingProviders.size(); 9342 int i; 9343 for (i=0; i<N; i++) { 9344 if (mLaunchingProviders.get(i) == cpr) { 9345 break; 9346 } 9347 } 9348 9349 // If the provider is not already being launched, then get it 9350 // started. 9351 if (i >= N) { 9352 final long origId = Binder.clearCallingIdentity(); 9353 9354 try { 9355 // Content provider is now in use, its package can't be stopped. 9356 try { 9357 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9358 AppGlobals.getPackageManager().setPackageStoppedState( 9359 cpr.appInfo.packageName, false, userId); 9360 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9361 } catch (RemoteException e) { 9362 } catch (IllegalArgumentException e) { 9363 Slog.w(TAG, "Failed trying to unstop package " 9364 + cpr.appInfo.packageName + ": " + e); 9365 } 9366 9367 // Use existing process if already started 9368 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9369 ProcessRecord proc = getProcessRecordLocked( 9370 cpi.processName, cpr.appInfo.uid, false); 9371 if (proc != null && proc.thread != null) { 9372 if (DEBUG_PROVIDER) { 9373 Slog.d(TAG, "Installing in existing process " + proc); 9374 } 9375 if (!proc.pubProviders.containsKey(cpi.name)) { 9376 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9377 proc.pubProviders.put(cpi.name, cpr); 9378 try { 9379 proc.thread.scheduleInstallProvider(cpi); 9380 } catch (RemoteException e) { 9381 } 9382 } 9383 } else { 9384 checkTime(startTime, "getContentProviderImpl: before start process"); 9385 proc = startProcessLocked(cpi.processName, 9386 cpr.appInfo, false, 0, "content provider", 9387 new ComponentName(cpi.applicationInfo.packageName, 9388 cpi.name), false, false, false); 9389 checkTime(startTime, "getContentProviderImpl: after start process"); 9390 if (proc == null) { 9391 Slog.w(TAG, "Unable to launch app " 9392 + cpi.applicationInfo.packageName + "/" 9393 + cpi.applicationInfo.uid + " for provider " 9394 + name + ": process is bad"); 9395 return null; 9396 } 9397 } 9398 cpr.launchingApp = proc; 9399 mLaunchingProviders.add(cpr); 9400 } finally { 9401 Binder.restoreCallingIdentity(origId); 9402 } 9403 } 9404 9405 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9406 9407 // Make sure the provider is published (the same provider class 9408 // may be published under multiple names). 9409 if (firstClass) { 9410 mProviderMap.putProviderByClass(comp, cpr); 9411 } 9412 9413 mProviderMap.putProviderByName(name, cpr); 9414 conn = incProviderCountLocked(r, cpr, token, stable); 9415 if (conn != null) { 9416 conn.waiting = true; 9417 } 9418 } 9419 checkTime(startTime, "getContentProviderImpl: done!"); 9420 } 9421 9422 // Wait for the provider to be published... 9423 synchronized (cpr) { 9424 while (cpr.provider == null) { 9425 if (cpr.launchingApp == null) { 9426 Slog.w(TAG, "Unable to launch app " 9427 + cpi.applicationInfo.packageName + "/" 9428 + cpi.applicationInfo.uid + " for provider " 9429 + name + ": launching app became null"); 9430 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9431 UserHandle.getUserId(cpi.applicationInfo.uid), 9432 cpi.applicationInfo.packageName, 9433 cpi.applicationInfo.uid, name); 9434 return null; 9435 } 9436 try { 9437 if (DEBUG_MU) { 9438 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9439 + cpr.launchingApp); 9440 } 9441 if (conn != null) { 9442 conn.waiting = true; 9443 } 9444 cpr.wait(); 9445 } catch (InterruptedException ex) { 9446 } finally { 9447 if (conn != null) { 9448 conn.waiting = false; 9449 } 9450 } 9451 } 9452 } 9453 return cpr != null ? cpr.newHolder(conn) : null; 9454 } 9455 9456 @Override 9457 public final ContentProviderHolder getContentProvider( 9458 IApplicationThread caller, String name, int userId, boolean stable) { 9459 enforceNotIsolatedCaller("getContentProvider"); 9460 if (caller == null) { 9461 String msg = "null IApplicationThread when getting content provider " 9462 + name; 9463 Slog.w(TAG, msg); 9464 throw new SecurityException(msg); 9465 } 9466 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9467 // with cross-user grant. 9468 return getContentProviderImpl(caller, name, null, stable, userId); 9469 } 9470 9471 public ContentProviderHolder getContentProviderExternal( 9472 String name, int userId, IBinder token) { 9473 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9474 "Do not have permission in call getContentProviderExternal()"); 9475 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9476 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9477 return getContentProviderExternalUnchecked(name, token, userId); 9478 } 9479 9480 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9481 IBinder token, int userId) { 9482 return getContentProviderImpl(null, name, token, true, userId); 9483 } 9484 9485 /** 9486 * Drop a content provider from a ProcessRecord's bookkeeping 9487 */ 9488 public void removeContentProvider(IBinder connection, boolean stable) { 9489 enforceNotIsolatedCaller("removeContentProvider"); 9490 long ident = Binder.clearCallingIdentity(); 9491 try { 9492 synchronized (this) { 9493 ContentProviderConnection conn; 9494 try { 9495 conn = (ContentProviderConnection)connection; 9496 } catch (ClassCastException e) { 9497 String msg ="removeContentProvider: " + connection 9498 + " not a ContentProviderConnection"; 9499 Slog.w(TAG, msg); 9500 throw new IllegalArgumentException(msg); 9501 } 9502 if (conn == null) { 9503 throw new NullPointerException("connection is null"); 9504 } 9505 if (decProviderCountLocked(conn, null, null, stable)) { 9506 updateOomAdjLocked(); 9507 } 9508 } 9509 } finally { 9510 Binder.restoreCallingIdentity(ident); 9511 } 9512 } 9513 9514 public void removeContentProviderExternal(String name, IBinder token) { 9515 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9516 "Do not have permission in call removeContentProviderExternal()"); 9517 int userId = UserHandle.getCallingUserId(); 9518 long ident = Binder.clearCallingIdentity(); 9519 try { 9520 removeContentProviderExternalUnchecked(name, token, userId); 9521 } finally { 9522 Binder.restoreCallingIdentity(ident); 9523 } 9524 } 9525 9526 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9527 synchronized (this) { 9528 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9529 if(cpr == null) { 9530 //remove from mProvidersByClass 9531 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9532 return; 9533 } 9534 9535 //update content provider record entry info 9536 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9537 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9538 if (localCpr.hasExternalProcessHandles()) { 9539 if (localCpr.removeExternalProcessHandleLocked(token)) { 9540 updateOomAdjLocked(); 9541 } else { 9542 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9543 + " with no external reference for token: " 9544 + token + "."); 9545 } 9546 } else { 9547 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9548 + " with no external references."); 9549 } 9550 } 9551 } 9552 9553 public final void publishContentProviders(IApplicationThread caller, 9554 List<ContentProviderHolder> providers) { 9555 if (providers == null) { 9556 return; 9557 } 9558 9559 enforceNotIsolatedCaller("publishContentProviders"); 9560 synchronized (this) { 9561 final ProcessRecord r = getRecordForAppLocked(caller); 9562 if (DEBUG_MU) 9563 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9564 if (r == null) { 9565 throw new SecurityException( 9566 "Unable to find app for caller " + caller 9567 + " (pid=" + Binder.getCallingPid() 9568 + ") when publishing content providers"); 9569 } 9570 9571 final long origId = Binder.clearCallingIdentity(); 9572 9573 final int N = providers.size(); 9574 for (int i=0; i<N; i++) { 9575 ContentProviderHolder src = providers.get(i); 9576 if (src == null || src.info == null || src.provider == null) { 9577 continue; 9578 } 9579 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9580 if (DEBUG_MU) 9581 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9582 if (dst != null) { 9583 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9584 mProviderMap.putProviderByClass(comp, dst); 9585 String names[] = dst.info.authority.split(";"); 9586 for (int j = 0; j < names.length; j++) { 9587 mProviderMap.putProviderByName(names[j], dst); 9588 } 9589 9590 int NL = mLaunchingProviders.size(); 9591 int j; 9592 for (j=0; j<NL; j++) { 9593 if (mLaunchingProviders.get(j) == dst) { 9594 mLaunchingProviders.remove(j); 9595 j--; 9596 NL--; 9597 } 9598 } 9599 synchronized (dst) { 9600 dst.provider = src.provider; 9601 dst.proc = r; 9602 dst.notifyAll(); 9603 } 9604 updateOomAdjLocked(r); 9605 } 9606 } 9607 9608 Binder.restoreCallingIdentity(origId); 9609 } 9610 } 9611 9612 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9613 ContentProviderConnection conn; 9614 try { 9615 conn = (ContentProviderConnection)connection; 9616 } catch (ClassCastException e) { 9617 String msg ="refContentProvider: " + connection 9618 + " not a ContentProviderConnection"; 9619 Slog.w(TAG, msg); 9620 throw new IllegalArgumentException(msg); 9621 } 9622 if (conn == null) { 9623 throw new NullPointerException("connection is null"); 9624 } 9625 9626 synchronized (this) { 9627 if (stable > 0) { 9628 conn.numStableIncs += stable; 9629 } 9630 stable = conn.stableCount + stable; 9631 if (stable < 0) { 9632 throw new IllegalStateException("stableCount < 0: " + stable); 9633 } 9634 9635 if (unstable > 0) { 9636 conn.numUnstableIncs += unstable; 9637 } 9638 unstable = conn.unstableCount + unstable; 9639 if (unstable < 0) { 9640 throw new IllegalStateException("unstableCount < 0: " + unstable); 9641 } 9642 9643 if ((stable+unstable) <= 0) { 9644 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9645 + stable + " unstable=" + unstable); 9646 } 9647 conn.stableCount = stable; 9648 conn.unstableCount = unstable; 9649 return !conn.dead; 9650 } 9651 } 9652 9653 public void unstableProviderDied(IBinder connection) { 9654 ContentProviderConnection conn; 9655 try { 9656 conn = (ContentProviderConnection)connection; 9657 } catch (ClassCastException e) { 9658 String msg ="refContentProvider: " + connection 9659 + " not a ContentProviderConnection"; 9660 Slog.w(TAG, msg); 9661 throw new IllegalArgumentException(msg); 9662 } 9663 if (conn == null) { 9664 throw new NullPointerException("connection is null"); 9665 } 9666 9667 // Safely retrieve the content provider associated with the connection. 9668 IContentProvider provider; 9669 synchronized (this) { 9670 provider = conn.provider.provider; 9671 } 9672 9673 if (provider == null) { 9674 // Um, yeah, we're way ahead of you. 9675 return; 9676 } 9677 9678 // Make sure the caller is being honest with us. 9679 if (provider.asBinder().pingBinder()) { 9680 // Er, no, still looks good to us. 9681 synchronized (this) { 9682 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9683 + " says " + conn + " died, but we don't agree"); 9684 return; 9685 } 9686 } 9687 9688 // Well look at that! It's dead! 9689 synchronized (this) { 9690 if (conn.provider.provider != provider) { 9691 // But something changed... good enough. 9692 return; 9693 } 9694 9695 ProcessRecord proc = conn.provider.proc; 9696 if (proc == null || proc.thread == null) { 9697 // Seems like the process is already cleaned up. 9698 return; 9699 } 9700 9701 // As far as we're concerned, this is just like receiving a 9702 // death notification... just a bit prematurely. 9703 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9704 + ") early provider death"); 9705 final long ident = Binder.clearCallingIdentity(); 9706 try { 9707 appDiedLocked(proc); 9708 } finally { 9709 Binder.restoreCallingIdentity(ident); 9710 } 9711 } 9712 } 9713 9714 @Override 9715 public void appNotRespondingViaProvider(IBinder connection) { 9716 enforceCallingPermission( 9717 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9718 9719 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9720 if (conn == null) { 9721 Slog.w(TAG, "ContentProviderConnection is null"); 9722 return; 9723 } 9724 9725 final ProcessRecord host = conn.provider.proc; 9726 if (host == null) { 9727 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9728 return; 9729 } 9730 9731 final long token = Binder.clearCallingIdentity(); 9732 try { 9733 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9734 } finally { 9735 Binder.restoreCallingIdentity(token); 9736 } 9737 } 9738 9739 public final void installSystemProviders() { 9740 List<ProviderInfo> providers; 9741 synchronized (this) { 9742 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9743 providers = generateApplicationProvidersLocked(app); 9744 if (providers != null) { 9745 for (int i=providers.size()-1; i>=0; i--) { 9746 ProviderInfo pi = (ProviderInfo)providers.get(i); 9747 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9748 Slog.w(TAG, "Not installing system proc provider " + pi.name 9749 + ": not system .apk"); 9750 providers.remove(i); 9751 } 9752 } 9753 } 9754 } 9755 if (providers != null) { 9756 mSystemThread.installSystemProviders(providers); 9757 } 9758 9759 mCoreSettingsObserver = new CoreSettingsObserver(this); 9760 9761 //mUsageStatsService.monitorPackages(); 9762 } 9763 9764 /** 9765 * Allows apps to retrieve the MIME type of a URI. 9766 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9767 * users, then it does not need permission to access the ContentProvider. 9768 * Either, it needs cross-user uri grants. 9769 * 9770 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9771 * 9772 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9773 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9774 */ 9775 public String getProviderMimeType(Uri uri, int userId) { 9776 enforceNotIsolatedCaller("getProviderMimeType"); 9777 final String name = uri.getAuthority(); 9778 int callingUid = Binder.getCallingUid(); 9779 int callingPid = Binder.getCallingPid(); 9780 long ident = 0; 9781 boolean clearedIdentity = false; 9782 userId = unsafeConvertIncomingUser(userId); 9783 if (canClearIdentity(callingPid, callingUid, userId)) { 9784 clearedIdentity = true; 9785 ident = Binder.clearCallingIdentity(); 9786 } 9787 ContentProviderHolder holder = null; 9788 try { 9789 holder = getContentProviderExternalUnchecked(name, null, userId); 9790 if (holder != null) { 9791 return holder.provider.getType(uri); 9792 } 9793 } catch (RemoteException e) { 9794 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9795 return null; 9796 } finally { 9797 // We need to clear the identity to call removeContentProviderExternalUnchecked 9798 if (!clearedIdentity) { 9799 ident = Binder.clearCallingIdentity(); 9800 } 9801 try { 9802 if (holder != null) { 9803 removeContentProviderExternalUnchecked(name, null, userId); 9804 } 9805 } finally { 9806 Binder.restoreCallingIdentity(ident); 9807 } 9808 } 9809 9810 return null; 9811 } 9812 9813 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9814 if (UserHandle.getUserId(callingUid) == userId) { 9815 return true; 9816 } 9817 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9818 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9819 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9820 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9821 return true; 9822 } 9823 return false; 9824 } 9825 9826 // ========================================================= 9827 // GLOBAL MANAGEMENT 9828 // ========================================================= 9829 9830 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9831 boolean isolated, int isolatedUid) { 9832 String proc = customProcess != null ? customProcess : info.processName; 9833 BatteryStatsImpl.Uid.Proc ps = null; 9834 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9835 int uid = info.uid; 9836 if (isolated) { 9837 if (isolatedUid == 0) { 9838 int userId = UserHandle.getUserId(uid); 9839 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9840 while (true) { 9841 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9842 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9843 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9844 } 9845 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9846 mNextIsolatedProcessUid++; 9847 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9848 // No process for this uid, use it. 9849 break; 9850 } 9851 stepsLeft--; 9852 if (stepsLeft <= 0) { 9853 return null; 9854 } 9855 } 9856 } else { 9857 // Special case for startIsolatedProcess (internal only), where 9858 // the uid of the isolated process is specified by the caller. 9859 uid = isolatedUid; 9860 } 9861 } 9862 return new ProcessRecord(stats, info, proc, uid); 9863 } 9864 9865 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9866 String abiOverride) { 9867 ProcessRecord app; 9868 if (!isolated) { 9869 app = getProcessRecordLocked(info.processName, info.uid, true); 9870 } else { 9871 app = null; 9872 } 9873 9874 if (app == null) { 9875 app = newProcessRecordLocked(info, null, isolated, 0); 9876 mProcessNames.put(info.processName, app.uid, app); 9877 if (isolated) { 9878 mIsolatedProcesses.put(app.uid, app); 9879 } 9880 updateLruProcessLocked(app, false, null); 9881 updateOomAdjLocked(); 9882 } 9883 9884 // This package really, really can not be stopped. 9885 try { 9886 AppGlobals.getPackageManager().setPackageStoppedState( 9887 info.packageName, false, UserHandle.getUserId(app.uid)); 9888 } catch (RemoteException e) { 9889 } catch (IllegalArgumentException e) { 9890 Slog.w(TAG, "Failed trying to unstop package " 9891 + info.packageName + ": " + e); 9892 } 9893 9894 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9895 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9896 app.persistent = true; 9897 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9898 } 9899 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9900 mPersistentStartingProcesses.add(app); 9901 startProcessLocked(app, "added application", app.processName, abiOverride, 9902 null /* entryPoint */, null /* entryPointArgs */); 9903 } 9904 9905 return app; 9906 } 9907 9908 public void unhandledBack() { 9909 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9910 "unhandledBack()"); 9911 9912 synchronized(this) { 9913 final long origId = Binder.clearCallingIdentity(); 9914 try { 9915 getFocusedStack().unhandledBackLocked(); 9916 } finally { 9917 Binder.restoreCallingIdentity(origId); 9918 } 9919 } 9920 } 9921 9922 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9923 enforceNotIsolatedCaller("openContentUri"); 9924 final int userId = UserHandle.getCallingUserId(); 9925 String name = uri.getAuthority(); 9926 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9927 ParcelFileDescriptor pfd = null; 9928 if (cph != null) { 9929 // We record the binder invoker's uid in thread-local storage before 9930 // going to the content provider to open the file. Later, in the code 9931 // that handles all permissions checks, we look for this uid and use 9932 // that rather than the Activity Manager's own uid. The effect is that 9933 // we do the check against the caller's permissions even though it looks 9934 // to the content provider like the Activity Manager itself is making 9935 // the request. 9936 Binder token = new Binder(); 9937 sCallerIdentity.set(new Identity( 9938 token, Binder.getCallingPid(), Binder.getCallingUid())); 9939 try { 9940 pfd = cph.provider.openFile(null, uri, "r", null, token); 9941 } catch (FileNotFoundException e) { 9942 // do nothing; pfd will be returned null 9943 } finally { 9944 // Ensure that whatever happens, we clean up the identity state 9945 sCallerIdentity.remove(); 9946 // Ensure we're done with the provider. 9947 removeContentProviderExternalUnchecked(name, null, userId); 9948 } 9949 } else { 9950 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9951 } 9952 return pfd; 9953 } 9954 9955 // Actually is sleeping or shutting down or whatever else in the future 9956 // is an inactive state. 9957 public boolean isSleepingOrShuttingDown() { 9958 return isSleeping() || mShuttingDown; 9959 } 9960 9961 public boolean isSleeping() { 9962 return mSleeping; 9963 } 9964 9965 void onWakefulnessChanged(int wakefulness) { 9966 synchronized(this) { 9967 mWakefulness = wakefulness; 9968 updateSleepIfNeededLocked(); 9969 } 9970 } 9971 9972 void finishRunningVoiceLocked() { 9973 if (mRunningVoice) { 9974 mRunningVoice = false; 9975 updateSleepIfNeededLocked(); 9976 } 9977 } 9978 9979 void updateSleepIfNeededLocked() { 9980 if (mSleeping && !shouldSleepLocked()) { 9981 mSleeping = false; 9982 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9983 } else if (!mSleeping && shouldSleepLocked()) { 9984 mSleeping = true; 9985 mStackSupervisor.goingToSleepLocked(); 9986 9987 // Initialize the wake times of all processes. 9988 checkExcessivePowerUsageLocked(false); 9989 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9990 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9991 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9992 } 9993 } 9994 9995 private boolean shouldSleepLocked() { 9996 // Resume applications while running a voice interactor. 9997 if (mRunningVoice) { 9998 return false; 9999 } 10000 10001 switch (mWakefulness) { 10002 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10003 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10004 // If we're interactive but applications are already paused then defer 10005 // resuming them until the lock screen is hidden. 10006 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10007 case PowerManagerInternal.WAKEFULNESS_DOZING: 10008 // If we're dozing then pause applications whenever the lock screen is shown. 10009 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10010 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10011 default: 10012 // If we're asleep then pause applications unconditionally. 10013 return true; 10014 } 10015 } 10016 10017 /** Pokes the task persister. */ 10018 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10019 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10020 // Never persist the home stack. 10021 return; 10022 } 10023 mTaskPersister.wakeup(task, flush); 10024 } 10025 10026 /** Notifies all listeners when the task stack has changed. */ 10027 void notifyTaskStackChangedLocked() { 10028 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10029 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10030 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10031 } 10032 10033 @Override 10034 public boolean shutdown(int timeout) { 10035 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10036 != PackageManager.PERMISSION_GRANTED) { 10037 throw new SecurityException("Requires permission " 10038 + android.Manifest.permission.SHUTDOWN); 10039 } 10040 10041 boolean timedout = false; 10042 10043 synchronized(this) { 10044 mShuttingDown = true; 10045 updateEventDispatchingLocked(); 10046 timedout = mStackSupervisor.shutdownLocked(timeout); 10047 } 10048 10049 mAppOpsService.shutdown(); 10050 if (mUsageStatsService != null) { 10051 mUsageStatsService.prepareShutdown(); 10052 } 10053 mBatteryStatsService.shutdown(); 10054 synchronized (this) { 10055 mProcessStats.shutdownLocked(); 10056 notifyTaskPersisterLocked(null, true); 10057 } 10058 10059 return timedout; 10060 } 10061 10062 public final void activitySlept(IBinder token) { 10063 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10064 10065 final long origId = Binder.clearCallingIdentity(); 10066 10067 synchronized (this) { 10068 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10069 if (r != null) { 10070 mStackSupervisor.activitySleptLocked(r); 10071 } 10072 } 10073 10074 Binder.restoreCallingIdentity(origId); 10075 } 10076 10077 private String lockScreenShownToString() { 10078 switch (mLockScreenShown) { 10079 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10080 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10081 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10082 default: return "Unknown=" + mLockScreenShown; 10083 } 10084 } 10085 10086 void logLockScreen(String msg) { 10087 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10088 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10089 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10090 + " mSleeping=" + mSleeping); 10091 } 10092 10093 void startRunningVoiceLocked() { 10094 if (!mRunningVoice) { 10095 mRunningVoice = true; 10096 updateSleepIfNeededLocked(); 10097 } 10098 } 10099 10100 private void updateEventDispatchingLocked() { 10101 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10102 } 10103 10104 public void setLockScreenShown(boolean shown) { 10105 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10106 != PackageManager.PERMISSION_GRANTED) { 10107 throw new SecurityException("Requires permission " 10108 + android.Manifest.permission.DEVICE_POWER); 10109 } 10110 10111 synchronized(this) { 10112 long ident = Binder.clearCallingIdentity(); 10113 try { 10114 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10115 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10116 updateSleepIfNeededLocked(); 10117 } finally { 10118 Binder.restoreCallingIdentity(ident); 10119 } 10120 } 10121 } 10122 10123 @Override 10124 public void stopAppSwitches() { 10125 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10126 != PackageManager.PERMISSION_GRANTED) { 10127 throw new SecurityException("Requires permission " 10128 + android.Manifest.permission.STOP_APP_SWITCHES); 10129 } 10130 10131 synchronized(this) { 10132 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10133 + APP_SWITCH_DELAY_TIME; 10134 mDidAppSwitch = false; 10135 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10136 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10137 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10138 } 10139 } 10140 10141 public void resumeAppSwitches() { 10142 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10143 != PackageManager.PERMISSION_GRANTED) { 10144 throw new SecurityException("Requires permission " 10145 + android.Manifest.permission.STOP_APP_SWITCHES); 10146 } 10147 10148 synchronized(this) { 10149 // Note that we don't execute any pending app switches... we will 10150 // let those wait until either the timeout, or the next start 10151 // activity request. 10152 mAppSwitchesAllowedTime = 0; 10153 } 10154 } 10155 10156 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10157 int callingPid, int callingUid, String name) { 10158 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10159 return true; 10160 } 10161 10162 int perm = checkComponentPermission( 10163 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10164 sourceUid, -1, true); 10165 if (perm == PackageManager.PERMISSION_GRANTED) { 10166 return true; 10167 } 10168 10169 // If the actual IPC caller is different from the logical source, then 10170 // also see if they are allowed to control app switches. 10171 if (callingUid != -1 && callingUid != sourceUid) { 10172 perm = checkComponentPermission( 10173 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10174 callingUid, -1, true); 10175 if (perm == PackageManager.PERMISSION_GRANTED) { 10176 return true; 10177 } 10178 } 10179 10180 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10181 return false; 10182 } 10183 10184 public void setDebugApp(String packageName, boolean waitForDebugger, 10185 boolean persistent) { 10186 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10187 "setDebugApp()"); 10188 10189 long ident = Binder.clearCallingIdentity(); 10190 try { 10191 // Note that this is not really thread safe if there are multiple 10192 // callers into it at the same time, but that's not a situation we 10193 // care about. 10194 if (persistent) { 10195 final ContentResolver resolver = mContext.getContentResolver(); 10196 Settings.Global.putString( 10197 resolver, Settings.Global.DEBUG_APP, 10198 packageName); 10199 Settings.Global.putInt( 10200 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10201 waitForDebugger ? 1 : 0); 10202 } 10203 10204 synchronized (this) { 10205 if (!persistent) { 10206 mOrigDebugApp = mDebugApp; 10207 mOrigWaitForDebugger = mWaitForDebugger; 10208 } 10209 mDebugApp = packageName; 10210 mWaitForDebugger = waitForDebugger; 10211 mDebugTransient = !persistent; 10212 if (packageName != null) { 10213 forceStopPackageLocked(packageName, -1, false, false, true, true, 10214 false, UserHandle.USER_ALL, "set debug app"); 10215 } 10216 } 10217 } finally { 10218 Binder.restoreCallingIdentity(ident); 10219 } 10220 } 10221 10222 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10223 synchronized (this) { 10224 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10225 if (!isDebuggable) { 10226 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10227 throw new SecurityException("Process not debuggable: " + app.packageName); 10228 } 10229 } 10230 10231 mOpenGlTraceApp = processName; 10232 } 10233 } 10234 10235 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10236 synchronized (this) { 10237 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10238 if (!isDebuggable) { 10239 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10240 throw new SecurityException("Process not debuggable: " + app.packageName); 10241 } 10242 } 10243 mProfileApp = processName; 10244 mProfileFile = profilerInfo.profileFile; 10245 if (mProfileFd != null) { 10246 try { 10247 mProfileFd.close(); 10248 } catch (IOException e) { 10249 } 10250 mProfileFd = null; 10251 } 10252 mProfileFd = profilerInfo.profileFd; 10253 mSamplingInterval = profilerInfo.samplingInterval; 10254 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10255 mProfileType = 0; 10256 } 10257 } 10258 10259 @Override 10260 public void setAlwaysFinish(boolean enabled) { 10261 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10262 "setAlwaysFinish()"); 10263 10264 Settings.Global.putInt( 10265 mContext.getContentResolver(), 10266 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10267 10268 synchronized (this) { 10269 mAlwaysFinishActivities = enabled; 10270 } 10271 } 10272 10273 @Override 10274 public void setActivityController(IActivityController controller) { 10275 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10276 "setActivityController()"); 10277 synchronized (this) { 10278 mController = controller; 10279 Watchdog.getInstance().setActivityController(controller); 10280 } 10281 } 10282 10283 @Override 10284 public void setUserIsMonkey(boolean userIsMonkey) { 10285 synchronized (this) { 10286 synchronized (mPidsSelfLocked) { 10287 final int callingPid = Binder.getCallingPid(); 10288 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10289 if (precessRecord == null) { 10290 throw new SecurityException("Unknown process: " + callingPid); 10291 } 10292 if (precessRecord.instrumentationUiAutomationConnection == null) { 10293 throw new SecurityException("Only an instrumentation process " 10294 + "with a UiAutomation can call setUserIsMonkey"); 10295 } 10296 } 10297 mUserIsMonkey = userIsMonkey; 10298 } 10299 } 10300 10301 @Override 10302 public boolean isUserAMonkey() { 10303 synchronized (this) { 10304 // If there is a controller also implies the user is a monkey. 10305 return (mUserIsMonkey || mController != null); 10306 } 10307 } 10308 10309 public void requestBugReport() { 10310 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10311 SystemProperties.set("ctl.start", "bugreport"); 10312 } 10313 10314 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10315 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10316 } 10317 10318 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10319 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10320 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10321 } 10322 return KEY_DISPATCHING_TIMEOUT; 10323 } 10324 10325 @Override 10326 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10327 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10328 != PackageManager.PERMISSION_GRANTED) { 10329 throw new SecurityException("Requires permission " 10330 + android.Manifest.permission.FILTER_EVENTS); 10331 } 10332 ProcessRecord proc; 10333 long timeout; 10334 synchronized (this) { 10335 synchronized (mPidsSelfLocked) { 10336 proc = mPidsSelfLocked.get(pid); 10337 } 10338 timeout = getInputDispatchingTimeoutLocked(proc); 10339 } 10340 10341 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10342 return -1; 10343 } 10344 10345 return timeout; 10346 } 10347 10348 /** 10349 * Handle input dispatching timeouts. 10350 * Returns whether input dispatching should be aborted or not. 10351 */ 10352 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10353 final ActivityRecord activity, final ActivityRecord parent, 10354 final boolean aboveSystem, String reason) { 10355 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10356 != PackageManager.PERMISSION_GRANTED) { 10357 throw new SecurityException("Requires permission " 10358 + android.Manifest.permission.FILTER_EVENTS); 10359 } 10360 10361 final String annotation; 10362 if (reason == null) { 10363 annotation = "Input dispatching timed out"; 10364 } else { 10365 annotation = "Input dispatching timed out (" + reason + ")"; 10366 } 10367 10368 if (proc != null) { 10369 synchronized (this) { 10370 if (proc.debugging) { 10371 return false; 10372 } 10373 10374 if (mDidDexOpt) { 10375 // Give more time since we were dexopting. 10376 mDidDexOpt = false; 10377 return false; 10378 } 10379 10380 if (proc.instrumentationClass != null) { 10381 Bundle info = new Bundle(); 10382 info.putString("shortMsg", "keyDispatchingTimedOut"); 10383 info.putString("longMsg", annotation); 10384 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10385 return true; 10386 } 10387 } 10388 mHandler.post(new Runnable() { 10389 @Override 10390 public void run() { 10391 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10392 } 10393 }); 10394 } 10395 10396 return true; 10397 } 10398 10399 public Bundle getAssistContextExtras(int requestType) { 10400 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10401 UserHandle.getCallingUserId()); 10402 if (pae == null) { 10403 return null; 10404 } 10405 synchronized (pae) { 10406 while (!pae.haveResult) { 10407 try { 10408 pae.wait(); 10409 } catch (InterruptedException e) { 10410 } 10411 } 10412 if (pae.result != null) { 10413 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10414 } 10415 } 10416 synchronized (this) { 10417 mPendingAssistExtras.remove(pae); 10418 mHandler.removeCallbacks(pae); 10419 } 10420 return pae.extras; 10421 } 10422 10423 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10424 int userHandle) { 10425 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10426 "getAssistContextExtras()"); 10427 PendingAssistExtras pae; 10428 Bundle extras = new Bundle(); 10429 synchronized (this) { 10430 ActivityRecord activity = getFocusedStack().mResumedActivity; 10431 if (activity == null) { 10432 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10433 return null; 10434 } 10435 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10436 if (activity.app == null || activity.app.thread == null) { 10437 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10438 return null; 10439 } 10440 if (activity.app.pid == Binder.getCallingPid()) { 10441 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10442 return null; 10443 } 10444 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10445 try { 10446 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10447 requestType); 10448 mPendingAssistExtras.add(pae); 10449 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10450 } catch (RemoteException e) { 10451 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10452 return null; 10453 } 10454 return pae; 10455 } 10456 } 10457 10458 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10459 PendingAssistExtras pae = (PendingAssistExtras)token; 10460 synchronized (pae) { 10461 pae.result = extras; 10462 pae.haveResult = true; 10463 pae.notifyAll(); 10464 if (pae.intent == null) { 10465 // Caller is just waiting for the result. 10466 return; 10467 } 10468 } 10469 10470 // We are now ready to launch the assist activity. 10471 synchronized (this) { 10472 boolean exists = mPendingAssistExtras.remove(pae); 10473 mHandler.removeCallbacks(pae); 10474 if (!exists) { 10475 // Timed out. 10476 return; 10477 } 10478 } 10479 pae.intent.replaceExtras(extras); 10480 if (pae.hint != null) { 10481 pae.intent.putExtra(pae.hint, true); 10482 } 10483 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10484 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10485 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10486 closeSystemDialogs("assist"); 10487 try { 10488 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10489 } catch (ActivityNotFoundException e) { 10490 Slog.w(TAG, "No activity to handle assist action.", e); 10491 } 10492 } 10493 10494 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10495 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10496 } 10497 10498 public void registerProcessObserver(IProcessObserver observer) { 10499 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10500 "registerProcessObserver()"); 10501 synchronized (this) { 10502 mProcessObservers.register(observer); 10503 } 10504 } 10505 10506 @Override 10507 public void unregisterProcessObserver(IProcessObserver observer) { 10508 synchronized (this) { 10509 mProcessObservers.unregister(observer); 10510 } 10511 } 10512 10513 @Override 10514 public boolean convertFromTranslucent(IBinder token) { 10515 final long origId = Binder.clearCallingIdentity(); 10516 try { 10517 synchronized (this) { 10518 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10519 if (r == null) { 10520 return false; 10521 } 10522 final boolean translucentChanged = r.changeWindowTranslucency(true); 10523 if (translucentChanged) { 10524 r.task.stack.releaseBackgroundResources(); 10525 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10526 } 10527 mWindowManager.setAppFullscreen(token, true); 10528 return translucentChanged; 10529 } 10530 } finally { 10531 Binder.restoreCallingIdentity(origId); 10532 } 10533 } 10534 10535 @Override 10536 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10537 final long origId = Binder.clearCallingIdentity(); 10538 try { 10539 synchronized (this) { 10540 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10541 if (r == null) { 10542 return false; 10543 } 10544 int index = r.task.mActivities.lastIndexOf(r); 10545 if (index > 0) { 10546 ActivityRecord under = r.task.mActivities.get(index - 1); 10547 under.returningOptions = options; 10548 } 10549 final boolean translucentChanged = r.changeWindowTranslucency(false); 10550 if (translucentChanged) { 10551 r.task.stack.convertToTranslucent(r); 10552 } 10553 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10554 mWindowManager.setAppFullscreen(token, false); 10555 return translucentChanged; 10556 } 10557 } finally { 10558 Binder.restoreCallingIdentity(origId); 10559 } 10560 } 10561 10562 @Override 10563 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10564 final long origId = Binder.clearCallingIdentity(); 10565 try { 10566 synchronized (this) { 10567 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10568 if (r != null) { 10569 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10570 } 10571 } 10572 return false; 10573 } finally { 10574 Binder.restoreCallingIdentity(origId); 10575 } 10576 } 10577 10578 @Override 10579 public boolean isBackgroundVisibleBehind(IBinder token) { 10580 final long origId = Binder.clearCallingIdentity(); 10581 try { 10582 synchronized (this) { 10583 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10584 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10585 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10586 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10587 return visible; 10588 } 10589 } finally { 10590 Binder.restoreCallingIdentity(origId); 10591 } 10592 } 10593 10594 @Override 10595 public ActivityOptions getActivityOptions(IBinder token) { 10596 final long origId = Binder.clearCallingIdentity(); 10597 try { 10598 synchronized (this) { 10599 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10600 if (r != null) { 10601 final ActivityOptions activityOptions = r.pendingOptions; 10602 r.pendingOptions = null; 10603 return activityOptions; 10604 } 10605 return null; 10606 } 10607 } finally { 10608 Binder.restoreCallingIdentity(origId); 10609 } 10610 } 10611 10612 @Override 10613 public void setImmersive(IBinder token, boolean immersive) { 10614 synchronized(this) { 10615 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10616 if (r == null) { 10617 throw new IllegalArgumentException(); 10618 } 10619 r.immersive = immersive; 10620 10621 // update associated state if we're frontmost 10622 if (r == mFocusedActivity) { 10623 if (DEBUG_IMMERSIVE) { 10624 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10625 } 10626 applyUpdateLockStateLocked(r); 10627 } 10628 } 10629 } 10630 10631 @Override 10632 public boolean isImmersive(IBinder token) { 10633 synchronized (this) { 10634 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10635 if (r == null) { 10636 throw new IllegalArgumentException(); 10637 } 10638 return r.immersive; 10639 } 10640 } 10641 10642 public boolean isTopActivityImmersive() { 10643 enforceNotIsolatedCaller("startActivity"); 10644 synchronized (this) { 10645 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10646 return (r != null) ? r.immersive : false; 10647 } 10648 } 10649 10650 @Override 10651 public boolean isTopOfTask(IBinder token) { 10652 synchronized (this) { 10653 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10654 if (r == null) { 10655 throw new IllegalArgumentException(); 10656 } 10657 return r.task.getTopActivity() == r; 10658 } 10659 } 10660 10661 public final void enterSafeMode() { 10662 synchronized(this) { 10663 // It only makes sense to do this before the system is ready 10664 // and started launching other packages. 10665 if (!mSystemReady) { 10666 try { 10667 AppGlobals.getPackageManager().enterSafeMode(); 10668 } catch (RemoteException e) { 10669 } 10670 } 10671 10672 mSafeMode = true; 10673 } 10674 } 10675 10676 public final void showSafeModeOverlay() { 10677 View v = LayoutInflater.from(mContext).inflate( 10678 com.android.internal.R.layout.safe_mode, null); 10679 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10680 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10681 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10682 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10683 lp.gravity = Gravity.BOTTOM | Gravity.START; 10684 lp.format = v.getBackground().getOpacity(); 10685 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10686 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10687 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10688 ((WindowManager)mContext.getSystemService( 10689 Context.WINDOW_SERVICE)).addView(v, lp); 10690 } 10691 10692 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10693 if (!(sender instanceof PendingIntentRecord)) { 10694 return; 10695 } 10696 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10697 synchronized (stats) { 10698 if (mBatteryStatsService.isOnBattery()) { 10699 mBatteryStatsService.enforceCallingPermission(); 10700 PendingIntentRecord rec = (PendingIntentRecord)sender; 10701 int MY_UID = Binder.getCallingUid(); 10702 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10703 BatteryStatsImpl.Uid.Pkg pkg = 10704 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10705 sourcePkg != null ? sourcePkg : rec.key.packageName); 10706 pkg.incWakeupsLocked(); 10707 } 10708 } 10709 } 10710 10711 public boolean killPids(int[] pids, String pReason, boolean secure) { 10712 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10713 throw new SecurityException("killPids only available to the system"); 10714 } 10715 String reason = (pReason == null) ? "Unknown" : pReason; 10716 // XXX Note: don't acquire main activity lock here, because the window 10717 // manager calls in with its locks held. 10718 10719 boolean killed = false; 10720 synchronized (mPidsSelfLocked) { 10721 int[] types = new int[pids.length]; 10722 int worstType = 0; 10723 for (int i=0; i<pids.length; i++) { 10724 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10725 if (proc != null) { 10726 int type = proc.setAdj; 10727 types[i] = type; 10728 if (type > worstType) { 10729 worstType = type; 10730 } 10731 } 10732 } 10733 10734 // If the worst oom_adj is somewhere in the cached proc LRU range, 10735 // then constrain it so we will kill all cached procs. 10736 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10737 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10738 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10739 } 10740 10741 // If this is not a secure call, don't let it kill processes that 10742 // are important. 10743 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10744 worstType = ProcessList.SERVICE_ADJ; 10745 } 10746 10747 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10748 for (int i=0; i<pids.length; i++) { 10749 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10750 if (proc == null) { 10751 continue; 10752 } 10753 int adj = proc.setAdj; 10754 if (adj >= worstType && !proc.killedByAm) { 10755 proc.kill(reason, true); 10756 killed = true; 10757 } 10758 } 10759 } 10760 return killed; 10761 } 10762 10763 @Override 10764 public void killUid(int uid, String reason) { 10765 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10766 throw new SecurityException("killUid only available to the system"); 10767 } 10768 synchronized (this) { 10769 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10770 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10771 reason != null ? reason : "kill uid"); 10772 } 10773 } 10774 10775 @Override 10776 public boolean killProcessesBelowForeground(String reason) { 10777 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10778 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10779 } 10780 10781 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10782 } 10783 10784 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10785 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10786 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10787 } 10788 10789 boolean killed = false; 10790 synchronized (mPidsSelfLocked) { 10791 final int size = mPidsSelfLocked.size(); 10792 for (int i = 0; i < size; i++) { 10793 final int pid = mPidsSelfLocked.keyAt(i); 10794 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10795 if (proc == null) continue; 10796 10797 final int adj = proc.setAdj; 10798 if (adj > belowAdj && !proc.killedByAm) { 10799 proc.kill(reason, true); 10800 killed = true; 10801 } 10802 } 10803 } 10804 return killed; 10805 } 10806 10807 @Override 10808 public void hang(final IBinder who, boolean allowRestart) { 10809 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10810 != PackageManager.PERMISSION_GRANTED) { 10811 throw new SecurityException("Requires permission " 10812 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10813 } 10814 10815 final IBinder.DeathRecipient death = new DeathRecipient() { 10816 @Override 10817 public void binderDied() { 10818 synchronized (this) { 10819 notifyAll(); 10820 } 10821 } 10822 }; 10823 10824 try { 10825 who.linkToDeath(death, 0); 10826 } catch (RemoteException e) { 10827 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10828 return; 10829 } 10830 10831 synchronized (this) { 10832 Watchdog.getInstance().setAllowRestart(allowRestart); 10833 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10834 synchronized (death) { 10835 while (who.isBinderAlive()) { 10836 try { 10837 death.wait(); 10838 } catch (InterruptedException e) { 10839 } 10840 } 10841 } 10842 Watchdog.getInstance().setAllowRestart(true); 10843 } 10844 } 10845 10846 @Override 10847 public void restart() { 10848 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10849 != PackageManager.PERMISSION_GRANTED) { 10850 throw new SecurityException("Requires permission " 10851 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10852 } 10853 10854 Log.i(TAG, "Sending shutdown broadcast..."); 10855 10856 BroadcastReceiver br = new BroadcastReceiver() { 10857 @Override public void onReceive(Context context, Intent intent) { 10858 // Now the broadcast is done, finish up the low-level shutdown. 10859 Log.i(TAG, "Shutting down activity manager..."); 10860 shutdown(10000); 10861 Log.i(TAG, "Shutdown complete, restarting!"); 10862 Process.killProcess(Process.myPid()); 10863 System.exit(10); 10864 } 10865 }; 10866 10867 // First send the high-level shut down broadcast. 10868 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10869 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10870 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10871 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10872 mContext.sendOrderedBroadcastAsUser(intent, 10873 UserHandle.ALL, null, br, mHandler, 0, null, null); 10874 */ 10875 br.onReceive(mContext, intent); 10876 } 10877 10878 private long getLowRamTimeSinceIdle(long now) { 10879 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10880 } 10881 10882 @Override 10883 public void performIdleMaintenance() { 10884 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10885 != PackageManager.PERMISSION_GRANTED) { 10886 throw new SecurityException("Requires permission " 10887 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10888 } 10889 10890 synchronized (this) { 10891 final long now = SystemClock.uptimeMillis(); 10892 final long timeSinceLastIdle = now - mLastIdleTime; 10893 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10894 mLastIdleTime = now; 10895 mLowRamTimeSinceLastIdle = 0; 10896 if (mLowRamStartTime != 0) { 10897 mLowRamStartTime = now; 10898 } 10899 10900 StringBuilder sb = new StringBuilder(128); 10901 sb.append("Idle maintenance over "); 10902 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10903 sb.append(" low RAM for "); 10904 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10905 Slog.i(TAG, sb.toString()); 10906 10907 // If at least 1/3 of our time since the last idle period has been spent 10908 // with RAM low, then we want to kill processes. 10909 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10910 10911 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10912 ProcessRecord proc = mLruProcesses.get(i); 10913 if (proc.notCachedSinceIdle) { 10914 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10915 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10916 if (doKilling && proc.initialIdlePss != 0 10917 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10918 proc.kill("idle maint (pss " + proc.lastPss 10919 + " from " + proc.initialIdlePss + ")", true); 10920 } 10921 } 10922 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10923 proc.notCachedSinceIdle = true; 10924 proc.initialIdlePss = 0; 10925 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10926 isSleeping(), now); 10927 } 10928 } 10929 10930 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10931 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10932 } 10933 } 10934 10935 private void retrieveSettings() { 10936 final ContentResolver resolver = mContext.getContentResolver(); 10937 String debugApp = Settings.Global.getString( 10938 resolver, Settings.Global.DEBUG_APP); 10939 boolean waitForDebugger = Settings.Global.getInt( 10940 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10941 boolean alwaysFinishActivities = Settings.Global.getInt( 10942 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10943 boolean forceRtl = Settings.Global.getInt( 10944 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10945 // Transfer any global setting for forcing RTL layout, into a System Property 10946 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10947 10948 Configuration configuration = new Configuration(); 10949 Settings.System.getConfiguration(resolver, configuration); 10950 if (forceRtl) { 10951 // This will take care of setting the correct layout direction flags 10952 configuration.setLayoutDirection(configuration.locale); 10953 } 10954 10955 synchronized (this) { 10956 mDebugApp = mOrigDebugApp = debugApp; 10957 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10958 mAlwaysFinishActivities = alwaysFinishActivities; 10959 // This happens before any activities are started, so we can 10960 // change mConfiguration in-place. 10961 updateConfigurationLocked(configuration, null, false, true); 10962 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10963 } 10964 } 10965 10966 /** Loads resources after the current configuration has been set. */ 10967 private void loadResourcesOnSystemReady() { 10968 final Resources res = mContext.getResources(); 10969 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10970 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10971 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10972 } 10973 10974 public boolean testIsSystemReady() { 10975 // no need to synchronize(this) just to read & return the value 10976 return mSystemReady; 10977 } 10978 10979 private static File getCalledPreBootReceiversFile() { 10980 File dataDir = Environment.getDataDirectory(); 10981 File systemDir = new File(dataDir, "system"); 10982 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10983 return fname; 10984 } 10985 10986 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10987 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10988 File file = getCalledPreBootReceiversFile(); 10989 FileInputStream fis = null; 10990 try { 10991 fis = new FileInputStream(file); 10992 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10993 int fvers = dis.readInt(); 10994 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10995 String vers = dis.readUTF(); 10996 String codename = dis.readUTF(); 10997 String build = dis.readUTF(); 10998 if (android.os.Build.VERSION.RELEASE.equals(vers) 10999 && android.os.Build.VERSION.CODENAME.equals(codename) 11000 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11001 int num = dis.readInt(); 11002 while (num > 0) { 11003 num--; 11004 String pkg = dis.readUTF(); 11005 String cls = dis.readUTF(); 11006 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11007 } 11008 } 11009 } 11010 } catch (FileNotFoundException e) { 11011 } catch (IOException e) { 11012 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11013 } finally { 11014 if (fis != null) { 11015 try { 11016 fis.close(); 11017 } catch (IOException e) { 11018 } 11019 } 11020 } 11021 return lastDoneReceivers; 11022 } 11023 11024 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11025 File file = getCalledPreBootReceiversFile(); 11026 FileOutputStream fos = null; 11027 DataOutputStream dos = null; 11028 try { 11029 fos = new FileOutputStream(file); 11030 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11031 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11032 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11033 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11034 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11035 dos.writeInt(list.size()); 11036 for (int i=0; i<list.size(); i++) { 11037 dos.writeUTF(list.get(i).getPackageName()); 11038 dos.writeUTF(list.get(i).getClassName()); 11039 } 11040 } catch (IOException e) { 11041 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11042 file.delete(); 11043 } finally { 11044 FileUtils.sync(fos); 11045 if (dos != null) { 11046 try { 11047 dos.close(); 11048 } catch (IOException e) { 11049 // TODO Auto-generated catch block 11050 e.printStackTrace(); 11051 } 11052 } 11053 } 11054 } 11055 11056 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11057 ArrayList<ComponentName> doneReceivers, int userId) { 11058 boolean waitingUpdate = false; 11059 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11060 List<ResolveInfo> ris = null; 11061 try { 11062 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11063 intent, null, 0, userId); 11064 } catch (RemoteException e) { 11065 } 11066 if (ris != null) { 11067 for (int i=ris.size()-1; i>=0; i--) { 11068 if ((ris.get(i).activityInfo.applicationInfo.flags 11069 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11070 ris.remove(i); 11071 } 11072 } 11073 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11074 11075 // For User 0, load the version number. When delivering to a new user, deliver 11076 // to all receivers. 11077 if (userId == UserHandle.USER_OWNER) { 11078 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11079 for (int i=0; i<ris.size(); i++) { 11080 ActivityInfo ai = ris.get(i).activityInfo; 11081 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11082 if (lastDoneReceivers.contains(comp)) { 11083 // We already did the pre boot receiver for this app with the current 11084 // platform version, so don't do it again... 11085 ris.remove(i); 11086 i--; 11087 // ...however, do keep it as one that has been done, so we don't 11088 // forget about it when rewriting the file of last done receivers. 11089 doneReceivers.add(comp); 11090 } 11091 } 11092 } 11093 11094 // If primary user, send broadcast to all available users, else just to userId 11095 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11096 : new int[] { userId }; 11097 for (int i = 0; i < ris.size(); i++) { 11098 ActivityInfo ai = ris.get(i).activityInfo; 11099 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11100 doneReceivers.add(comp); 11101 intent.setComponent(comp); 11102 for (int j=0; j<users.length; j++) { 11103 IIntentReceiver finisher = null; 11104 // On last receiver and user, set up a completion callback 11105 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11106 finisher = new IIntentReceiver.Stub() { 11107 public void performReceive(Intent intent, int resultCode, 11108 String data, Bundle extras, boolean ordered, 11109 boolean sticky, int sendingUser) { 11110 // The raw IIntentReceiver interface is called 11111 // with the AM lock held, so redispatch to 11112 // execute our code without the lock. 11113 mHandler.post(onFinishCallback); 11114 } 11115 }; 11116 } 11117 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11118 + " for user " + users[j]); 11119 broadcastIntentLocked(null, null, intent, null, finisher, 11120 0, null, null, null, AppOpsManager.OP_NONE, 11121 true, false, MY_PID, Process.SYSTEM_UID, 11122 users[j]); 11123 if (finisher != null) { 11124 waitingUpdate = true; 11125 } 11126 } 11127 } 11128 } 11129 11130 return waitingUpdate; 11131 } 11132 11133 public void systemReady(final Runnable goingCallback) { 11134 synchronized(this) { 11135 if (mSystemReady) { 11136 // If we're done calling all the receivers, run the next "boot phase" passed in 11137 // by the SystemServer 11138 if (goingCallback != null) { 11139 goingCallback.run(); 11140 } 11141 return; 11142 } 11143 11144 // Make sure we have the current profile info, since it is needed for 11145 // security checks. 11146 updateCurrentProfileIdsLocked(); 11147 11148 if (mRecentTasks == null) { 11149 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11150 if (!mRecentTasks.isEmpty()) { 11151 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11152 } 11153 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11154 mTaskPersister.startPersisting(); 11155 } 11156 11157 // Check to see if there are any update receivers to run. 11158 if (!mDidUpdate) { 11159 if (mWaitingUpdate) { 11160 return; 11161 } 11162 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11163 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11164 public void run() { 11165 synchronized (ActivityManagerService.this) { 11166 mDidUpdate = true; 11167 } 11168 writeLastDonePreBootReceivers(doneReceivers); 11169 showBootMessage(mContext.getText( 11170 R.string.android_upgrading_complete), 11171 false); 11172 systemReady(goingCallback); 11173 } 11174 }, doneReceivers, UserHandle.USER_OWNER); 11175 11176 if (mWaitingUpdate) { 11177 return; 11178 } 11179 mDidUpdate = true; 11180 } 11181 11182 mAppOpsService.systemReady(); 11183 mSystemReady = true; 11184 } 11185 11186 ArrayList<ProcessRecord> procsToKill = null; 11187 synchronized(mPidsSelfLocked) { 11188 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11189 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11190 if (!isAllowedWhileBooting(proc.info)){ 11191 if (procsToKill == null) { 11192 procsToKill = new ArrayList<ProcessRecord>(); 11193 } 11194 procsToKill.add(proc); 11195 } 11196 } 11197 } 11198 11199 synchronized(this) { 11200 if (procsToKill != null) { 11201 for (int i=procsToKill.size()-1; i>=0; i--) { 11202 ProcessRecord proc = procsToKill.get(i); 11203 Slog.i(TAG, "Removing system update proc: " + proc); 11204 removeProcessLocked(proc, true, false, "system update done"); 11205 } 11206 } 11207 11208 // Now that we have cleaned up any update processes, we 11209 // are ready to start launching real processes and know that 11210 // we won't trample on them any more. 11211 mProcessesReady = true; 11212 } 11213 11214 Slog.i(TAG, "System now ready"); 11215 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11216 SystemClock.uptimeMillis()); 11217 11218 synchronized(this) { 11219 // Make sure we have no pre-ready processes sitting around. 11220 11221 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11222 ResolveInfo ri = mContext.getPackageManager() 11223 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11224 STOCK_PM_FLAGS); 11225 CharSequence errorMsg = null; 11226 if (ri != null) { 11227 ActivityInfo ai = ri.activityInfo; 11228 ApplicationInfo app = ai.applicationInfo; 11229 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11230 mTopAction = Intent.ACTION_FACTORY_TEST; 11231 mTopData = null; 11232 mTopComponent = new ComponentName(app.packageName, 11233 ai.name); 11234 } else { 11235 errorMsg = mContext.getResources().getText( 11236 com.android.internal.R.string.factorytest_not_system); 11237 } 11238 } else { 11239 errorMsg = mContext.getResources().getText( 11240 com.android.internal.R.string.factorytest_no_action); 11241 } 11242 if (errorMsg != null) { 11243 mTopAction = null; 11244 mTopData = null; 11245 mTopComponent = null; 11246 Message msg = Message.obtain(); 11247 msg.what = SHOW_FACTORY_ERROR_MSG; 11248 msg.getData().putCharSequence("msg", errorMsg); 11249 mHandler.sendMessage(msg); 11250 } 11251 } 11252 } 11253 11254 retrieveSettings(); 11255 loadResourcesOnSystemReady(); 11256 11257 synchronized (this) { 11258 readGrantedUriPermissionsLocked(); 11259 } 11260 11261 if (goingCallback != null) goingCallback.run(); 11262 11263 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11264 Integer.toString(mCurrentUserId), mCurrentUserId); 11265 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11266 Integer.toString(mCurrentUserId), mCurrentUserId); 11267 mSystemServiceManager.startUser(mCurrentUserId); 11268 11269 synchronized (this) { 11270 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11271 try { 11272 List apps = AppGlobals.getPackageManager(). 11273 getPersistentApplications(STOCK_PM_FLAGS); 11274 if (apps != null) { 11275 int N = apps.size(); 11276 int i; 11277 for (i=0; i<N; i++) { 11278 ApplicationInfo info 11279 = (ApplicationInfo)apps.get(i); 11280 if (info != null && 11281 !info.packageName.equals("android")) { 11282 addAppLocked(info, false, null /* ABI override */); 11283 } 11284 } 11285 } 11286 } catch (RemoteException ex) { 11287 // pm is in same process, this will never happen. 11288 } 11289 } 11290 11291 // Start up initial activity. 11292 mBooting = true; 11293 startHomeActivityLocked(mCurrentUserId); 11294 11295 try { 11296 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11297 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11298 + " data partition or your device will be unstable."); 11299 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11300 } 11301 } catch (RemoteException e) { 11302 } 11303 11304 if (!Build.isFingerprintConsistent()) { 11305 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11306 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11307 } 11308 11309 long ident = Binder.clearCallingIdentity(); 11310 try { 11311 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11312 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11313 | Intent.FLAG_RECEIVER_FOREGROUND); 11314 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11315 broadcastIntentLocked(null, null, intent, 11316 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11317 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11318 intent = new Intent(Intent.ACTION_USER_STARTING); 11319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11320 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11321 broadcastIntentLocked(null, null, intent, 11322 null, new IIntentReceiver.Stub() { 11323 @Override 11324 public void performReceive(Intent intent, int resultCode, String data, 11325 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11326 throws RemoteException { 11327 } 11328 }, 0, null, null, 11329 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11330 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11331 } catch (Throwable t) { 11332 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11333 } finally { 11334 Binder.restoreCallingIdentity(ident); 11335 } 11336 mStackSupervisor.resumeTopActivitiesLocked(); 11337 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11338 } 11339 } 11340 11341 private boolean makeAppCrashingLocked(ProcessRecord app, 11342 String shortMsg, String longMsg, String stackTrace) { 11343 app.crashing = true; 11344 app.crashingReport = generateProcessError(app, 11345 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11346 startAppProblemLocked(app); 11347 app.stopFreezingAllLocked(); 11348 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11349 } 11350 11351 private void makeAppNotRespondingLocked(ProcessRecord app, 11352 String activity, String shortMsg, String longMsg) { 11353 app.notResponding = true; 11354 app.notRespondingReport = generateProcessError(app, 11355 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11356 activity, shortMsg, longMsg, null); 11357 startAppProblemLocked(app); 11358 app.stopFreezingAllLocked(); 11359 } 11360 11361 /** 11362 * Generate a process error record, suitable for attachment to a ProcessRecord. 11363 * 11364 * @param app The ProcessRecord in which the error occurred. 11365 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11366 * ActivityManager.AppErrorStateInfo 11367 * @param activity The activity associated with the crash, if known. 11368 * @param shortMsg Short message describing the crash. 11369 * @param longMsg Long message describing the crash. 11370 * @param stackTrace Full crash stack trace, may be null. 11371 * 11372 * @return Returns a fully-formed AppErrorStateInfo record. 11373 */ 11374 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11375 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11376 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11377 11378 report.condition = condition; 11379 report.processName = app.processName; 11380 report.pid = app.pid; 11381 report.uid = app.info.uid; 11382 report.tag = activity; 11383 report.shortMsg = shortMsg; 11384 report.longMsg = longMsg; 11385 report.stackTrace = stackTrace; 11386 11387 return report; 11388 } 11389 11390 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11391 synchronized (this) { 11392 app.crashing = false; 11393 app.crashingReport = null; 11394 app.notResponding = false; 11395 app.notRespondingReport = null; 11396 if (app.anrDialog == fromDialog) { 11397 app.anrDialog = null; 11398 } 11399 if (app.waitDialog == fromDialog) { 11400 app.waitDialog = null; 11401 } 11402 if (app.pid > 0 && app.pid != MY_PID) { 11403 handleAppCrashLocked(app, null, null, null); 11404 app.kill("user request after error", true); 11405 } 11406 } 11407 } 11408 11409 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11410 String stackTrace) { 11411 long now = SystemClock.uptimeMillis(); 11412 11413 Long crashTime; 11414 if (!app.isolated) { 11415 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11416 } else { 11417 crashTime = null; 11418 } 11419 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11420 // This process loses! 11421 Slog.w(TAG, "Process " + app.info.processName 11422 + " has crashed too many times: killing!"); 11423 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11424 app.userId, app.info.processName, app.uid); 11425 mStackSupervisor.handleAppCrashLocked(app); 11426 if (!app.persistent) { 11427 // We don't want to start this process again until the user 11428 // explicitly does so... but for persistent process, we really 11429 // need to keep it running. If a persistent process is actually 11430 // repeatedly crashing, then badness for everyone. 11431 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11432 app.info.processName); 11433 if (!app.isolated) { 11434 // XXX We don't have a way to mark isolated processes 11435 // as bad, since they don't have a peristent identity. 11436 mBadProcesses.put(app.info.processName, app.uid, 11437 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11438 mProcessCrashTimes.remove(app.info.processName, app.uid); 11439 } 11440 app.bad = true; 11441 app.removed = true; 11442 // Don't let services in this process be restarted and potentially 11443 // annoy the user repeatedly. Unless it is persistent, since those 11444 // processes run critical code. 11445 removeProcessLocked(app, false, false, "crash"); 11446 mStackSupervisor.resumeTopActivitiesLocked(); 11447 return false; 11448 } 11449 mStackSupervisor.resumeTopActivitiesLocked(); 11450 } else { 11451 mStackSupervisor.finishTopRunningActivityLocked(app); 11452 } 11453 11454 // Bump up the crash count of any services currently running in the proc. 11455 for (int i=app.services.size()-1; i>=0; i--) { 11456 // Any services running in the application need to be placed 11457 // back in the pending list. 11458 ServiceRecord sr = app.services.valueAt(i); 11459 sr.crashCount++; 11460 } 11461 11462 // If the crashing process is what we consider to be the "home process" and it has been 11463 // replaced by a third-party app, clear the package preferred activities from packages 11464 // with a home activity running in the process to prevent a repeatedly crashing app 11465 // from blocking the user to manually clear the list. 11466 final ArrayList<ActivityRecord> activities = app.activities; 11467 if (app == mHomeProcess && activities.size() > 0 11468 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11469 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11470 final ActivityRecord r = activities.get(activityNdx); 11471 if (r.isHomeActivity()) { 11472 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11473 try { 11474 ActivityThread.getPackageManager() 11475 .clearPackagePreferredActivities(r.packageName); 11476 } catch (RemoteException c) { 11477 // pm is in same process, this will never happen. 11478 } 11479 } 11480 } 11481 } 11482 11483 if (!app.isolated) { 11484 // XXX Can't keep track of crash times for isolated processes, 11485 // because they don't have a perisistent identity. 11486 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11487 } 11488 11489 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11490 return true; 11491 } 11492 11493 void startAppProblemLocked(ProcessRecord app) { 11494 // If this app is not running under the current user, then we 11495 // can't give it a report button because that would require 11496 // launching the report UI under a different user. 11497 app.errorReportReceiver = null; 11498 11499 for (int userId : mCurrentProfileIds) { 11500 if (app.userId == userId) { 11501 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11502 mContext, app.info.packageName, app.info.flags); 11503 } 11504 } 11505 skipCurrentReceiverLocked(app); 11506 } 11507 11508 void skipCurrentReceiverLocked(ProcessRecord app) { 11509 for (BroadcastQueue queue : mBroadcastQueues) { 11510 queue.skipCurrentReceiverLocked(app); 11511 } 11512 } 11513 11514 /** 11515 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11516 * The application process will exit immediately after this call returns. 11517 * @param app object of the crashing app, null for the system server 11518 * @param crashInfo describing the exception 11519 */ 11520 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11521 ProcessRecord r = findAppProcess(app, "Crash"); 11522 final String processName = app == null ? "system_server" 11523 : (r == null ? "unknown" : r.processName); 11524 11525 handleApplicationCrashInner("crash", r, processName, crashInfo); 11526 } 11527 11528 /* Native crash reporting uses this inner version because it needs to be somewhat 11529 * decoupled from the AM-managed cleanup lifecycle 11530 */ 11531 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11532 ApplicationErrorReport.CrashInfo crashInfo) { 11533 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11534 UserHandle.getUserId(Binder.getCallingUid()), processName, 11535 r == null ? -1 : r.info.flags, 11536 crashInfo.exceptionClassName, 11537 crashInfo.exceptionMessage, 11538 crashInfo.throwFileName, 11539 crashInfo.throwLineNumber); 11540 11541 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11542 11543 crashApplication(r, crashInfo); 11544 } 11545 11546 public void handleApplicationStrictModeViolation( 11547 IBinder app, 11548 int violationMask, 11549 StrictMode.ViolationInfo info) { 11550 ProcessRecord r = findAppProcess(app, "StrictMode"); 11551 if (r == null) { 11552 return; 11553 } 11554 11555 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11556 Integer stackFingerprint = info.hashCode(); 11557 boolean logIt = true; 11558 synchronized (mAlreadyLoggedViolatedStacks) { 11559 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11560 logIt = false; 11561 // TODO: sub-sample into EventLog for these, with 11562 // the info.durationMillis? Then we'd get 11563 // the relative pain numbers, without logging all 11564 // the stack traces repeatedly. We'd want to do 11565 // likewise in the client code, which also does 11566 // dup suppression, before the Binder call. 11567 } else { 11568 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11569 mAlreadyLoggedViolatedStacks.clear(); 11570 } 11571 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11572 } 11573 } 11574 if (logIt) { 11575 logStrictModeViolationToDropBox(r, info); 11576 } 11577 } 11578 11579 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11580 AppErrorResult result = new AppErrorResult(); 11581 synchronized (this) { 11582 final long origId = Binder.clearCallingIdentity(); 11583 11584 Message msg = Message.obtain(); 11585 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11586 HashMap<String, Object> data = new HashMap<String, Object>(); 11587 data.put("result", result); 11588 data.put("app", r); 11589 data.put("violationMask", violationMask); 11590 data.put("info", info); 11591 msg.obj = data; 11592 mHandler.sendMessage(msg); 11593 11594 Binder.restoreCallingIdentity(origId); 11595 } 11596 int res = result.get(); 11597 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11598 } 11599 } 11600 11601 // Depending on the policy in effect, there could be a bunch of 11602 // these in quick succession so we try to batch these together to 11603 // minimize disk writes, number of dropbox entries, and maximize 11604 // compression, by having more fewer, larger records. 11605 private void logStrictModeViolationToDropBox( 11606 ProcessRecord process, 11607 StrictMode.ViolationInfo info) { 11608 if (info == null) { 11609 return; 11610 } 11611 final boolean isSystemApp = process == null || 11612 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11613 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11614 final String processName = process == null ? "unknown" : process.processName; 11615 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11616 final DropBoxManager dbox = (DropBoxManager) 11617 mContext.getSystemService(Context.DROPBOX_SERVICE); 11618 11619 // Exit early if the dropbox isn't configured to accept this report type. 11620 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11621 11622 boolean bufferWasEmpty; 11623 boolean needsFlush; 11624 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11625 synchronized (sb) { 11626 bufferWasEmpty = sb.length() == 0; 11627 appendDropBoxProcessHeaders(process, processName, sb); 11628 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11629 sb.append("System-App: ").append(isSystemApp).append("\n"); 11630 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11631 if (info.violationNumThisLoop != 0) { 11632 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11633 } 11634 if (info.numAnimationsRunning != 0) { 11635 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11636 } 11637 if (info.broadcastIntentAction != null) { 11638 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11639 } 11640 if (info.durationMillis != -1) { 11641 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11642 } 11643 if (info.numInstances != -1) { 11644 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11645 } 11646 if (info.tags != null) { 11647 for (String tag : info.tags) { 11648 sb.append("Span-Tag: ").append(tag).append("\n"); 11649 } 11650 } 11651 sb.append("\n"); 11652 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11653 sb.append(info.crashInfo.stackTrace); 11654 } 11655 sb.append("\n"); 11656 11657 // Only buffer up to ~64k. Various logging bits truncate 11658 // things at 128k. 11659 needsFlush = (sb.length() > 64 * 1024); 11660 } 11661 11662 // Flush immediately if the buffer's grown too large, or this 11663 // is a non-system app. Non-system apps are isolated with a 11664 // different tag & policy and not batched. 11665 // 11666 // Batching is useful during internal testing with 11667 // StrictMode settings turned up high. Without batching, 11668 // thousands of separate files could be created on boot. 11669 if (!isSystemApp || needsFlush) { 11670 new Thread("Error dump: " + dropboxTag) { 11671 @Override 11672 public void run() { 11673 String report; 11674 synchronized (sb) { 11675 report = sb.toString(); 11676 sb.delete(0, sb.length()); 11677 sb.trimToSize(); 11678 } 11679 if (report.length() != 0) { 11680 dbox.addText(dropboxTag, report); 11681 } 11682 } 11683 }.start(); 11684 return; 11685 } 11686 11687 // System app batching: 11688 if (!bufferWasEmpty) { 11689 // An existing dropbox-writing thread is outstanding, so 11690 // we don't need to start it up. The existing thread will 11691 // catch the buffer appends we just did. 11692 return; 11693 } 11694 11695 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11696 // (After this point, we shouldn't access AMS internal data structures.) 11697 new Thread("Error dump: " + dropboxTag) { 11698 @Override 11699 public void run() { 11700 // 5 second sleep to let stacks arrive and be batched together 11701 try { 11702 Thread.sleep(5000); // 5 seconds 11703 } catch (InterruptedException e) {} 11704 11705 String errorReport; 11706 synchronized (mStrictModeBuffer) { 11707 errorReport = mStrictModeBuffer.toString(); 11708 if (errorReport.length() == 0) { 11709 return; 11710 } 11711 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11712 mStrictModeBuffer.trimToSize(); 11713 } 11714 dbox.addText(dropboxTag, errorReport); 11715 } 11716 }.start(); 11717 } 11718 11719 /** 11720 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11721 * @param app object of the crashing app, null for the system server 11722 * @param tag reported by the caller 11723 * @param system whether this wtf is coming from the system 11724 * @param crashInfo describing the context of the error 11725 * @return true if the process should exit immediately (WTF is fatal) 11726 */ 11727 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11728 final ApplicationErrorReport.CrashInfo crashInfo) { 11729 final int callingUid = Binder.getCallingUid(); 11730 final int callingPid = Binder.getCallingPid(); 11731 11732 if (system) { 11733 // If this is coming from the system, we could very well have low-level 11734 // system locks held, so we want to do this all asynchronously. And we 11735 // never want this to become fatal, so there is that too. 11736 mHandler.post(new Runnable() { 11737 @Override public void run() { 11738 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11739 } 11740 }); 11741 return false; 11742 } 11743 11744 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11745 crashInfo); 11746 11747 if (r != null && r.pid != Process.myPid() && 11748 Settings.Global.getInt(mContext.getContentResolver(), 11749 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11750 crashApplication(r, crashInfo); 11751 return true; 11752 } else { 11753 return false; 11754 } 11755 } 11756 11757 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11758 final ApplicationErrorReport.CrashInfo crashInfo) { 11759 final ProcessRecord r = findAppProcess(app, "WTF"); 11760 final String processName = app == null ? "system_server" 11761 : (r == null ? "unknown" : r.processName); 11762 11763 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11764 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11765 11766 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11767 11768 return r; 11769 } 11770 11771 /** 11772 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11773 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11774 */ 11775 private ProcessRecord findAppProcess(IBinder app, String reason) { 11776 if (app == null) { 11777 return null; 11778 } 11779 11780 synchronized (this) { 11781 final int NP = mProcessNames.getMap().size(); 11782 for (int ip=0; ip<NP; ip++) { 11783 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11784 final int NA = apps.size(); 11785 for (int ia=0; ia<NA; ia++) { 11786 ProcessRecord p = apps.valueAt(ia); 11787 if (p.thread != null && p.thread.asBinder() == app) { 11788 return p; 11789 } 11790 } 11791 } 11792 11793 Slog.w(TAG, "Can't find mystery application for " + reason 11794 + " from pid=" + Binder.getCallingPid() 11795 + " uid=" + Binder.getCallingUid() + ": " + app); 11796 return null; 11797 } 11798 } 11799 11800 /** 11801 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11802 * to append various headers to the dropbox log text. 11803 */ 11804 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11805 StringBuilder sb) { 11806 // Watchdog thread ends up invoking this function (with 11807 // a null ProcessRecord) to add the stack file to dropbox. 11808 // Do not acquire a lock on this (am) in such cases, as it 11809 // could cause a potential deadlock, if and when watchdog 11810 // is invoked due to unavailability of lock on am and it 11811 // would prevent watchdog from killing system_server. 11812 if (process == null) { 11813 sb.append("Process: ").append(processName).append("\n"); 11814 return; 11815 } 11816 // Note: ProcessRecord 'process' is guarded by the service 11817 // instance. (notably process.pkgList, which could otherwise change 11818 // concurrently during execution of this method) 11819 synchronized (this) { 11820 sb.append("Process: ").append(processName).append("\n"); 11821 int flags = process.info.flags; 11822 IPackageManager pm = AppGlobals.getPackageManager(); 11823 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11824 for (int ip=0; ip<process.pkgList.size(); ip++) { 11825 String pkg = process.pkgList.keyAt(ip); 11826 sb.append("Package: ").append(pkg); 11827 try { 11828 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11829 if (pi != null) { 11830 sb.append(" v").append(pi.versionCode); 11831 if (pi.versionName != null) { 11832 sb.append(" (").append(pi.versionName).append(")"); 11833 } 11834 } 11835 } catch (RemoteException e) { 11836 Slog.e(TAG, "Error getting package info: " + pkg, e); 11837 } 11838 sb.append("\n"); 11839 } 11840 } 11841 } 11842 11843 private static String processClass(ProcessRecord process) { 11844 if (process == null || process.pid == MY_PID) { 11845 return "system_server"; 11846 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11847 return "system_app"; 11848 } else { 11849 return "data_app"; 11850 } 11851 } 11852 11853 /** 11854 * Write a description of an error (crash, WTF, ANR) to the drop box. 11855 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11856 * @param process which caused the error, null means the system server 11857 * @param activity which triggered the error, null if unknown 11858 * @param parent activity related to the error, null if unknown 11859 * @param subject line related to the error, null if absent 11860 * @param report in long form describing the error, null if absent 11861 * @param logFile to include in the report, null if none 11862 * @param crashInfo giving an application stack trace, null if absent 11863 */ 11864 public void addErrorToDropBox(String eventType, 11865 ProcessRecord process, String processName, ActivityRecord activity, 11866 ActivityRecord parent, String subject, 11867 final String report, final File logFile, 11868 final ApplicationErrorReport.CrashInfo crashInfo) { 11869 // NOTE -- this must never acquire the ActivityManagerService lock, 11870 // otherwise the watchdog may be prevented from resetting the system. 11871 11872 final String dropboxTag = processClass(process) + "_" + eventType; 11873 final DropBoxManager dbox = (DropBoxManager) 11874 mContext.getSystemService(Context.DROPBOX_SERVICE); 11875 11876 // Exit early if the dropbox isn't configured to accept this report type. 11877 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11878 11879 final StringBuilder sb = new StringBuilder(1024); 11880 appendDropBoxProcessHeaders(process, processName, sb); 11881 if (activity != null) { 11882 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11883 } 11884 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11885 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11886 } 11887 if (parent != null && parent != activity) { 11888 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11889 } 11890 if (subject != null) { 11891 sb.append("Subject: ").append(subject).append("\n"); 11892 } 11893 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11894 if (Debug.isDebuggerConnected()) { 11895 sb.append("Debugger: Connected\n"); 11896 } 11897 sb.append("\n"); 11898 11899 // Do the rest in a worker thread to avoid blocking the caller on I/O 11900 // (After this point, we shouldn't access AMS internal data structures.) 11901 Thread worker = new Thread("Error dump: " + dropboxTag) { 11902 @Override 11903 public void run() { 11904 if (report != null) { 11905 sb.append(report); 11906 } 11907 if (logFile != null) { 11908 try { 11909 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11910 "\n\n[[TRUNCATED]]")); 11911 } catch (IOException e) { 11912 Slog.e(TAG, "Error reading " + logFile, e); 11913 } 11914 } 11915 if (crashInfo != null && crashInfo.stackTrace != null) { 11916 sb.append(crashInfo.stackTrace); 11917 } 11918 11919 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11920 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11921 if (lines > 0) { 11922 sb.append("\n"); 11923 11924 // Merge several logcat streams, and take the last N lines 11925 InputStreamReader input = null; 11926 try { 11927 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11928 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11929 "-b", "crash", 11930 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11931 11932 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11933 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11934 input = new InputStreamReader(logcat.getInputStream()); 11935 11936 int num; 11937 char[] buf = new char[8192]; 11938 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11939 } catch (IOException e) { 11940 Slog.e(TAG, "Error running logcat", e); 11941 } finally { 11942 if (input != null) try { input.close(); } catch (IOException e) {} 11943 } 11944 } 11945 11946 dbox.addText(dropboxTag, sb.toString()); 11947 } 11948 }; 11949 11950 if (process == null) { 11951 // If process is null, we are being called from some internal code 11952 // and may be about to die -- run this synchronously. 11953 worker.run(); 11954 } else { 11955 worker.start(); 11956 } 11957 } 11958 11959 /** 11960 * Bring up the "unexpected error" dialog box for a crashing app. 11961 * Deal with edge cases (intercepts from instrumented applications, 11962 * ActivityController, error intent receivers, that sort of thing). 11963 * @param r the application crashing 11964 * @param crashInfo describing the failure 11965 */ 11966 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11967 long timeMillis = System.currentTimeMillis(); 11968 String shortMsg = crashInfo.exceptionClassName; 11969 String longMsg = crashInfo.exceptionMessage; 11970 String stackTrace = crashInfo.stackTrace; 11971 if (shortMsg != null && longMsg != null) { 11972 longMsg = shortMsg + ": " + longMsg; 11973 } else if (shortMsg != null) { 11974 longMsg = shortMsg; 11975 } 11976 11977 AppErrorResult result = new AppErrorResult(); 11978 synchronized (this) { 11979 if (mController != null) { 11980 try { 11981 String name = r != null ? r.processName : null; 11982 int pid = r != null ? r.pid : Binder.getCallingPid(); 11983 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11984 if (!mController.appCrashed(name, pid, 11985 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11986 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11987 && "Native crash".equals(crashInfo.exceptionClassName)) { 11988 Slog.w(TAG, "Skip killing native crashed app " + name 11989 + "(" + pid + ") during testing"); 11990 } else { 11991 Slog.w(TAG, "Force-killing crashed app " + name 11992 + " at watcher's request"); 11993 if (r != null) { 11994 r.kill("crash", true); 11995 } else { 11996 // Huh. 11997 Process.killProcess(pid); 11998 Process.killProcessGroup(uid, pid); 11999 } 12000 } 12001 return; 12002 } 12003 } catch (RemoteException e) { 12004 mController = null; 12005 Watchdog.getInstance().setActivityController(null); 12006 } 12007 } 12008 12009 final long origId = Binder.clearCallingIdentity(); 12010 12011 // If this process is running instrumentation, finish it. 12012 if (r != null && r.instrumentationClass != null) { 12013 Slog.w(TAG, "Error in app " + r.processName 12014 + " running instrumentation " + r.instrumentationClass + ":"); 12015 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12016 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12017 Bundle info = new Bundle(); 12018 info.putString("shortMsg", shortMsg); 12019 info.putString("longMsg", longMsg); 12020 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12021 Binder.restoreCallingIdentity(origId); 12022 return; 12023 } 12024 12025 // If we can't identify the process or it's already exceeded its crash quota, 12026 // quit right away without showing a crash dialog. 12027 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12028 Binder.restoreCallingIdentity(origId); 12029 return; 12030 } 12031 12032 Message msg = Message.obtain(); 12033 msg.what = SHOW_ERROR_MSG; 12034 HashMap data = new HashMap(); 12035 data.put("result", result); 12036 data.put("app", r); 12037 msg.obj = data; 12038 mHandler.sendMessage(msg); 12039 12040 Binder.restoreCallingIdentity(origId); 12041 } 12042 12043 int res = result.get(); 12044 12045 Intent appErrorIntent = null; 12046 synchronized (this) { 12047 if (r != null && !r.isolated) { 12048 // XXX Can't keep track of crash time for isolated processes, 12049 // since they don't have a persistent identity. 12050 mProcessCrashTimes.put(r.info.processName, r.uid, 12051 SystemClock.uptimeMillis()); 12052 } 12053 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12054 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12055 } 12056 } 12057 12058 if (appErrorIntent != null) { 12059 try { 12060 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12061 } catch (ActivityNotFoundException e) { 12062 Slog.w(TAG, "bug report receiver dissappeared", e); 12063 } 12064 } 12065 } 12066 12067 Intent createAppErrorIntentLocked(ProcessRecord r, 12068 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12069 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12070 if (report == null) { 12071 return null; 12072 } 12073 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12074 result.setComponent(r.errorReportReceiver); 12075 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12076 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12077 return result; 12078 } 12079 12080 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12081 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12082 if (r.errorReportReceiver == null) { 12083 return null; 12084 } 12085 12086 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12087 return null; 12088 } 12089 12090 ApplicationErrorReport report = new ApplicationErrorReport(); 12091 report.packageName = r.info.packageName; 12092 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12093 report.processName = r.processName; 12094 report.time = timeMillis; 12095 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12096 12097 if (r.crashing || r.forceCrashReport) { 12098 report.type = ApplicationErrorReport.TYPE_CRASH; 12099 report.crashInfo = crashInfo; 12100 } else if (r.notResponding) { 12101 report.type = ApplicationErrorReport.TYPE_ANR; 12102 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12103 12104 report.anrInfo.activity = r.notRespondingReport.tag; 12105 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12106 report.anrInfo.info = r.notRespondingReport.longMsg; 12107 } 12108 12109 return report; 12110 } 12111 12112 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12113 enforceNotIsolatedCaller("getProcessesInErrorState"); 12114 // assume our apps are happy - lazy create the list 12115 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12116 12117 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12118 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12119 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12120 12121 synchronized (this) { 12122 12123 // iterate across all processes 12124 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12125 ProcessRecord app = mLruProcesses.get(i); 12126 if (!allUsers && app.userId != userId) { 12127 continue; 12128 } 12129 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12130 // This one's in trouble, so we'll generate a report for it 12131 // crashes are higher priority (in case there's a crash *and* an anr) 12132 ActivityManager.ProcessErrorStateInfo report = null; 12133 if (app.crashing) { 12134 report = app.crashingReport; 12135 } else if (app.notResponding) { 12136 report = app.notRespondingReport; 12137 } 12138 12139 if (report != null) { 12140 if (errList == null) { 12141 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12142 } 12143 errList.add(report); 12144 } else { 12145 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12146 " crashing = " + app.crashing + 12147 " notResponding = " + app.notResponding); 12148 } 12149 } 12150 } 12151 } 12152 12153 return errList; 12154 } 12155 12156 static int procStateToImportance(int procState, int memAdj, 12157 ActivityManager.RunningAppProcessInfo currApp) { 12158 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12159 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12160 currApp.lru = memAdj; 12161 } else { 12162 currApp.lru = 0; 12163 } 12164 return imp; 12165 } 12166 12167 private void fillInProcMemInfo(ProcessRecord app, 12168 ActivityManager.RunningAppProcessInfo outInfo) { 12169 outInfo.pid = app.pid; 12170 outInfo.uid = app.info.uid; 12171 if (mHeavyWeightProcess == app) { 12172 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12173 } 12174 if (app.persistent) { 12175 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12176 } 12177 if (app.activities.size() > 0) { 12178 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12179 } 12180 outInfo.lastTrimLevel = app.trimMemoryLevel; 12181 int adj = app.curAdj; 12182 int procState = app.curProcState; 12183 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12184 outInfo.importanceReasonCode = app.adjTypeCode; 12185 outInfo.processState = app.curProcState; 12186 } 12187 12188 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12189 enforceNotIsolatedCaller("getRunningAppProcesses"); 12190 // Lazy instantiation of list 12191 List<ActivityManager.RunningAppProcessInfo> runList = null; 12192 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12193 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12194 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12195 synchronized (this) { 12196 // Iterate across all processes 12197 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12198 ProcessRecord app = mLruProcesses.get(i); 12199 if (!allUsers && app.userId != userId) { 12200 continue; 12201 } 12202 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12203 // Generate process state info for running application 12204 ActivityManager.RunningAppProcessInfo currApp = 12205 new ActivityManager.RunningAppProcessInfo(app.processName, 12206 app.pid, app.getPackageList()); 12207 fillInProcMemInfo(app, currApp); 12208 if (app.adjSource instanceof ProcessRecord) { 12209 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12210 currApp.importanceReasonImportance = 12211 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12212 app.adjSourceProcState); 12213 } else if (app.adjSource instanceof ActivityRecord) { 12214 ActivityRecord r = (ActivityRecord)app.adjSource; 12215 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12216 } 12217 if (app.adjTarget instanceof ComponentName) { 12218 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12219 } 12220 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12221 // + " lru=" + currApp.lru); 12222 if (runList == null) { 12223 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12224 } 12225 runList.add(currApp); 12226 } 12227 } 12228 } 12229 return runList; 12230 } 12231 12232 public List<ApplicationInfo> getRunningExternalApplications() { 12233 enforceNotIsolatedCaller("getRunningExternalApplications"); 12234 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12235 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12236 if (runningApps != null && runningApps.size() > 0) { 12237 Set<String> extList = new HashSet<String>(); 12238 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12239 if (app.pkgList != null) { 12240 for (String pkg : app.pkgList) { 12241 extList.add(pkg); 12242 } 12243 } 12244 } 12245 IPackageManager pm = AppGlobals.getPackageManager(); 12246 for (String pkg : extList) { 12247 try { 12248 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12249 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12250 retList.add(info); 12251 } 12252 } catch (RemoteException e) { 12253 } 12254 } 12255 } 12256 return retList; 12257 } 12258 12259 @Override 12260 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12261 enforceNotIsolatedCaller("getMyMemoryState"); 12262 synchronized (this) { 12263 ProcessRecord proc; 12264 synchronized (mPidsSelfLocked) { 12265 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12266 } 12267 fillInProcMemInfo(proc, outInfo); 12268 } 12269 } 12270 12271 @Override 12272 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12273 if (checkCallingPermission(android.Manifest.permission.DUMP) 12274 != PackageManager.PERMISSION_GRANTED) { 12275 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12276 + Binder.getCallingPid() 12277 + ", uid=" + Binder.getCallingUid() 12278 + " without permission " 12279 + android.Manifest.permission.DUMP); 12280 return; 12281 } 12282 12283 boolean dumpAll = false; 12284 boolean dumpClient = false; 12285 String dumpPackage = null; 12286 12287 int opti = 0; 12288 while (opti < args.length) { 12289 String opt = args[opti]; 12290 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12291 break; 12292 } 12293 opti++; 12294 if ("-a".equals(opt)) { 12295 dumpAll = true; 12296 } else if ("-c".equals(opt)) { 12297 dumpClient = true; 12298 } else if ("-h".equals(opt)) { 12299 pw.println("Activity manager dump options:"); 12300 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12301 pw.println(" cmd may be one of:"); 12302 pw.println(" a[ctivities]: activity stack state"); 12303 pw.println(" r[recents]: recent activities state"); 12304 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12305 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12306 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12307 pw.println(" o[om]: out of memory management"); 12308 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12309 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12310 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12311 pw.println(" service [COMP_SPEC]: service client-side state"); 12312 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12313 pw.println(" all: dump all activities"); 12314 pw.println(" top: dump the top activity"); 12315 pw.println(" write: write all pending state to storage"); 12316 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12317 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12318 pw.println(" a partial substring in a component name, a"); 12319 pw.println(" hex object identifier."); 12320 pw.println(" -a: include all available server state."); 12321 pw.println(" -c: include client state."); 12322 return; 12323 } else { 12324 pw.println("Unknown argument: " + opt + "; use -h for help"); 12325 } 12326 } 12327 12328 long origId = Binder.clearCallingIdentity(); 12329 boolean more = false; 12330 // Is the caller requesting to dump a particular piece of data? 12331 if (opti < args.length) { 12332 String cmd = args[opti]; 12333 opti++; 12334 if ("activities".equals(cmd) || "a".equals(cmd)) { 12335 synchronized (this) { 12336 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12337 } 12338 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12339 synchronized (this) { 12340 dumpRecentsLocked(fd, pw, args, opti, true, null); 12341 } 12342 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12343 String[] newArgs; 12344 String name; 12345 if (opti >= args.length) { 12346 name = null; 12347 newArgs = EMPTY_STRING_ARRAY; 12348 } else { 12349 name = args[opti]; 12350 opti++; 12351 newArgs = new String[args.length - opti]; 12352 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12353 args.length - opti); 12354 } 12355 synchronized (this) { 12356 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12357 } 12358 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12359 String[] newArgs; 12360 String name; 12361 if (opti >= args.length) { 12362 name = null; 12363 newArgs = EMPTY_STRING_ARRAY; 12364 } else { 12365 name = args[opti]; 12366 opti++; 12367 newArgs = new String[args.length - opti]; 12368 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12369 args.length - opti); 12370 } 12371 synchronized (this) { 12372 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12373 } 12374 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12375 String[] newArgs; 12376 String name; 12377 if (opti >= args.length) { 12378 name = null; 12379 newArgs = EMPTY_STRING_ARRAY; 12380 } else { 12381 name = args[opti]; 12382 opti++; 12383 newArgs = new String[args.length - opti]; 12384 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12385 args.length - opti); 12386 } 12387 synchronized (this) { 12388 dumpProcessesLocked(fd, pw, args, opti, true, name); 12389 } 12390 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12391 synchronized (this) { 12392 dumpOomLocked(fd, pw, args, opti, true); 12393 } 12394 } else if ("provider".equals(cmd)) { 12395 String[] newArgs; 12396 String name; 12397 if (opti >= args.length) { 12398 name = null; 12399 newArgs = EMPTY_STRING_ARRAY; 12400 } else { 12401 name = args[opti]; 12402 opti++; 12403 newArgs = new String[args.length - opti]; 12404 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12405 } 12406 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12407 pw.println("No providers match: " + name); 12408 pw.println("Use -h for help."); 12409 } 12410 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12411 synchronized (this) { 12412 dumpProvidersLocked(fd, pw, args, opti, true, null); 12413 } 12414 } else if ("service".equals(cmd)) { 12415 String[] newArgs; 12416 String name; 12417 if (opti >= args.length) { 12418 name = null; 12419 newArgs = EMPTY_STRING_ARRAY; 12420 } else { 12421 name = args[opti]; 12422 opti++; 12423 newArgs = new String[args.length - opti]; 12424 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12425 args.length - opti); 12426 } 12427 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12428 pw.println("No services match: " + name); 12429 pw.println("Use -h for help."); 12430 } 12431 } else if ("package".equals(cmd)) { 12432 String[] newArgs; 12433 if (opti >= args.length) { 12434 pw.println("package: no package name specified"); 12435 pw.println("Use -h for help."); 12436 } else { 12437 dumpPackage = args[opti]; 12438 opti++; 12439 newArgs = new String[args.length - opti]; 12440 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12441 args.length - opti); 12442 args = newArgs; 12443 opti = 0; 12444 more = true; 12445 } 12446 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12447 synchronized (this) { 12448 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12449 } 12450 } else if ("write".equals(cmd)) { 12451 mTaskPersister.flush(); 12452 pw.println("All tasks persisted."); 12453 return; 12454 } else { 12455 // Dumping a single activity? 12456 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12457 pw.println("Bad activity command, or no activities match: " + cmd); 12458 pw.println("Use -h for help."); 12459 } 12460 } 12461 if (!more) { 12462 Binder.restoreCallingIdentity(origId); 12463 return; 12464 } 12465 } 12466 12467 // No piece of data specified, dump everything. 12468 synchronized (this) { 12469 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12470 pw.println(); 12471 if (dumpAll) { 12472 pw.println("-------------------------------------------------------------------------------"); 12473 } 12474 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12475 pw.println(); 12476 if (dumpAll) { 12477 pw.println("-------------------------------------------------------------------------------"); 12478 } 12479 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12480 pw.println(); 12481 if (dumpAll) { 12482 pw.println("-------------------------------------------------------------------------------"); 12483 } 12484 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12485 pw.println(); 12486 if (dumpAll) { 12487 pw.println("-------------------------------------------------------------------------------"); 12488 } 12489 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12490 pw.println(); 12491 if (dumpAll) { 12492 pw.println("-------------------------------------------------------------------------------"); 12493 } 12494 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12495 pw.println(); 12496 if (dumpAll) { 12497 pw.println("-------------------------------------------------------------------------------"); 12498 } 12499 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12500 } 12501 Binder.restoreCallingIdentity(origId); 12502 } 12503 12504 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12505 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12506 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12507 12508 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12509 dumpPackage); 12510 boolean needSep = printedAnything; 12511 12512 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12513 dumpPackage, needSep, " mFocusedActivity: "); 12514 if (printed) { 12515 printedAnything = true; 12516 needSep = false; 12517 } 12518 12519 if (dumpPackage == null) { 12520 if (needSep) { 12521 pw.println(); 12522 } 12523 needSep = true; 12524 printedAnything = true; 12525 mStackSupervisor.dump(pw, " "); 12526 } 12527 12528 if (!printedAnything) { 12529 pw.println(" (nothing)"); 12530 } 12531 } 12532 12533 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12534 int opti, boolean dumpAll, String dumpPackage) { 12535 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12536 12537 boolean printedAnything = false; 12538 12539 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12540 boolean printedHeader = false; 12541 12542 final int N = mRecentTasks.size(); 12543 for (int i=0; i<N; i++) { 12544 TaskRecord tr = mRecentTasks.get(i); 12545 if (dumpPackage != null) { 12546 if (tr.realActivity == null || 12547 !dumpPackage.equals(tr.realActivity)) { 12548 continue; 12549 } 12550 } 12551 if (!printedHeader) { 12552 pw.println(" Recent tasks:"); 12553 printedHeader = true; 12554 printedAnything = true; 12555 } 12556 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12557 pw.println(tr); 12558 if (dumpAll) { 12559 mRecentTasks.get(i).dump(pw, " "); 12560 } 12561 } 12562 } 12563 12564 if (!printedAnything) { 12565 pw.println(" (nothing)"); 12566 } 12567 } 12568 12569 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12570 int opti, boolean dumpAll, String dumpPackage) { 12571 boolean needSep = false; 12572 boolean printedAnything = false; 12573 int numPers = 0; 12574 12575 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12576 12577 if (dumpAll) { 12578 final int NP = mProcessNames.getMap().size(); 12579 for (int ip=0; ip<NP; ip++) { 12580 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12581 final int NA = procs.size(); 12582 for (int ia=0; ia<NA; ia++) { 12583 ProcessRecord r = procs.valueAt(ia); 12584 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12585 continue; 12586 } 12587 if (!needSep) { 12588 pw.println(" All known processes:"); 12589 needSep = true; 12590 printedAnything = true; 12591 } 12592 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12593 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12594 pw.print(" "); pw.println(r); 12595 r.dump(pw, " "); 12596 if (r.persistent) { 12597 numPers++; 12598 } 12599 } 12600 } 12601 } 12602 12603 if (mIsolatedProcesses.size() > 0) { 12604 boolean printed = false; 12605 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12606 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12607 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12608 continue; 12609 } 12610 if (!printed) { 12611 if (needSep) { 12612 pw.println(); 12613 } 12614 pw.println(" Isolated process list (sorted by uid):"); 12615 printedAnything = true; 12616 printed = true; 12617 needSep = true; 12618 } 12619 pw.println(String.format("%sIsolated #%2d: %s", 12620 " ", i, r.toString())); 12621 } 12622 } 12623 12624 if (mLruProcesses.size() > 0) { 12625 if (needSep) { 12626 pw.println(); 12627 } 12628 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12629 pw.print(" total, non-act at "); 12630 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12631 pw.print(", non-svc at "); 12632 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12633 pw.println("):"); 12634 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12635 needSep = true; 12636 printedAnything = true; 12637 } 12638 12639 if (dumpAll || dumpPackage != null) { 12640 synchronized (mPidsSelfLocked) { 12641 boolean printed = false; 12642 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12643 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12644 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12645 continue; 12646 } 12647 if (!printed) { 12648 if (needSep) pw.println(); 12649 needSep = true; 12650 pw.println(" PID mappings:"); 12651 printed = true; 12652 printedAnything = true; 12653 } 12654 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12655 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12656 } 12657 } 12658 } 12659 12660 if (mForegroundProcesses.size() > 0) { 12661 synchronized (mPidsSelfLocked) { 12662 boolean printed = false; 12663 for (int i=0; i<mForegroundProcesses.size(); i++) { 12664 ProcessRecord r = mPidsSelfLocked.get( 12665 mForegroundProcesses.valueAt(i).pid); 12666 if (dumpPackage != null && (r == null 12667 || !r.pkgList.containsKey(dumpPackage))) { 12668 continue; 12669 } 12670 if (!printed) { 12671 if (needSep) pw.println(); 12672 needSep = true; 12673 pw.println(" Foreground Processes:"); 12674 printed = true; 12675 printedAnything = true; 12676 } 12677 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12678 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12679 } 12680 } 12681 } 12682 12683 if (mPersistentStartingProcesses.size() > 0) { 12684 if (needSep) pw.println(); 12685 needSep = true; 12686 printedAnything = true; 12687 pw.println(" Persisent processes that are starting:"); 12688 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12689 "Starting Norm", "Restarting PERS", dumpPackage); 12690 } 12691 12692 if (mRemovedProcesses.size() > 0) { 12693 if (needSep) pw.println(); 12694 needSep = true; 12695 printedAnything = true; 12696 pw.println(" Processes that are being removed:"); 12697 dumpProcessList(pw, this, mRemovedProcesses, " ", 12698 "Removed Norm", "Removed PERS", dumpPackage); 12699 } 12700 12701 if (mProcessesOnHold.size() > 0) { 12702 if (needSep) pw.println(); 12703 needSep = true; 12704 printedAnything = true; 12705 pw.println(" Processes that are on old until the system is ready:"); 12706 dumpProcessList(pw, this, mProcessesOnHold, " ", 12707 "OnHold Norm", "OnHold PERS", dumpPackage); 12708 } 12709 12710 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12711 12712 if (mProcessCrashTimes.getMap().size() > 0) { 12713 boolean printed = false; 12714 long now = SystemClock.uptimeMillis(); 12715 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12716 final int NP = pmap.size(); 12717 for (int ip=0; ip<NP; ip++) { 12718 String pname = pmap.keyAt(ip); 12719 SparseArray<Long> uids = pmap.valueAt(ip); 12720 final int N = uids.size(); 12721 for (int i=0; i<N; i++) { 12722 int puid = uids.keyAt(i); 12723 ProcessRecord r = mProcessNames.get(pname, puid); 12724 if (dumpPackage != null && (r == null 12725 || !r.pkgList.containsKey(dumpPackage))) { 12726 continue; 12727 } 12728 if (!printed) { 12729 if (needSep) pw.println(); 12730 needSep = true; 12731 pw.println(" Time since processes crashed:"); 12732 printed = true; 12733 printedAnything = true; 12734 } 12735 pw.print(" Process "); pw.print(pname); 12736 pw.print(" uid "); pw.print(puid); 12737 pw.print(": last crashed "); 12738 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12739 pw.println(" ago"); 12740 } 12741 } 12742 } 12743 12744 if (mBadProcesses.getMap().size() > 0) { 12745 boolean printed = false; 12746 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12747 final int NP = pmap.size(); 12748 for (int ip=0; ip<NP; ip++) { 12749 String pname = pmap.keyAt(ip); 12750 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12751 final int N = uids.size(); 12752 for (int i=0; i<N; i++) { 12753 int puid = uids.keyAt(i); 12754 ProcessRecord r = mProcessNames.get(pname, puid); 12755 if (dumpPackage != null && (r == null 12756 || !r.pkgList.containsKey(dumpPackage))) { 12757 continue; 12758 } 12759 if (!printed) { 12760 if (needSep) pw.println(); 12761 needSep = true; 12762 pw.println(" Bad processes:"); 12763 printedAnything = true; 12764 } 12765 BadProcessInfo info = uids.valueAt(i); 12766 pw.print(" Bad process "); pw.print(pname); 12767 pw.print(" uid "); pw.print(puid); 12768 pw.print(": crashed at time "); pw.println(info.time); 12769 if (info.shortMsg != null) { 12770 pw.print(" Short msg: "); pw.println(info.shortMsg); 12771 } 12772 if (info.longMsg != null) { 12773 pw.print(" Long msg: "); pw.println(info.longMsg); 12774 } 12775 if (info.stack != null) { 12776 pw.println(" Stack:"); 12777 int lastPos = 0; 12778 for (int pos=0; pos<info.stack.length(); pos++) { 12779 if (info.stack.charAt(pos) == '\n') { 12780 pw.print(" "); 12781 pw.write(info.stack, lastPos, pos-lastPos); 12782 pw.println(); 12783 lastPos = pos+1; 12784 } 12785 } 12786 if (lastPos < info.stack.length()) { 12787 pw.print(" "); 12788 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12789 pw.println(); 12790 } 12791 } 12792 } 12793 } 12794 } 12795 12796 if (dumpPackage == null) { 12797 pw.println(); 12798 needSep = false; 12799 pw.println(" mStartedUsers:"); 12800 for (int i=0; i<mStartedUsers.size(); i++) { 12801 UserStartedState uss = mStartedUsers.valueAt(i); 12802 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12803 pw.print(": "); uss.dump("", pw); 12804 } 12805 pw.print(" mStartedUserArray: ["); 12806 for (int i=0; i<mStartedUserArray.length; i++) { 12807 if (i > 0) pw.print(", "); 12808 pw.print(mStartedUserArray[i]); 12809 } 12810 pw.println("]"); 12811 pw.print(" mUserLru: ["); 12812 for (int i=0; i<mUserLru.size(); i++) { 12813 if (i > 0) pw.print(", "); 12814 pw.print(mUserLru.get(i)); 12815 } 12816 pw.println("]"); 12817 if (dumpAll) { 12818 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12819 } 12820 synchronized (mUserProfileGroupIdsSelfLocked) { 12821 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12822 pw.println(" mUserProfileGroupIds:"); 12823 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12824 pw.print(" User #"); 12825 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12826 pw.print(" -> profile #"); 12827 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12828 } 12829 } 12830 } 12831 } 12832 if (mHomeProcess != null && (dumpPackage == null 12833 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12834 if (needSep) { 12835 pw.println(); 12836 needSep = false; 12837 } 12838 pw.println(" mHomeProcess: " + mHomeProcess); 12839 } 12840 if (mPreviousProcess != null && (dumpPackage == null 12841 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12842 if (needSep) { 12843 pw.println(); 12844 needSep = false; 12845 } 12846 pw.println(" mPreviousProcess: " + mPreviousProcess); 12847 } 12848 if (dumpAll) { 12849 StringBuilder sb = new StringBuilder(128); 12850 sb.append(" mPreviousProcessVisibleTime: "); 12851 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12852 pw.println(sb); 12853 } 12854 if (mHeavyWeightProcess != null && (dumpPackage == null 12855 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12856 if (needSep) { 12857 pw.println(); 12858 needSep = false; 12859 } 12860 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12861 } 12862 if (dumpPackage == null) { 12863 pw.println(" mConfiguration: " + mConfiguration); 12864 } 12865 if (dumpAll) { 12866 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12867 if (mCompatModePackages.getPackages().size() > 0) { 12868 boolean printed = false; 12869 for (Map.Entry<String, Integer> entry 12870 : mCompatModePackages.getPackages().entrySet()) { 12871 String pkg = entry.getKey(); 12872 int mode = entry.getValue(); 12873 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12874 continue; 12875 } 12876 if (!printed) { 12877 pw.println(" mScreenCompatPackages:"); 12878 printed = true; 12879 } 12880 pw.print(" "); pw.print(pkg); pw.print(": "); 12881 pw.print(mode); pw.println(); 12882 } 12883 } 12884 } 12885 if (dumpPackage == null) { 12886 pw.println(" mWakefulness=" 12887 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12888 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12889 + lockScreenShownToString()); 12890 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12891 } 12892 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12893 || mOrigWaitForDebugger) { 12894 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12895 || dumpPackage.equals(mOrigDebugApp)) { 12896 if (needSep) { 12897 pw.println(); 12898 needSep = false; 12899 } 12900 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12901 + " mDebugTransient=" + mDebugTransient 12902 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12903 } 12904 } 12905 if (mOpenGlTraceApp != null) { 12906 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12907 if (needSep) { 12908 pw.println(); 12909 needSep = false; 12910 } 12911 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12912 } 12913 } 12914 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12915 || mProfileFd != null) { 12916 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12917 if (needSep) { 12918 pw.println(); 12919 needSep = false; 12920 } 12921 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12922 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12923 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12924 + mAutoStopProfiler); 12925 pw.println(" mProfileType=" + mProfileType); 12926 } 12927 } 12928 if (dumpPackage == null) { 12929 if (mAlwaysFinishActivities || mController != null) { 12930 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12931 + " mController=" + mController); 12932 } 12933 if (dumpAll) { 12934 pw.println(" Total persistent processes: " + numPers); 12935 pw.println(" mProcessesReady=" + mProcessesReady 12936 + " mSystemReady=" + mSystemReady 12937 + " mBooted=" + mBooted 12938 + " mFactoryTest=" + mFactoryTest); 12939 pw.println(" mBooting=" + mBooting 12940 + " mCallFinishBooting=" + mCallFinishBooting 12941 + " mBootAnimationComplete=" + mBootAnimationComplete); 12942 pw.print(" mLastPowerCheckRealtime="); 12943 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12944 pw.println(""); 12945 pw.print(" mLastPowerCheckUptime="); 12946 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12947 pw.println(""); 12948 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12949 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12950 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12951 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12952 + " (" + mLruProcesses.size() + " total)" 12953 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12954 + " mNumServiceProcs=" + mNumServiceProcs 12955 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12956 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12957 + " mLastMemoryLevel" + mLastMemoryLevel 12958 + " mLastNumProcesses" + mLastNumProcesses); 12959 long now = SystemClock.uptimeMillis(); 12960 pw.print(" mLastIdleTime="); 12961 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12962 pw.print(" mLowRamSinceLastIdle="); 12963 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12964 pw.println(); 12965 } 12966 } 12967 12968 if (!printedAnything) { 12969 pw.println(" (nothing)"); 12970 } 12971 } 12972 12973 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12974 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12975 if (mProcessesToGc.size() > 0) { 12976 boolean printed = false; 12977 long now = SystemClock.uptimeMillis(); 12978 for (int i=0; i<mProcessesToGc.size(); i++) { 12979 ProcessRecord proc = mProcessesToGc.get(i); 12980 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12981 continue; 12982 } 12983 if (!printed) { 12984 if (needSep) pw.println(); 12985 needSep = true; 12986 pw.println(" Processes that are waiting to GC:"); 12987 printed = true; 12988 } 12989 pw.print(" Process "); pw.println(proc); 12990 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12991 pw.print(", last gced="); 12992 pw.print(now-proc.lastRequestedGc); 12993 pw.print(" ms ago, last lowMem="); 12994 pw.print(now-proc.lastLowMemory); 12995 pw.println(" ms ago"); 12996 12997 } 12998 } 12999 return needSep; 13000 } 13001 13002 void printOomLevel(PrintWriter pw, String name, int adj) { 13003 pw.print(" "); 13004 if (adj >= 0) { 13005 pw.print(' '); 13006 if (adj < 10) pw.print(' '); 13007 } else { 13008 if (adj > -10) pw.print(' '); 13009 } 13010 pw.print(adj); 13011 pw.print(": "); 13012 pw.print(name); 13013 pw.print(" ("); 13014 pw.print(mProcessList.getMemLevel(adj)/1024); 13015 pw.println(" kB)"); 13016 } 13017 13018 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13019 int opti, boolean dumpAll) { 13020 boolean needSep = false; 13021 13022 if (mLruProcesses.size() > 0) { 13023 if (needSep) pw.println(); 13024 needSep = true; 13025 pw.println(" OOM levels:"); 13026 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13027 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13028 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13029 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13030 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13031 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13032 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13033 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13034 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13035 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13036 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13037 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13038 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13039 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13040 13041 if (needSep) pw.println(); 13042 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13043 pw.print(" total, non-act at "); 13044 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13045 pw.print(", non-svc at "); 13046 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13047 pw.println("):"); 13048 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13049 needSep = true; 13050 } 13051 13052 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13053 13054 pw.println(); 13055 pw.println(" mHomeProcess: " + mHomeProcess); 13056 pw.println(" mPreviousProcess: " + mPreviousProcess); 13057 if (mHeavyWeightProcess != null) { 13058 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13059 } 13060 13061 return true; 13062 } 13063 13064 /** 13065 * There are three ways to call this: 13066 * - no provider specified: dump all the providers 13067 * - a flattened component name that matched an existing provider was specified as the 13068 * first arg: dump that one provider 13069 * - the first arg isn't the flattened component name of an existing provider: 13070 * dump all providers whose component contains the first arg as a substring 13071 */ 13072 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13073 int opti, boolean dumpAll) { 13074 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13075 } 13076 13077 static class ItemMatcher { 13078 ArrayList<ComponentName> components; 13079 ArrayList<String> strings; 13080 ArrayList<Integer> objects; 13081 boolean all; 13082 13083 ItemMatcher() { 13084 all = true; 13085 } 13086 13087 void build(String name) { 13088 ComponentName componentName = ComponentName.unflattenFromString(name); 13089 if (componentName != null) { 13090 if (components == null) { 13091 components = new ArrayList<ComponentName>(); 13092 } 13093 components.add(componentName); 13094 all = false; 13095 } else { 13096 int objectId = 0; 13097 // Not a '/' separated full component name; maybe an object ID? 13098 try { 13099 objectId = Integer.parseInt(name, 16); 13100 if (objects == null) { 13101 objects = new ArrayList<Integer>(); 13102 } 13103 objects.add(objectId); 13104 all = false; 13105 } catch (RuntimeException e) { 13106 // Not an integer; just do string match. 13107 if (strings == null) { 13108 strings = new ArrayList<String>(); 13109 } 13110 strings.add(name); 13111 all = false; 13112 } 13113 } 13114 } 13115 13116 int build(String[] args, int opti) { 13117 for (; opti<args.length; opti++) { 13118 String name = args[opti]; 13119 if ("--".equals(name)) { 13120 return opti+1; 13121 } 13122 build(name); 13123 } 13124 return opti; 13125 } 13126 13127 boolean match(Object object, ComponentName comp) { 13128 if (all) { 13129 return true; 13130 } 13131 if (components != null) { 13132 for (int i=0; i<components.size(); i++) { 13133 if (components.get(i).equals(comp)) { 13134 return true; 13135 } 13136 } 13137 } 13138 if (objects != null) { 13139 for (int i=0; i<objects.size(); i++) { 13140 if (System.identityHashCode(object) == objects.get(i)) { 13141 return true; 13142 } 13143 } 13144 } 13145 if (strings != null) { 13146 String flat = comp.flattenToString(); 13147 for (int i=0; i<strings.size(); i++) { 13148 if (flat.contains(strings.get(i))) { 13149 return true; 13150 } 13151 } 13152 } 13153 return false; 13154 } 13155 } 13156 13157 /** 13158 * There are three things that cmd can be: 13159 * - a flattened component name that matches an existing activity 13160 * - the cmd arg isn't the flattened component name of an existing activity: 13161 * dump all activity whose component contains the cmd as a substring 13162 * - A hex number of the ActivityRecord object instance. 13163 */ 13164 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13165 int opti, boolean dumpAll) { 13166 ArrayList<ActivityRecord> activities; 13167 13168 synchronized (this) { 13169 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13170 } 13171 13172 if (activities.size() <= 0) { 13173 return false; 13174 } 13175 13176 String[] newArgs = new String[args.length - opti]; 13177 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13178 13179 TaskRecord lastTask = null; 13180 boolean needSep = false; 13181 for (int i=activities.size()-1; i>=0; i--) { 13182 ActivityRecord r = activities.get(i); 13183 if (needSep) { 13184 pw.println(); 13185 } 13186 needSep = true; 13187 synchronized (this) { 13188 if (lastTask != r.task) { 13189 lastTask = r.task; 13190 pw.print("TASK "); pw.print(lastTask.affinity); 13191 pw.print(" id="); pw.println(lastTask.taskId); 13192 if (dumpAll) { 13193 lastTask.dump(pw, " "); 13194 } 13195 } 13196 } 13197 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13198 } 13199 return true; 13200 } 13201 13202 /** 13203 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13204 * there is a thread associated with the activity. 13205 */ 13206 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13207 final ActivityRecord r, String[] args, boolean dumpAll) { 13208 String innerPrefix = prefix + " "; 13209 synchronized (this) { 13210 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13211 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13212 pw.print(" pid="); 13213 if (r.app != null) pw.println(r.app.pid); 13214 else pw.println("(not running)"); 13215 if (dumpAll) { 13216 r.dump(pw, innerPrefix); 13217 } 13218 } 13219 if (r.app != null && r.app.thread != null) { 13220 // flush anything that is already in the PrintWriter since the thread is going 13221 // to write to the file descriptor directly 13222 pw.flush(); 13223 try { 13224 TransferPipe tp = new TransferPipe(); 13225 try { 13226 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13227 r.appToken, innerPrefix, args); 13228 tp.go(fd); 13229 } finally { 13230 tp.kill(); 13231 } 13232 } catch (IOException e) { 13233 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13234 } catch (RemoteException e) { 13235 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13236 } 13237 } 13238 } 13239 13240 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13241 int opti, boolean dumpAll, String dumpPackage) { 13242 boolean needSep = false; 13243 boolean onlyHistory = false; 13244 boolean printedAnything = false; 13245 13246 if ("history".equals(dumpPackage)) { 13247 if (opti < args.length && "-s".equals(args[opti])) { 13248 dumpAll = false; 13249 } 13250 onlyHistory = true; 13251 dumpPackage = null; 13252 } 13253 13254 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13255 if (!onlyHistory && dumpAll) { 13256 if (mRegisteredReceivers.size() > 0) { 13257 boolean printed = false; 13258 Iterator it = mRegisteredReceivers.values().iterator(); 13259 while (it.hasNext()) { 13260 ReceiverList r = (ReceiverList)it.next(); 13261 if (dumpPackage != null && (r.app == null || 13262 !dumpPackage.equals(r.app.info.packageName))) { 13263 continue; 13264 } 13265 if (!printed) { 13266 pw.println(" Registered Receivers:"); 13267 needSep = true; 13268 printed = true; 13269 printedAnything = true; 13270 } 13271 pw.print(" * "); pw.println(r); 13272 r.dump(pw, " "); 13273 } 13274 } 13275 13276 if (mReceiverResolver.dump(pw, needSep ? 13277 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13278 " ", dumpPackage, false, false)) { 13279 needSep = true; 13280 printedAnything = true; 13281 } 13282 } 13283 13284 for (BroadcastQueue q : mBroadcastQueues) { 13285 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13286 printedAnything |= needSep; 13287 } 13288 13289 needSep = true; 13290 13291 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13292 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13293 if (needSep) { 13294 pw.println(); 13295 } 13296 needSep = true; 13297 printedAnything = true; 13298 pw.print(" Sticky broadcasts for user "); 13299 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13300 StringBuilder sb = new StringBuilder(128); 13301 for (Map.Entry<String, ArrayList<Intent>> ent 13302 : mStickyBroadcasts.valueAt(user).entrySet()) { 13303 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13304 if (dumpAll) { 13305 pw.println(":"); 13306 ArrayList<Intent> intents = ent.getValue(); 13307 final int N = intents.size(); 13308 for (int i=0; i<N; i++) { 13309 sb.setLength(0); 13310 sb.append(" Intent: "); 13311 intents.get(i).toShortString(sb, false, true, false, false); 13312 pw.println(sb.toString()); 13313 Bundle bundle = intents.get(i).getExtras(); 13314 if (bundle != null) { 13315 pw.print(" "); 13316 pw.println(bundle.toString()); 13317 } 13318 } 13319 } else { 13320 pw.println(""); 13321 } 13322 } 13323 } 13324 } 13325 13326 if (!onlyHistory && dumpAll) { 13327 pw.println(); 13328 for (BroadcastQueue queue : mBroadcastQueues) { 13329 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13330 + queue.mBroadcastsScheduled); 13331 } 13332 pw.println(" mHandler:"); 13333 mHandler.dump(new PrintWriterPrinter(pw), " "); 13334 needSep = true; 13335 printedAnything = true; 13336 } 13337 13338 if (!printedAnything) { 13339 pw.println(" (nothing)"); 13340 } 13341 } 13342 13343 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13344 int opti, boolean dumpAll, String dumpPackage) { 13345 boolean needSep; 13346 boolean printedAnything = false; 13347 13348 ItemMatcher matcher = new ItemMatcher(); 13349 matcher.build(args, opti); 13350 13351 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13352 13353 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13354 printedAnything |= needSep; 13355 13356 if (mLaunchingProviders.size() > 0) { 13357 boolean printed = false; 13358 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13359 ContentProviderRecord r = mLaunchingProviders.get(i); 13360 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13361 continue; 13362 } 13363 if (!printed) { 13364 if (needSep) pw.println(); 13365 needSep = true; 13366 pw.println(" Launching content providers:"); 13367 printed = true; 13368 printedAnything = true; 13369 } 13370 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13371 pw.println(r); 13372 } 13373 } 13374 13375 if (mGrantedUriPermissions.size() > 0) { 13376 boolean printed = false; 13377 int dumpUid = -2; 13378 if (dumpPackage != null) { 13379 try { 13380 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13381 } catch (NameNotFoundException e) { 13382 dumpUid = -1; 13383 } 13384 } 13385 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13386 int uid = mGrantedUriPermissions.keyAt(i); 13387 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13388 continue; 13389 } 13390 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13391 if (!printed) { 13392 if (needSep) pw.println(); 13393 needSep = true; 13394 pw.println(" Granted Uri Permissions:"); 13395 printed = true; 13396 printedAnything = true; 13397 } 13398 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13399 for (UriPermission perm : perms.values()) { 13400 pw.print(" "); pw.println(perm); 13401 if (dumpAll) { 13402 perm.dump(pw, " "); 13403 } 13404 } 13405 } 13406 } 13407 13408 if (!printedAnything) { 13409 pw.println(" (nothing)"); 13410 } 13411 } 13412 13413 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13414 int opti, boolean dumpAll, String dumpPackage) { 13415 boolean printed = false; 13416 13417 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13418 13419 if (mIntentSenderRecords.size() > 0) { 13420 Iterator<WeakReference<PendingIntentRecord>> it 13421 = mIntentSenderRecords.values().iterator(); 13422 while (it.hasNext()) { 13423 WeakReference<PendingIntentRecord> ref = it.next(); 13424 PendingIntentRecord rec = ref != null ? ref.get(): null; 13425 if (dumpPackage != null && (rec == null 13426 || !dumpPackage.equals(rec.key.packageName))) { 13427 continue; 13428 } 13429 printed = true; 13430 if (rec != null) { 13431 pw.print(" * "); pw.println(rec); 13432 if (dumpAll) { 13433 rec.dump(pw, " "); 13434 } 13435 } else { 13436 pw.print(" * "); pw.println(ref); 13437 } 13438 } 13439 } 13440 13441 if (!printed) { 13442 pw.println(" (nothing)"); 13443 } 13444 } 13445 13446 private static final int dumpProcessList(PrintWriter pw, 13447 ActivityManagerService service, List list, 13448 String prefix, String normalLabel, String persistentLabel, 13449 String dumpPackage) { 13450 int numPers = 0; 13451 final int N = list.size()-1; 13452 for (int i=N; i>=0; i--) { 13453 ProcessRecord r = (ProcessRecord)list.get(i); 13454 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13455 continue; 13456 } 13457 pw.println(String.format("%s%s #%2d: %s", 13458 prefix, (r.persistent ? persistentLabel : normalLabel), 13459 i, r.toString())); 13460 if (r.persistent) { 13461 numPers++; 13462 } 13463 } 13464 return numPers; 13465 } 13466 13467 private static final boolean dumpProcessOomList(PrintWriter pw, 13468 ActivityManagerService service, List<ProcessRecord> origList, 13469 String prefix, String normalLabel, String persistentLabel, 13470 boolean inclDetails, String dumpPackage) { 13471 13472 ArrayList<Pair<ProcessRecord, Integer>> list 13473 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13474 for (int i=0; i<origList.size(); i++) { 13475 ProcessRecord r = origList.get(i); 13476 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13477 continue; 13478 } 13479 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13480 } 13481 13482 if (list.size() <= 0) { 13483 return false; 13484 } 13485 13486 Comparator<Pair<ProcessRecord, Integer>> comparator 13487 = new Comparator<Pair<ProcessRecord, Integer>>() { 13488 @Override 13489 public int compare(Pair<ProcessRecord, Integer> object1, 13490 Pair<ProcessRecord, Integer> object2) { 13491 if (object1.first.setAdj != object2.first.setAdj) { 13492 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13493 } 13494 if (object1.second.intValue() != object2.second.intValue()) { 13495 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13496 } 13497 return 0; 13498 } 13499 }; 13500 13501 Collections.sort(list, comparator); 13502 13503 final long curRealtime = SystemClock.elapsedRealtime(); 13504 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13505 final long curUptime = SystemClock.uptimeMillis(); 13506 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13507 13508 for (int i=list.size()-1; i>=0; i--) { 13509 ProcessRecord r = list.get(i).first; 13510 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13511 char schedGroup; 13512 switch (r.setSchedGroup) { 13513 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13514 schedGroup = 'B'; 13515 break; 13516 case Process.THREAD_GROUP_DEFAULT: 13517 schedGroup = 'F'; 13518 break; 13519 default: 13520 schedGroup = '?'; 13521 break; 13522 } 13523 char foreground; 13524 if (r.foregroundActivities) { 13525 foreground = 'A'; 13526 } else if (r.foregroundServices) { 13527 foreground = 'S'; 13528 } else { 13529 foreground = ' '; 13530 } 13531 String procState = ProcessList.makeProcStateString(r.curProcState); 13532 pw.print(prefix); 13533 pw.print(r.persistent ? persistentLabel : normalLabel); 13534 pw.print(" #"); 13535 int num = (origList.size()-1)-list.get(i).second; 13536 if (num < 10) pw.print(' '); 13537 pw.print(num); 13538 pw.print(": "); 13539 pw.print(oomAdj); 13540 pw.print(' '); 13541 pw.print(schedGroup); 13542 pw.print('/'); 13543 pw.print(foreground); 13544 pw.print('/'); 13545 pw.print(procState); 13546 pw.print(" trm:"); 13547 if (r.trimMemoryLevel < 10) pw.print(' '); 13548 pw.print(r.trimMemoryLevel); 13549 pw.print(' '); 13550 pw.print(r.toShortString()); 13551 pw.print(" ("); 13552 pw.print(r.adjType); 13553 pw.println(')'); 13554 if (r.adjSource != null || r.adjTarget != null) { 13555 pw.print(prefix); 13556 pw.print(" "); 13557 if (r.adjTarget instanceof ComponentName) { 13558 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13559 } else if (r.adjTarget != null) { 13560 pw.print(r.adjTarget.toString()); 13561 } else { 13562 pw.print("{null}"); 13563 } 13564 pw.print("<="); 13565 if (r.adjSource instanceof ProcessRecord) { 13566 pw.print("Proc{"); 13567 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13568 pw.println("}"); 13569 } else if (r.adjSource != null) { 13570 pw.println(r.adjSource.toString()); 13571 } else { 13572 pw.println("{null}"); 13573 } 13574 } 13575 if (inclDetails) { 13576 pw.print(prefix); 13577 pw.print(" "); 13578 pw.print("oom: max="); pw.print(r.maxAdj); 13579 pw.print(" curRaw="); pw.print(r.curRawAdj); 13580 pw.print(" setRaw="); pw.print(r.setRawAdj); 13581 pw.print(" cur="); pw.print(r.curAdj); 13582 pw.print(" set="); pw.println(r.setAdj); 13583 pw.print(prefix); 13584 pw.print(" "); 13585 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13586 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13587 pw.print(" lastPss="); pw.print(r.lastPss); 13588 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13589 pw.print(prefix); 13590 pw.print(" "); 13591 pw.print("cached="); pw.print(r.cached); 13592 pw.print(" empty="); pw.print(r.empty); 13593 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13594 13595 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13596 if (r.lastWakeTime != 0) { 13597 long wtime; 13598 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13599 synchronized (stats) { 13600 wtime = stats.getProcessWakeTime(r.info.uid, 13601 r.pid, curRealtime); 13602 } 13603 long timeUsed = wtime - r.lastWakeTime; 13604 pw.print(prefix); 13605 pw.print(" "); 13606 pw.print("keep awake over "); 13607 TimeUtils.formatDuration(realtimeSince, pw); 13608 pw.print(" used "); 13609 TimeUtils.formatDuration(timeUsed, pw); 13610 pw.print(" ("); 13611 pw.print((timeUsed*100)/realtimeSince); 13612 pw.println("%)"); 13613 } 13614 if (r.lastCpuTime != 0) { 13615 long timeUsed = r.curCpuTime - r.lastCpuTime; 13616 pw.print(prefix); 13617 pw.print(" "); 13618 pw.print("run cpu over "); 13619 TimeUtils.formatDuration(uptimeSince, pw); 13620 pw.print(" used "); 13621 TimeUtils.formatDuration(timeUsed, pw); 13622 pw.print(" ("); 13623 pw.print((timeUsed*100)/uptimeSince); 13624 pw.println("%)"); 13625 } 13626 } 13627 } 13628 } 13629 return true; 13630 } 13631 13632 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13633 String[] args) { 13634 ArrayList<ProcessRecord> procs; 13635 synchronized (this) { 13636 if (args != null && args.length > start 13637 && args[start].charAt(0) != '-') { 13638 procs = new ArrayList<ProcessRecord>(); 13639 int pid = -1; 13640 try { 13641 pid = Integer.parseInt(args[start]); 13642 } catch (NumberFormatException e) { 13643 } 13644 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13645 ProcessRecord proc = mLruProcesses.get(i); 13646 if (proc.pid == pid) { 13647 procs.add(proc); 13648 } else if (allPkgs && proc.pkgList != null 13649 && proc.pkgList.containsKey(args[start])) { 13650 procs.add(proc); 13651 } else if (proc.processName.equals(args[start])) { 13652 procs.add(proc); 13653 } 13654 } 13655 if (procs.size() <= 0) { 13656 return null; 13657 } 13658 } else { 13659 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13660 } 13661 } 13662 return procs; 13663 } 13664 13665 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13666 PrintWriter pw, String[] args) { 13667 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13668 if (procs == null) { 13669 pw.println("No process found for: " + args[0]); 13670 return; 13671 } 13672 13673 long uptime = SystemClock.uptimeMillis(); 13674 long realtime = SystemClock.elapsedRealtime(); 13675 pw.println("Applications Graphics Acceleration Info:"); 13676 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13677 13678 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13679 ProcessRecord r = procs.get(i); 13680 if (r.thread != null) { 13681 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13682 pw.flush(); 13683 try { 13684 TransferPipe tp = new TransferPipe(); 13685 try { 13686 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13687 tp.go(fd); 13688 } finally { 13689 tp.kill(); 13690 } 13691 } catch (IOException e) { 13692 pw.println("Failure while dumping the app: " + r); 13693 pw.flush(); 13694 } catch (RemoteException e) { 13695 pw.println("Got a RemoteException while dumping the app " + r); 13696 pw.flush(); 13697 } 13698 } 13699 } 13700 } 13701 13702 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13703 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13704 if (procs == null) { 13705 pw.println("No process found for: " + args[0]); 13706 return; 13707 } 13708 13709 pw.println("Applications Database Info:"); 13710 13711 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13712 ProcessRecord r = procs.get(i); 13713 if (r.thread != null) { 13714 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13715 pw.flush(); 13716 try { 13717 TransferPipe tp = new TransferPipe(); 13718 try { 13719 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13720 tp.go(fd); 13721 } finally { 13722 tp.kill(); 13723 } 13724 } catch (IOException e) { 13725 pw.println("Failure while dumping the app: " + r); 13726 pw.flush(); 13727 } catch (RemoteException e) { 13728 pw.println("Got a RemoteException while dumping the app " + r); 13729 pw.flush(); 13730 } 13731 } 13732 } 13733 } 13734 13735 final static class MemItem { 13736 final boolean isProc; 13737 final String label; 13738 final String shortLabel; 13739 final long pss; 13740 final int id; 13741 final boolean hasActivities; 13742 ArrayList<MemItem> subitems; 13743 13744 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13745 boolean _hasActivities) { 13746 isProc = true; 13747 label = _label; 13748 shortLabel = _shortLabel; 13749 pss = _pss; 13750 id = _id; 13751 hasActivities = _hasActivities; 13752 } 13753 13754 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13755 isProc = false; 13756 label = _label; 13757 shortLabel = _shortLabel; 13758 pss = _pss; 13759 id = _id; 13760 hasActivities = false; 13761 } 13762 } 13763 13764 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13765 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13766 if (sort && !isCompact) { 13767 Collections.sort(items, new Comparator<MemItem>() { 13768 @Override 13769 public int compare(MemItem lhs, MemItem rhs) { 13770 if (lhs.pss < rhs.pss) { 13771 return 1; 13772 } else if (lhs.pss > rhs.pss) { 13773 return -1; 13774 } 13775 return 0; 13776 } 13777 }); 13778 } 13779 13780 for (int i=0; i<items.size(); i++) { 13781 MemItem mi = items.get(i); 13782 if (!isCompact) { 13783 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13784 } else if (mi.isProc) { 13785 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13786 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13787 pw.println(mi.hasActivities ? ",a" : ",e"); 13788 } else { 13789 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13790 pw.println(mi.pss); 13791 } 13792 if (mi.subitems != null) { 13793 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13794 true, isCompact); 13795 } 13796 } 13797 } 13798 13799 // These are in KB. 13800 static final long[] DUMP_MEM_BUCKETS = new long[] { 13801 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13802 120*1024, 160*1024, 200*1024, 13803 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13804 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13805 }; 13806 13807 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13808 boolean stackLike) { 13809 int start = label.lastIndexOf('.'); 13810 if (start >= 0) start++; 13811 else start = 0; 13812 int end = label.length(); 13813 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13814 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13815 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13816 out.append(bucket); 13817 out.append(stackLike ? "MB." : "MB "); 13818 out.append(label, start, end); 13819 return; 13820 } 13821 } 13822 out.append(memKB/1024); 13823 out.append(stackLike ? "MB." : "MB "); 13824 out.append(label, start, end); 13825 } 13826 13827 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13828 ProcessList.NATIVE_ADJ, 13829 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13830 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13831 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13832 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13833 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13834 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13835 }; 13836 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13837 "Native", 13838 "System", "Persistent", "Persistent Service", "Foreground", 13839 "Visible", "Perceptible", 13840 "Heavy Weight", "Backup", 13841 "A Services", "Home", 13842 "Previous", "B Services", "Cached" 13843 }; 13844 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13845 "native", 13846 "sys", "pers", "persvc", "fore", 13847 "vis", "percept", 13848 "heavy", "backup", 13849 "servicea", "home", 13850 "prev", "serviceb", "cached" 13851 }; 13852 13853 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13854 long realtime, boolean isCheckinRequest, boolean isCompact) { 13855 if (isCheckinRequest || isCompact) { 13856 // short checkin version 13857 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13858 } else { 13859 pw.println("Applications Memory Usage (kB):"); 13860 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13861 } 13862 } 13863 13864 private static final int KSM_SHARED = 0; 13865 private static final int KSM_SHARING = 1; 13866 private static final int KSM_UNSHARED = 2; 13867 private static final int KSM_VOLATILE = 3; 13868 13869 private final long[] getKsmInfo() { 13870 long[] longOut = new long[4]; 13871 final int[] SINGLE_LONG_FORMAT = new int[] { 13872 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13873 }; 13874 long[] longTmp = new long[1]; 13875 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13876 SINGLE_LONG_FORMAT, null, longTmp, null); 13877 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13878 longTmp[0] = 0; 13879 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13880 SINGLE_LONG_FORMAT, null, longTmp, null); 13881 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13882 longTmp[0] = 0; 13883 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13884 SINGLE_LONG_FORMAT, null, longTmp, null); 13885 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13886 longTmp[0] = 0; 13887 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13888 SINGLE_LONG_FORMAT, null, longTmp, null); 13889 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13890 return longOut; 13891 } 13892 13893 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13894 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13895 boolean dumpDetails = false; 13896 boolean dumpFullDetails = false; 13897 boolean dumpDalvik = false; 13898 boolean oomOnly = false; 13899 boolean isCompact = false; 13900 boolean localOnly = false; 13901 boolean packages = false; 13902 13903 int opti = 0; 13904 while (opti < args.length) { 13905 String opt = args[opti]; 13906 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13907 break; 13908 } 13909 opti++; 13910 if ("-a".equals(opt)) { 13911 dumpDetails = true; 13912 dumpFullDetails = true; 13913 dumpDalvik = true; 13914 } else if ("-d".equals(opt)) { 13915 dumpDalvik = true; 13916 } else if ("-c".equals(opt)) { 13917 isCompact = true; 13918 } else if ("--oom".equals(opt)) { 13919 oomOnly = true; 13920 } else if ("--local".equals(opt)) { 13921 localOnly = true; 13922 } else if ("--package".equals(opt)) { 13923 packages = true; 13924 } else if ("-h".equals(opt)) { 13925 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13926 pw.println(" -a: include all available information for each process."); 13927 pw.println(" -d: include dalvik details when dumping process details."); 13928 pw.println(" -c: dump in a compact machine-parseable representation."); 13929 pw.println(" --oom: only show processes organized by oom adj."); 13930 pw.println(" --local: only collect details locally, don't call process."); 13931 pw.println(" --package: interpret process arg as package, dumping all"); 13932 pw.println(" processes that have loaded that package."); 13933 pw.println("If [process] is specified it can be the name or "); 13934 pw.println("pid of a specific process to dump."); 13935 return; 13936 } else { 13937 pw.println("Unknown argument: " + opt + "; use -h for help"); 13938 } 13939 } 13940 13941 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13942 long uptime = SystemClock.uptimeMillis(); 13943 long realtime = SystemClock.elapsedRealtime(); 13944 final long[] tmpLong = new long[1]; 13945 13946 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13947 if (procs == null) { 13948 // No Java processes. Maybe they want to print a native process. 13949 if (args != null && args.length > opti 13950 && args[opti].charAt(0) != '-') { 13951 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13952 = new ArrayList<ProcessCpuTracker.Stats>(); 13953 updateCpuStatsNow(); 13954 int findPid = -1; 13955 try { 13956 findPid = Integer.parseInt(args[opti]); 13957 } catch (NumberFormatException e) { 13958 } 13959 synchronized (mProcessCpuTracker) { 13960 final int N = mProcessCpuTracker.countStats(); 13961 for (int i=0; i<N; i++) { 13962 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13963 if (st.pid == findPid || (st.baseName != null 13964 && st.baseName.equals(args[opti]))) { 13965 nativeProcs.add(st); 13966 } 13967 } 13968 } 13969 if (nativeProcs.size() > 0) { 13970 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13971 isCompact); 13972 Debug.MemoryInfo mi = null; 13973 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13974 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13975 final int pid = r.pid; 13976 if (!isCheckinRequest && dumpDetails) { 13977 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13978 } 13979 if (mi == null) { 13980 mi = new Debug.MemoryInfo(); 13981 } 13982 if (dumpDetails || (!brief && !oomOnly)) { 13983 Debug.getMemoryInfo(pid, mi); 13984 } else { 13985 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13986 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13987 } 13988 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13989 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13990 if (isCheckinRequest) { 13991 pw.println(); 13992 } 13993 } 13994 return; 13995 } 13996 } 13997 pw.println("No process found for: " + args[opti]); 13998 return; 13999 } 14000 14001 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14002 dumpDetails = true; 14003 } 14004 14005 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14006 14007 String[] innerArgs = new String[args.length-opti]; 14008 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14009 14010 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14011 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14012 long nativePss = 0; 14013 long dalvikPss = 0; 14014 long otherPss = 0; 14015 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14016 14017 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14018 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14019 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14020 14021 long totalPss = 0; 14022 long cachedPss = 0; 14023 14024 Debug.MemoryInfo mi = null; 14025 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14026 final ProcessRecord r = procs.get(i); 14027 final IApplicationThread thread; 14028 final int pid; 14029 final int oomAdj; 14030 final boolean hasActivities; 14031 synchronized (this) { 14032 thread = r.thread; 14033 pid = r.pid; 14034 oomAdj = r.getSetAdjWithServices(); 14035 hasActivities = r.activities.size() > 0; 14036 } 14037 if (thread != null) { 14038 if (!isCheckinRequest && dumpDetails) { 14039 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14040 } 14041 if (mi == null) { 14042 mi = new Debug.MemoryInfo(); 14043 } 14044 if (dumpDetails || (!brief && !oomOnly)) { 14045 Debug.getMemoryInfo(pid, mi); 14046 } else { 14047 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14048 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14049 } 14050 if (dumpDetails) { 14051 if (localOnly) { 14052 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14053 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14054 if (isCheckinRequest) { 14055 pw.println(); 14056 } 14057 } else { 14058 try { 14059 pw.flush(); 14060 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14061 dumpDalvik, innerArgs); 14062 } catch (RemoteException e) { 14063 if (!isCheckinRequest) { 14064 pw.println("Got RemoteException!"); 14065 pw.flush(); 14066 } 14067 } 14068 } 14069 } 14070 14071 final long myTotalPss = mi.getTotalPss(); 14072 final long myTotalUss = mi.getTotalUss(); 14073 14074 synchronized (this) { 14075 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14076 // Record this for posterity if the process has been stable. 14077 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14078 } 14079 } 14080 14081 if (!isCheckinRequest && mi != null) { 14082 totalPss += myTotalPss; 14083 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14084 (hasActivities ? " / activities)" : ")"), 14085 r.processName, myTotalPss, pid, hasActivities); 14086 procMems.add(pssItem); 14087 procMemsMap.put(pid, pssItem); 14088 14089 nativePss += mi.nativePss; 14090 dalvikPss += mi.dalvikPss; 14091 otherPss += mi.otherPss; 14092 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14093 long mem = mi.getOtherPss(j); 14094 miscPss[j] += mem; 14095 otherPss -= mem; 14096 } 14097 14098 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14099 cachedPss += myTotalPss; 14100 } 14101 14102 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14103 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14104 || oomIndex == (oomPss.length-1)) { 14105 oomPss[oomIndex] += myTotalPss; 14106 if (oomProcs[oomIndex] == null) { 14107 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14108 } 14109 oomProcs[oomIndex].add(pssItem); 14110 break; 14111 } 14112 } 14113 } 14114 } 14115 } 14116 14117 long nativeProcTotalPss = 0; 14118 14119 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14120 // If we are showing aggregations, also look for native processes to 14121 // include so that our aggregations are more accurate. 14122 updateCpuStatsNow(); 14123 synchronized (mProcessCpuTracker) { 14124 final int N = mProcessCpuTracker.countStats(); 14125 for (int i=0; i<N; i++) { 14126 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14127 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14128 if (mi == null) { 14129 mi = new Debug.MemoryInfo(); 14130 } 14131 if (!brief && !oomOnly) { 14132 Debug.getMemoryInfo(st.pid, mi); 14133 } else { 14134 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14135 mi.nativePrivateDirty = (int)tmpLong[0]; 14136 } 14137 14138 final long myTotalPss = mi.getTotalPss(); 14139 totalPss += myTotalPss; 14140 nativeProcTotalPss += myTotalPss; 14141 14142 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14143 st.name, myTotalPss, st.pid, false); 14144 procMems.add(pssItem); 14145 14146 nativePss += mi.nativePss; 14147 dalvikPss += mi.dalvikPss; 14148 otherPss += mi.otherPss; 14149 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14150 long mem = mi.getOtherPss(j); 14151 miscPss[j] += mem; 14152 otherPss -= mem; 14153 } 14154 oomPss[0] += myTotalPss; 14155 if (oomProcs[0] == null) { 14156 oomProcs[0] = new ArrayList<MemItem>(); 14157 } 14158 oomProcs[0].add(pssItem); 14159 } 14160 } 14161 } 14162 14163 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14164 14165 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14166 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14167 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14168 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14169 String label = Debug.MemoryInfo.getOtherLabel(j); 14170 catMems.add(new MemItem(label, label, miscPss[j], j)); 14171 } 14172 14173 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14174 for (int j=0; j<oomPss.length; j++) { 14175 if (oomPss[j] != 0) { 14176 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14177 : DUMP_MEM_OOM_LABEL[j]; 14178 MemItem item = new MemItem(label, label, oomPss[j], 14179 DUMP_MEM_OOM_ADJ[j]); 14180 item.subitems = oomProcs[j]; 14181 oomMems.add(item); 14182 } 14183 } 14184 14185 if (!brief && !oomOnly && !isCompact) { 14186 pw.println(); 14187 pw.println("Total PSS by process:"); 14188 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14189 pw.println(); 14190 } 14191 if (!isCompact) { 14192 pw.println("Total PSS by OOM adjustment:"); 14193 } 14194 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14195 if (!brief && !oomOnly) { 14196 PrintWriter out = categoryPw != null ? categoryPw : pw; 14197 if (!isCompact) { 14198 out.println(); 14199 out.println("Total PSS by category:"); 14200 } 14201 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14202 } 14203 if (!isCompact) { 14204 pw.println(); 14205 } 14206 MemInfoReader memInfo = new MemInfoReader(); 14207 memInfo.readMemInfo(); 14208 if (nativeProcTotalPss > 0) { 14209 synchronized (this) { 14210 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14211 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14212 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14213 } 14214 } 14215 if (!brief) { 14216 if (!isCompact) { 14217 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14218 pw.print(" kB (status "); 14219 switch (mLastMemoryLevel) { 14220 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14221 pw.println("normal)"); 14222 break; 14223 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14224 pw.println("moderate)"); 14225 break; 14226 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14227 pw.println("low)"); 14228 break; 14229 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14230 pw.println("critical)"); 14231 break; 14232 default: 14233 pw.print(mLastMemoryLevel); 14234 pw.println(")"); 14235 break; 14236 } 14237 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14238 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14239 pw.print(cachedPss); pw.print(" cached pss + "); 14240 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14241 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14242 } else { 14243 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14244 pw.print(cachedPss + memInfo.getCachedSizeKb() 14245 + memInfo.getFreeSizeKb()); pw.print(","); 14246 pw.println(totalPss - cachedPss); 14247 } 14248 } 14249 if (!isCompact) { 14250 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14251 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14252 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14253 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14254 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14255 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14256 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14257 } 14258 if (!brief) { 14259 if (memInfo.getZramTotalSizeKb() != 0) { 14260 if (!isCompact) { 14261 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14262 pw.print(" kB physical used for "); 14263 pw.print(memInfo.getSwapTotalSizeKb() 14264 - memInfo.getSwapFreeSizeKb()); 14265 pw.print(" kB in swap ("); 14266 pw.print(memInfo.getSwapTotalSizeKb()); 14267 pw.println(" kB total swap)"); 14268 } else { 14269 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14270 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14271 pw.println(memInfo.getSwapFreeSizeKb()); 14272 } 14273 } 14274 final long[] ksm = getKsmInfo(); 14275 if (!isCompact) { 14276 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14277 || ksm[KSM_VOLATILE] != 0) { 14278 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14279 pw.print(" kB saved from shared "); 14280 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14281 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14282 pw.print(" kB unshared; "); 14283 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14284 } 14285 pw.print(" Tuning: "); 14286 pw.print(ActivityManager.staticGetMemoryClass()); 14287 pw.print(" (large "); 14288 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14289 pw.print("), oom "); 14290 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14291 pw.print(" kB"); 14292 pw.print(", restore limit "); 14293 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14294 pw.print(" kB"); 14295 if (ActivityManager.isLowRamDeviceStatic()) { 14296 pw.print(" (low-ram)"); 14297 } 14298 if (ActivityManager.isHighEndGfx()) { 14299 pw.print(" (high-end-gfx)"); 14300 } 14301 pw.println(); 14302 } else { 14303 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14304 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14305 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14306 pw.print("tuning,"); 14307 pw.print(ActivityManager.staticGetMemoryClass()); 14308 pw.print(','); 14309 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14310 pw.print(','); 14311 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14312 if (ActivityManager.isLowRamDeviceStatic()) { 14313 pw.print(",low-ram"); 14314 } 14315 if (ActivityManager.isHighEndGfx()) { 14316 pw.print(",high-end-gfx"); 14317 } 14318 pw.println(); 14319 } 14320 } 14321 } 14322 } 14323 14324 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14325 String name) { 14326 sb.append(" "); 14327 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14328 sb.append(' '); 14329 sb.append(ProcessList.makeProcStateString(procState)); 14330 sb.append(' '); 14331 ProcessList.appendRamKb(sb, pss); 14332 sb.append(" kB: "); 14333 sb.append(name); 14334 } 14335 14336 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14337 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14338 sb.append(" ("); 14339 sb.append(mi.pid); 14340 sb.append(") "); 14341 sb.append(mi.adjType); 14342 sb.append('\n'); 14343 if (mi.adjReason != null) { 14344 sb.append(" "); 14345 sb.append(mi.adjReason); 14346 sb.append('\n'); 14347 } 14348 } 14349 14350 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14351 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14352 for (int i=0, N=memInfos.size(); i<N; i++) { 14353 ProcessMemInfo mi = memInfos.get(i); 14354 infoMap.put(mi.pid, mi); 14355 } 14356 updateCpuStatsNow(); 14357 synchronized (mProcessCpuTracker) { 14358 final int N = mProcessCpuTracker.countStats(); 14359 for (int i=0; i<N; i++) { 14360 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14361 if (st.vsize > 0) { 14362 long pss = Debug.getPss(st.pid, null); 14363 if (pss > 0) { 14364 if (infoMap.indexOfKey(st.pid) < 0) { 14365 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14366 ProcessList.NATIVE_ADJ, -1, "native", null); 14367 mi.pss = pss; 14368 memInfos.add(mi); 14369 } 14370 } 14371 } 14372 } 14373 } 14374 14375 long totalPss = 0; 14376 for (int i=0, N=memInfos.size(); i<N; i++) { 14377 ProcessMemInfo mi = memInfos.get(i); 14378 if (mi.pss == 0) { 14379 mi.pss = Debug.getPss(mi.pid, null); 14380 } 14381 totalPss += mi.pss; 14382 } 14383 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14384 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14385 if (lhs.oomAdj != rhs.oomAdj) { 14386 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14387 } 14388 if (lhs.pss != rhs.pss) { 14389 return lhs.pss < rhs.pss ? 1 : -1; 14390 } 14391 return 0; 14392 } 14393 }); 14394 14395 StringBuilder tag = new StringBuilder(128); 14396 StringBuilder stack = new StringBuilder(128); 14397 tag.append("Low on memory -- "); 14398 appendMemBucket(tag, totalPss, "total", false); 14399 appendMemBucket(stack, totalPss, "total", true); 14400 14401 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14402 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14403 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14404 14405 boolean firstLine = true; 14406 int lastOomAdj = Integer.MIN_VALUE; 14407 long extraNativeRam = 0; 14408 long cachedPss = 0; 14409 for (int i=0, N=memInfos.size(); i<N; i++) { 14410 ProcessMemInfo mi = memInfos.get(i); 14411 14412 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14413 cachedPss += mi.pss; 14414 } 14415 14416 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14417 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14418 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14419 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14420 if (lastOomAdj != mi.oomAdj) { 14421 lastOomAdj = mi.oomAdj; 14422 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14423 tag.append(" / "); 14424 } 14425 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14426 if (firstLine) { 14427 stack.append(":"); 14428 firstLine = false; 14429 } 14430 stack.append("\n\t at "); 14431 } else { 14432 stack.append("$"); 14433 } 14434 } else { 14435 tag.append(" "); 14436 stack.append("$"); 14437 } 14438 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14439 appendMemBucket(tag, mi.pss, mi.name, false); 14440 } 14441 appendMemBucket(stack, mi.pss, mi.name, true); 14442 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14443 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14444 stack.append("("); 14445 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14446 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14447 stack.append(DUMP_MEM_OOM_LABEL[k]); 14448 stack.append(":"); 14449 stack.append(DUMP_MEM_OOM_ADJ[k]); 14450 } 14451 } 14452 stack.append(")"); 14453 } 14454 } 14455 14456 appendMemInfo(fullNativeBuilder, mi); 14457 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14458 // The short form only has native processes that are >= 1MB. 14459 if (mi.pss >= 1000) { 14460 appendMemInfo(shortNativeBuilder, mi); 14461 } else { 14462 extraNativeRam += mi.pss; 14463 } 14464 } else { 14465 // Short form has all other details, but if we have collected RAM 14466 // from smaller native processes let's dump a summary of that. 14467 if (extraNativeRam > 0) { 14468 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14469 -1, extraNativeRam, "(Other native)"); 14470 shortNativeBuilder.append('\n'); 14471 extraNativeRam = 0; 14472 } 14473 appendMemInfo(fullJavaBuilder, mi); 14474 } 14475 } 14476 14477 fullJavaBuilder.append(" "); 14478 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14479 fullJavaBuilder.append(" kB: TOTAL\n"); 14480 14481 MemInfoReader memInfo = new MemInfoReader(); 14482 memInfo.readMemInfo(); 14483 final long[] infos = memInfo.getRawInfo(); 14484 14485 StringBuilder memInfoBuilder = new StringBuilder(1024); 14486 Debug.getMemInfo(infos); 14487 memInfoBuilder.append(" MemInfo: "); 14488 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14489 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14490 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14491 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14492 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14493 memInfoBuilder.append(" "); 14494 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14495 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14496 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14497 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14498 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14499 memInfoBuilder.append(" ZRAM: "); 14500 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14501 memInfoBuilder.append(" kB RAM, "); 14502 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14503 memInfoBuilder.append(" kB swap total, "); 14504 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14505 memInfoBuilder.append(" kB swap free\n"); 14506 } 14507 final long[] ksm = getKsmInfo(); 14508 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14509 || ksm[KSM_VOLATILE] != 0) { 14510 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14511 memInfoBuilder.append(" kB saved from shared "); 14512 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14513 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14514 memInfoBuilder.append(" kB unshared; "); 14515 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14516 } 14517 memInfoBuilder.append(" Free RAM: "); 14518 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14519 + memInfo.getFreeSizeKb()); 14520 memInfoBuilder.append(" kB\n"); 14521 memInfoBuilder.append(" Used RAM: "); 14522 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14523 memInfoBuilder.append(" kB\n"); 14524 memInfoBuilder.append(" Lost RAM: "); 14525 memInfoBuilder.append(memInfo.getTotalSizeKb() 14526 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14527 - memInfo.getKernelUsedSizeKb()); 14528 memInfoBuilder.append(" kB\n"); 14529 Slog.i(TAG, "Low on memory:"); 14530 Slog.i(TAG, shortNativeBuilder.toString()); 14531 Slog.i(TAG, fullJavaBuilder.toString()); 14532 Slog.i(TAG, memInfoBuilder.toString()); 14533 14534 StringBuilder dropBuilder = new StringBuilder(1024); 14535 /* 14536 StringWriter oomSw = new StringWriter(); 14537 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14538 StringWriter catSw = new StringWriter(); 14539 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14540 String[] emptyArgs = new String[] { }; 14541 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14542 oomPw.flush(); 14543 String oomString = oomSw.toString(); 14544 */ 14545 dropBuilder.append("Low on memory:"); 14546 dropBuilder.append(stack); 14547 dropBuilder.append('\n'); 14548 dropBuilder.append(fullNativeBuilder); 14549 dropBuilder.append(fullJavaBuilder); 14550 dropBuilder.append('\n'); 14551 dropBuilder.append(memInfoBuilder); 14552 dropBuilder.append('\n'); 14553 /* 14554 dropBuilder.append(oomString); 14555 dropBuilder.append('\n'); 14556 */ 14557 StringWriter catSw = new StringWriter(); 14558 synchronized (ActivityManagerService.this) { 14559 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14560 String[] emptyArgs = new String[] { }; 14561 catPw.println(); 14562 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14563 catPw.println(); 14564 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14565 false, false, null); 14566 catPw.println(); 14567 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14568 catPw.flush(); 14569 } 14570 dropBuilder.append(catSw.toString()); 14571 addErrorToDropBox("lowmem", null, "system_server", null, 14572 null, tag.toString(), dropBuilder.toString(), null, null); 14573 //Slog.i(TAG, "Sent to dropbox:"); 14574 //Slog.i(TAG, dropBuilder.toString()); 14575 synchronized (ActivityManagerService.this) { 14576 long now = SystemClock.uptimeMillis(); 14577 if (mLastMemUsageReportTime < now) { 14578 mLastMemUsageReportTime = now; 14579 } 14580 } 14581 } 14582 14583 /** 14584 * Searches array of arguments for the specified string 14585 * @param args array of argument strings 14586 * @param value value to search for 14587 * @return true if the value is contained in the array 14588 */ 14589 private static boolean scanArgs(String[] args, String value) { 14590 if (args != null) { 14591 for (String arg : args) { 14592 if (value.equals(arg)) { 14593 return true; 14594 } 14595 } 14596 } 14597 return false; 14598 } 14599 14600 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14601 ContentProviderRecord cpr, boolean always) { 14602 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14603 14604 if (!inLaunching || always) { 14605 synchronized (cpr) { 14606 cpr.launchingApp = null; 14607 cpr.notifyAll(); 14608 } 14609 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14610 String names[] = cpr.info.authority.split(";"); 14611 for (int j = 0; j < names.length; j++) { 14612 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14613 } 14614 } 14615 14616 for (int i=0; i<cpr.connections.size(); i++) { 14617 ContentProviderConnection conn = cpr.connections.get(i); 14618 if (conn.waiting) { 14619 // If this connection is waiting for the provider, then we don't 14620 // need to mess with its process unless we are always removing 14621 // or for some reason the provider is not currently launching. 14622 if (inLaunching && !always) { 14623 continue; 14624 } 14625 } 14626 ProcessRecord capp = conn.client; 14627 conn.dead = true; 14628 if (conn.stableCount > 0) { 14629 if (!capp.persistent && capp.thread != null 14630 && capp.pid != 0 14631 && capp.pid != MY_PID) { 14632 capp.kill("depends on provider " 14633 + cpr.name.flattenToShortString() 14634 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14635 } 14636 } else if (capp.thread != null && conn.provider.provider != null) { 14637 try { 14638 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14639 } catch (RemoteException e) { 14640 } 14641 // In the protocol here, we don't expect the client to correctly 14642 // clean up this connection, we'll just remove it. 14643 cpr.connections.remove(i); 14644 conn.client.conProviders.remove(conn); 14645 } 14646 } 14647 14648 if (inLaunching && always) { 14649 mLaunchingProviders.remove(cpr); 14650 } 14651 return inLaunching; 14652 } 14653 14654 /** 14655 * Main code for cleaning up a process when it has gone away. This is 14656 * called both as a result of the process dying, or directly when stopping 14657 * a process when running in single process mode. 14658 * 14659 * @return Returns true if the given process has been restarted, so the 14660 * app that was passed in must remain on the process lists. 14661 */ 14662 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14663 boolean restarting, boolean allowRestart, int index) { 14664 if (index >= 0) { 14665 removeLruProcessLocked(app); 14666 ProcessList.remove(app.pid); 14667 } 14668 14669 mProcessesToGc.remove(app); 14670 mPendingPssProcesses.remove(app); 14671 14672 // Dismiss any open dialogs. 14673 if (app.crashDialog != null && !app.forceCrashReport) { 14674 app.crashDialog.dismiss(); 14675 app.crashDialog = null; 14676 } 14677 if (app.anrDialog != null) { 14678 app.anrDialog.dismiss(); 14679 app.anrDialog = null; 14680 } 14681 if (app.waitDialog != null) { 14682 app.waitDialog.dismiss(); 14683 app.waitDialog = null; 14684 } 14685 14686 app.crashing = false; 14687 app.notResponding = false; 14688 14689 app.resetPackageList(mProcessStats); 14690 app.unlinkDeathRecipient(); 14691 app.makeInactive(mProcessStats); 14692 app.waitingToKill = null; 14693 app.forcingToForeground = null; 14694 updateProcessForegroundLocked(app, false, false); 14695 app.foregroundActivities = false; 14696 app.hasShownUi = false; 14697 app.treatLikeActivity = false; 14698 app.hasAboveClient = false; 14699 app.hasClientActivities = false; 14700 14701 mServices.killServicesLocked(app, allowRestart); 14702 14703 boolean restart = false; 14704 14705 // Remove published content providers. 14706 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14707 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14708 final boolean always = app.bad || !allowRestart; 14709 if (removeDyingProviderLocked(app, cpr, always) || always) { 14710 // We left the provider in the launching list, need to 14711 // restart it. 14712 restart = true; 14713 } 14714 14715 cpr.provider = null; 14716 cpr.proc = null; 14717 } 14718 app.pubProviders.clear(); 14719 14720 // Take care of any launching providers waiting for this process. 14721 if (checkAppInLaunchingProvidersLocked(app, false)) { 14722 restart = true; 14723 } 14724 14725 // Unregister from connected content providers. 14726 if (!app.conProviders.isEmpty()) { 14727 for (int i=0; i<app.conProviders.size(); i++) { 14728 ContentProviderConnection conn = app.conProviders.get(i); 14729 conn.provider.connections.remove(conn); 14730 } 14731 app.conProviders.clear(); 14732 } 14733 14734 // At this point there may be remaining entries in mLaunchingProviders 14735 // where we were the only one waiting, so they are no longer of use. 14736 // Look for these and clean up if found. 14737 // XXX Commented out for now. Trying to figure out a way to reproduce 14738 // the actual situation to identify what is actually going on. 14739 if (false) { 14740 for (int i=0; i<mLaunchingProviders.size(); i++) { 14741 ContentProviderRecord cpr = (ContentProviderRecord) 14742 mLaunchingProviders.get(i); 14743 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14744 synchronized (cpr) { 14745 cpr.launchingApp = null; 14746 cpr.notifyAll(); 14747 } 14748 } 14749 } 14750 } 14751 14752 skipCurrentReceiverLocked(app); 14753 14754 // Unregister any receivers. 14755 for (int i=app.receivers.size()-1; i>=0; i--) { 14756 removeReceiverLocked(app.receivers.valueAt(i)); 14757 } 14758 app.receivers.clear(); 14759 14760 // If the app is undergoing backup, tell the backup manager about it 14761 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14762 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14763 + mBackupTarget.appInfo + " died during backup"); 14764 try { 14765 IBackupManager bm = IBackupManager.Stub.asInterface( 14766 ServiceManager.getService(Context.BACKUP_SERVICE)); 14767 bm.agentDisconnected(app.info.packageName); 14768 } catch (RemoteException e) { 14769 // can't happen; backup manager is local 14770 } 14771 } 14772 14773 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14774 ProcessChangeItem item = mPendingProcessChanges.get(i); 14775 if (item.pid == app.pid) { 14776 mPendingProcessChanges.remove(i); 14777 mAvailProcessChanges.add(item); 14778 } 14779 } 14780 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14781 14782 // If the caller is restarting this app, then leave it in its 14783 // current lists and let the caller take care of it. 14784 if (restarting) { 14785 return false; 14786 } 14787 14788 if (!app.persistent || app.isolated) { 14789 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14790 "Removing non-persistent process during cleanup: " + app); 14791 mProcessNames.remove(app.processName, app.uid); 14792 mIsolatedProcesses.remove(app.uid); 14793 if (mHeavyWeightProcess == app) { 14794 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14795 mHeavyWeightProcess.userId, 0)); 14796 mHeavyWeightProcess = null; 14797 } 14798 } else if (!app.removed) { 14799 // This app is persistent, so we need to keep its record around. 14800 // If it is not already on the pending app list, add it there 14801 // and start a new process for it. 14802 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14803 mPersistentStartingProcesses.add(app); 14804 restart = true; 14805 } 14806 } 14807 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14808 "Clean-up removing on hold: " + app); 14809 mProcessesOnHold.remove(app); 14810 14811 if (app == mHomeProcess) { 14812 mHomeProcess = null; 14813 } 14814 if (app == mPreviousProcess) { 14815 mPreviousProcess = null; 14816 } 14817 14818 if (restart && !app.isolated) { 14819 // We have components that still need to be running in the 14820 // process, so re-launch it. 14821 if (index < 0) { 14822 ProcessList.remove(app.pid); 14823 } 14824 mProcessNames.put(app.processName, app.uid, app); 14825 startProcessLocked(app, "restart", app.processName); 14826 return true; 14827 } else if (app.pid > 0 && app.pid != MY_PID) { 14828 // Goodbye! 14829 boolean removed; 14830 synchronized (mPidsSelfLocked) { 14831 mPidsSelfLocked.remove(app.pid); 14832 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14833 } 14834 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14835 if (app.isolated) { 14836 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14837 } 14838 app.setPid(0); 14839 } 14840 return false; 14841 } 14842 14843 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14844 // Look through the content providers we are waiting to have launched, 14845 // and if any run in this process then either schedule a restart of 14846 // the process or kill the client waiting for it if this process has 14847 // gone bad. 14848 int NL = mLaunchingProviders.size(); 14849 boolean restart = false; 14850 for (int i=0; i<NL; i++) { 14851 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14852 if (cpr.launchingApp == app) { 14853 if (!alwaysBad && !app.bad) { 14854 restart = true; 14855 } else { 14856 removeDyingProviderLocked(app, cpr, true); 14857 // cpr should have been removed from mLaunchingProviders 14858 NL = mLaunchingProviders.size(); 14859 i--; 14860 } 14861 } 14862 } 14863 return restart; 14864 } 14865 14866 // ========================================================= 14867 // SERVICES 14868 // ========================================================= 14869 14870 @Override 14871 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14872 int flags) { 14873 enforceNotIsolatedCaller("getServices"); 14874 synchronized (this) { 14875 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14876 } 14877 } 14878 14879 @Override 14880 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14881 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14882 synchronized (this) { 14883 return mServices.getRunningServiceControlPanelLocked(name); 14884 } 14885 } 14886 14887 @Override 14888 public ComponentName startService(IApplicationThread caller, Intent service, 14889 String resolvedType, int userId) { 14890 enforceNotIsolatedCaller("startService"); 14891 // Refuse possible leaked file descriptors 14892 if (service != null && service.hasFileDescriptors() == true) { 14893 throw new IllegalArgumentException("File descriptors passed in Intent"); 14894 } 14895 14896 if (DEBUG_SERVICE) 14897 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14898 synchronized(this) { 14899 final int callingPid = Binder.getCallingPid(); 14900 final int callingUid = Binder.getCallingUid(); 14901 final long origId = Binder.clearCallingIdentity(); 14902 ComponentName res = mServices.startServiceLocked(caller, service, 14903 resolvedType, callingPid, callingUid, userId); 14904 Binder.restoreCallingIdentity(origId); 14905 return res; 14906 } 14907 } 14908 14909 ComponentName startServiceInPackage(int uid, 14910 Intent service, String resolvedType, int userId) { 14911 synchronized(this) { 14912 if (DEBUG_SERVICE) 14913 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14914 final long origId = Binder.clearCallingIdentity(); 14915 ComponentName res = mServices.startServiceLocked(null, service, 14916 resolvedType, -1, uid, userId); 14917 Binder.restoreCallingIdentity(origId); 14918 return res; 14919 } 14920 } 14921 14922 @Override 14923 public int stopService(IApplicationThread caller, Intent service, 14924 String resolvedType, int userId) { 14925 enforceNotIsolatedCaller("stopService"); 14926 // Refuse possible leaked file descriptors 14927 if (service != null && service.hasFileDescriptors() == true) { 14928 throw new IllegalArgumentException("File descriptors passed in Intent"); 14929 } 14930 14931 synchronized(this) { 14932 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14933 } 14934 } 14935 14936 @Override 14937 public IBinder peekService(Intent service, String resolvedType) { 14938 enforceNotIsolatedCaller("peekService"); 14939 // Refuse possible leaked file descriptors 14940 if (service != null && service.hasFileDescriptors() == true) { 14941 throw new IllegalArgumentException("File descriptors passed in Intent"); 14942 } 14943 synchronized(this) { 14944 return mServices.peekServiceLocked(service, resolvedType); 14945 } 14946 } 14947 14948 @Override 14949 public boolean stopServiceToken(ComponentName className, IBinder token, 14950 int startId) { 14951 synchronized(this) { 14952 return mServices.stopServiceTokenLocked(className, token, startId); 14953 } 14954 } 14955 14956 @Override 14957 public void setServiceForeground(ComponentName className, IBinder token, 14958 int id, Notification notification, boolean removeNotification) { 14959 synchronized(this) { 14960 mServices.setServiceForegroundLocked(className, token, id, notification, 14961 removeNotification); 14962 } 14963 } 14964 14965 @Override 14966 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14967 boolean requireFull, String name, String callerPackage) { 14968 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14969 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14970 } 14971 14972 int unsafeConvertIncomingUser(int userId) { 14973 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14974 ? mCurrentUserId : userId; 14975 } 14976 14977 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14978 int allowMode, String name, String callerPackage) { 14979 final int callingUserId = UserHandle.getUserId(callingUid); 14980 if (callingUserId == userId) { 14981 return userId; 14982 } 14983 14984 // Note that we may be accessing mCurrentUserId outside of a lock... 14985 // shouldn't be a big deal, if this is being called outside 14986 // of a locked context there is intrinsically a race with 14987 // the value the caller will receive and someone else changing it. 14988 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14989 // we will switch to the calling user if access to the current user fails. 14990 int targetUserId = unsafeConvertIncomingUser(userId); 14991 14992 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14993 final boolean allow; 14994 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14995 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14996 // If the caller has this permission, they always pass go. And collect $200. 14997 allow = true; 14998 } else if (allowMode == ALLOW_FULL_ONLY) { 14999 // We require full access, sucks to be you. 15000 allow = false; 15001 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15002 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15003 // If the caller does not have either permission, they are always doomed. 15004 allow = false; 15005 } else if (allowMode == ALLOW_NON_FULL) { 15006 // We are blanket allowing non-full access, you lucky caller! 15007 allow = true; 15008 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15009 // We may or may not allow this depending on whether the two users are 15010 // in the same profile. 15011 synchronized (mUserProfileGroupIdsSelfLocked) { 15012 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15013 UserInfo.NO_PROFILE_GROUP_ID); 15014 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15015 UserInfo.NO_PROFILE_GROUP_ID); 15016 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15017 && callingProfile == targetProfile; 15018 } 15019 } else { 15020 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15021 } 15022 if (!allow) { 15023 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15024 // In this case, they would like to just execute as their 15025 // owner user instead of failing. 15026 targetUserId = callingUserId; 15027 } else { 15028 StringBuilder builder = new StringBuilder(128); 15029 builder.append("Permission Denial: "); 15030 builder.append(name); 15031 if (callerPackage != null) { 15032 builder.append(" from "); 15033 builder.append(callerPackage); 15034 } 15035 builder.append(" asks to run as user "); 15036 builder.append(userId); 15037 builder.append(" but is calling from user "); 15038 builder.append(UserHandle.getUserId(callingUid)); 15039 builder.append("; this requires "); 15040 builder.append(INTERACT_ACROSS_USERS_FULL); 15041 if (allowMode != ALLOW_FULL_ONLY) { 15042 builder.append(" or "); 15043 builder.append(INTERACT_ACROSS_USERS); 15044 } 15045 String msg = builder.toString(); 15046 Slog.w(TAG, msg); 15047 throw new SecurityException(msg); 15048 } 15049 } 15050 } 15051 if (!allowAll && targetUserId < 0) { 15052 throw new IllegalArgumentException( 15053 "Call does not support special user #" + targetUserId); 15054 } 15055 // Check shell permission 15056 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15057 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15058 targetUserId)) { 15059 throw new SecurityException("Shell does not have permission to access user " 15060 + targetUserId + "\n " + Debug.getCallers(3)); 15061 } 15062 } 15063 return targetUserId; 15064 } 15065 15066 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15067 String className, int flags) { 15068 boolean result = false; 15069 // For apps that don't have pre-defined UIDs, check for permission 15070 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15071 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15072 if (ActivityManager.checkUidPermission( 15073 INTERACT_ACROSS_USERS, 15074 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15075 ComponentName comp = new ComponentName(aInfo.packageName, className); 15076 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15077 + " requests FLAG_SINGLE_USER, but app does not hold " 15078 + INTERACT_ACROSS_USERS; 15079 Slog.w(TAG, msg); 15080 throw new SecurityException(msg); 15081 } 15082 // Permission passed 15083 result = true; 15084 } 15085 } else if ("system".equals(componentProcessName)) { 15086 result = true; 15087 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15088 // Phone app and persistent apps are allowed to export singleuser providers. 15089 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15090 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15091 } 15092 if (DEBUG_MU) { 15093 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15094 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15095 } 15096 return result; 15097 } 15098 15099 /** 15100 * Checks to see if the caller is in the same app as the singleton 15101 * component, or the component is in a special app. It allows special apps 15102 * to export singleton components but prevents exporting singleton 15103 * components for regular apps. 15104 */ 15105 boolean isValidSingletonCall(int callingUid, int componentUid) { 15106 int componentAppId = UserHandle.getAppId(componentUid); 15107 return UserHandle.isSameApp(callingUid, componentUid) 15108 || componentAppId == Process.SYSTEM_UID 15109 || componentAppId == Process.PHONE_UID 15110 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15111 == PackageManager.PERMISSION_GRANTED; 15112 } 15113 15114 public int bindService(IApplicationThread caller, IBinder token, 15115 Intent service, String resolvedType, 15116 IServiceConnection connection, int flags, int userId) { 15117 enforceNotIsolatedCaller("bindService"); 15118 15119 // Refuse possible leaked file descriptors 15120 if (service != null && service.hasFileDescriptors() == true) { 15121 throw new IllegalArgumentException("File descriptors passed in Intent"); 15122 } 15123 15124 synchronized(this) { 15125 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15126 connection, flags, userId); 15127 } 15128 } 15129 15130 public boolean unbindService(IServiceConnection connection) { 15131 synchronized (this) { 15132 return mServices.unbindServiceLocked(connection); 15133 } 15134 } 15135 15136 public void publishService(IBinder token, Intent intent, IBinder service) { 15137 // Refuse possible leaked file descriptors 15138 if (intent != null && intent.hasFileDescriptors() == true) { 15139 throw new IllegalArgumentException("File descriptors passed in Intent"); 15140 } 15141 15142 synchronized(this) { 15143 if (!(token instanceof ServiceRecord)) { 15144 throw new IllegalArgumentException("Invalid service token"); 15145 } 15146 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15147 } 15148 } 15149 15150 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15151 // Refuse possible leaked file descriptors 15152 if (intent != null && intent.hasFileDescriptors() == true) { 15153 throw new IllegalArgumentException("File descriptors passed in Intent"); 15154 } 15155 15156 synchronized(this) { 15157 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15158 } 15159 } 15160 15161 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15162 synchronized(this) { 15163 if (!(token instanceof ServiceRecord)) { 15164 throw new IllegalArgumentException("Invalid service token"); 15165 } 15166 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15167 } 15168 } 15169 15170 // ========================================================= 15171 // BACKUP AND RESTORE 15172 // ========================================================= 15173 15174 // Cause the target app to be launched if necessary and its backup agent 15175 // instantiated. The backup agent will invoke backupAgentCreated() on the 15176 // activity manager to announce its creation. 15177 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15178 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15179 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15180 15181 synchronized(this) { 15182 // !!! TODO: currently no check here that we're already bound 15183 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15184 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15185 synchronized (stats) { 15186 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15187 } 15188 15189 // Backup agent is now in use, its package can't be stopped. 15190 try { 15191 AppGlobals.getPackageManager().setPackageStoppedState( 15192 app.packageName, false, UserHandle.getUserId(app.uid)); 15193 } catch (RemoteException e) { 15194 } catch (IllegalArgumentException e) { 15195 Slog.w(TAG, "Failed trying to unstop package " 15196 + app.packageName + ": " + e); 15197 } 15198 15199 BackupRecord r = new BackupRecord(ss, app, backupMode); 15200 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15201 ? new ComponentName(app.packageName, app.backupAgentName) 15202 : new ComponentName("android", "FullBackupAgent"); 15203 // startProcessLocked() returns existing proc's record if it's already running 15204 ProcessRecord proc = startProcessLocked(app.processName, app, 15205 false, 0, "backup", hostingName, false, false, false); 15206 if (proc == null) { 15207 Slog.e(TAG, "Unable to start backup agent process " + r); 15208 return false; 15209 } 15210 15211 r.app = proc; 15212 mBackupTarget = r; 15213 mBackupAppName = app.packageName; 15214 15215 // Try not to kill the process during backup 15216 updateOomAdjLocked(proc); 15217 15218 // If the process is already attached, schedule the creation of the backup agent now. 15219 // If it is not yet live, this will be done when it attaches to the framework. 15220 if (proc.thread != null) { 15221 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15222 try { 15223 proc.thread.scheduleCreateBackupAgent(app, 15224 compatibilityInfoForPackageLocked(app), backupMode); 15225 } catch (RemoteException e) { 15226 // Will time out on the backup manager side 15227 } 15228 } else { 15229 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15230 } 15231 // Invariants: at this point, the target app process exists and the application 15232 // is either already running or in the process of coming up. mBackupTarget and 15233 // mBackupAppName describe the app, so that when it binds back to the AM we 15234 // know that it's scheduled for a backup-agent operation. 15235 } 15236 15237 return true; 15238 } 15239 15240 @Override 15241 public void clearPendingBackup() { 15242 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15243 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15244 15245 synchronized (this) { 15246 mBackupTarget = null; 15247 mBackupAppName = null; 15248 } 15249 } 15250 15251 // A backup agent has just come up 15252 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15253 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15254 + " = " + agent); 15255 15256 synchronized(this) { 15257 if (!agentPackageName.equals(mBackupAppName)) { 15258 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15259 return; 15260 } 15261 } 15262 15263 long oldIdent = Binder.clearCallingIdentity(); 15264 try { 15265 IBackupManager bm = IBackupManager.Stub.asInterface( 15266 ServiceManager.getService(Context.BACKUP_SERVICE)); 15267 bm.agentConnected(agentPackageName, agent); 15268 } catch (RemoteException e) { 15269 // can't happen; the backup manager service is local 15270 } catch (Exception e) { 15271 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15272 e.printStackTrace(); 15273 } finally { 15274 Binder.restoreCallingIdentity(oldIdent); 15275 } 15276 } 15277 15278 // done with this agent 15279 public void unbindBackupAgent(ApplicationInfo appInfo) { 15280 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15281 if (appInfo == null) { 15282 Slog.w(TAG, "unbind backup agent for null app"); 15283 return; 15284 } 15285 15286 synchronized(this) { 15287 try { 15288 if (mBackupAppName == null) { 15289 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15290 return; 15291 } 15292 15293 if (!mBackupAppName.equals(appInfo.packageName)) { 15294 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15295 return; 15296 } 15297 15298 // Not backing this app up any more; reset its OOM adjustment 15299 final ProcessRecord proc = mBackupTarget.app; 15300 updateOomAdjLocked(proc); 15301 15302 // If the app crashed during backup, 'thread' will be null here 15303 if (proc.thread != null) { 15304 try { 15305 proc.thread.scheduleDestroyBackupAgent(appInfo, 15306 compatibilityInfoForPackageLocked(appInfo)); 15307 } catch (Exception e) { 15308 Slog.e(TAG, "Exception when unbinding backup agent:"); 15309 e.printStackTrace(); 15310 } 15311 } 15312 } finally { 15313 mBackupTarget = null; 15314 mBackupAppName = null; 15315 } 15316 } 15317 } 15318 // ========================================================= 15319 // BROADCASTS 15320 // ========================================================= 15321 15322 private final List getStickiesLocked(String action, IntentFilter filter, 15323 List cur, int userId) { 15324 final ContentResolver resolver = mContext.getContentResolver(); 15325 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15326 if (stickies == null) { 15327 return cur; 15328 } 15329 final ArrayList<Intent> list = stickies.get(action); 15330 if (list == null) { 15331 return cur; 15332 } 15333 int N = list.size(); 15334 for (int i=0; i<N; i++) { 15335 Intent intent = list.get(i); 15336 if (filter.match(resolver, intent, true, TAG) >= 0) { 15337 if (cur == null) { 15338 cur = new ArrayList<Intent>(); 15339 } 15340 cur.add(intent); 15341 } 15342 } 15343 return cur; 15344 } 15345 15346 boolean isPendingBroadcastProcessLocked(int pid) { 15347 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15348 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15349 } 15350 15351 void skipPendingBroadcastLocked(int pid) { 15352 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15353 for (BroadcastQueue queue : mBroadcastQueues) { 15354 queue.skipPendingBroadcastLocked(pid); 15355 } 15356 } 15357 15358 // The app just attached; send any pending broadcasts that it should receive 15359 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15360 boolean didSomething = false; 15361 for (BroadcastQueue queue : mBroadcastQueues) { 15362 didSomething |= queue.sendPendingBroadcastsLocked(app); 15363 } 15364 return didSomething; 15365 } 15366 15367 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15368 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15369 enforceNotIsolatedCaller("registerReceiver"); 15370 int callingUid; 15371 int callingPid; 15372 synchronized(this) { 15373 ProcessRecord callerApp = null; 15374 if (caller != null) { 15375 callerApp = getRecordForAppLocked(caller); 15376 if (callerApp == null) { 15377 throw new SecurityException( 15378 "Unable to find app for caller " + caller 15379 + " (pid=" + Binder.getCallingPid() 15380 + ") when registering receiver " + receiver); 15381 } 15382 if (callerApp.info.uid != Process.SYSTEM_UID && 15383 !callerApp.pkgList.containsKey(callerPackage) && 15384 !"android".equals(callerPackage)) { 15385 throw new SecurityException("Given caller package " + callerPackage 15386 + " is not running in process " + callerApp); 15387 } 15388 callingUid = callerApp.info.uid; 15389 callingPid = callerApp.pid; 15390 } else { 15391 callerPackage = null; 15392 callingUid = Binder.getCallingUid(); 15393 callingPid = Binder.getCallingPid(); 15394 } 15395 15396 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15397 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15398 15399 List allSticky = null; 15400 15401 // Look for any matching sticky broadcasts... 15402 Iterator actions = filter.actionsIterator(); 15403 if (actions != null) { 15404 while (actions.hasNext()) { 15405 String action = (String)actions.next(); 15406 allSticky = getStickiesLocked(action, filter, allSticky, 15407 UserHandle.USER_ALL); 15408 allSticky = getStickiesLocked(action, filter, allSticky, 15409 UserHandle.getUserId(callingUid)); 15410 } 15411 } else { 15412 allSticky = getStickiesLocked(null, filter, allSticky, 15413 UserHandle.USER_ALL); 15414 allSticky = getStickiesLocked(null, filter, allSticky, 15415 UserHandle.getUserId(callingUid)); 15416 } 15417 15418 // The first sticky in the list is returned directly back to 15419 // the client. 15420 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15421 15422 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15423 + ": " + sticky); 15424 15425 if (receiver == null) { 15426 return sticky; 15427 } 15428 15429 ReceiverList rl 15430 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15431 if (rl == null) { 15432 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15433 userId, receiver); 15434 if (rl.app != null) { 15435 rl.app.receivers.add(rl); 15436 } else { 15437 try { 15438 receiver.asBinder().linkToDeath(rl, 0); 15439 } catch (RemoteException e) { 15440 return sticky; 15441 } 15442 rl.linkedToDeath = true; 15443 } 15444 mRegisteredReceivers.put(receiver.asBinder(), rl); 15445 } else if (rl.uid != callingUid) { 15446 throw new IllegalArgumentException( 15447 "Receiver requested to register for uid " + callingUid 15448 + " was previously registered for uid " + rl.uid); 15449 } else if (rl.pid != callingPid) { 15450 throw new IllegalArgumentException( 15451 "Receiver requested to register for pid " + callingPid 15452 + " was previously registered for pid " + rl.pid); 15453 } else if (rl.userId != userId) { 15454 throw new IllegalArgumentException( 15455 "Receiver requested to register for user " + userId 15456 + " was previously registered for user " + rl.userId); 15457 } 15458 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15459 permission, callingUid, userId); 15460 rl.add(bf); 15461 if (!bf.debugCheck()) { 15462 Slog.w(TAG, "==> For Dynamic broadast"); 15463 } 15464 mReceiverResolver.addFilter(bf); 15465 15466 // Enqueue broadcasts for all existing stickies that match 15467 // this filter. 15468 if (allSticky != null) { 15469 ArrayList receivers = new ArrayList(); 15470 receivers.add(bf); 15471 15472 int N = allSticky.size(); 15473 for (int i=0; i<N; i++) { 15474 Intent intent = (Intent)allSticky.get(i); 15475 BroadcastQueue queue = broadcastQueueForIntent(intent); 15476 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15477 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15478 null, null, false, true, true, -1); 15479 queue.enqueueParallelBroadcastLocked(r); 15480 queue.scheduleBroadcastsLocked(); 15481 } 15482 } 15483 15484 return sticky; 15485 } 15486 } 15487 15488 public void unregisterReceiver(IIntentReceiver receiver) { 15489 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15490 15491 final long origId = Binder.clearCallingIdentity(); 15492 try { 15493 boolean doTrim = false; 15494 15495 synchronized(this) { 15496 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15497 if (rl != null) { 15498 if (rl.curBroadcast != null) { 15499 BroadcastRecord r = rl.curBroadcast; 15500 final boolean doNext = finishReceiverLocked( 15501 receiver.asBinder(), r.resultCode, r.resultData, 15502 r.resultExtras, r.resultAbort); 15503 if (doNext) { 15504 doTrim = true; 15505 r.queue.processNextBroadcast(false); 15506 } 15507 } 15508 15509 if (rl.app != null) { 15510 rl.app.receivers.remove(rl); 15511 } 15512 removeReceiverLocked(rl); 15513 if (rl.linkedToDeath) { 15514 rl.linkedToDeath = false; 15515 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15516 } 15517 } 15518 } 15519 15520 // If we actually concluded any broadcasts, we might now be able 15521 // to trim the recipients' apps from our working set 15522 if (doTrim) { 15523 trimApplications(); 15524 return; 15525 } 15526 15527 } finally { 15528 Binder.restoreCallingIdentity(origId); 15529 } 15530 } 15531 15532 void removeReceiverLocked(ReceiverList rl) { 15533 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15534 int N = rl.size(); 15535 for (int i=0; i<N; i++) { 15536 mReceiverResolver.removeFilter(rl.get(i)); 15537 } 15538 } 15539 15540 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15541 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15542 ProcessRecord r = mLruProcesses.get(i); 15543 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15544 try { 15545 r.thread.dispatchPackageBroadcast(cmd, packages); 15546 } catch (RemoteException ex) { 15547 } 15548 } 15549 } 15550 } 15551 15552 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15553 int callingUid, int[] users) { 15554 List<ResolveInfo> receivers = null; 15555 try { 15556 HashSet<ComponentName> singleUserReceivers = null; 15557 boolean scannedFirstReceivers = false; 15558 for (int user : users) { 15559 // Skip users that have Shell restrictions 15560 if (callingUid == Process.SHELL_UID 15561 && getUserManagerLocked().hasUserRestriction( 15562 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15563 continue; 15564 } 15565 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15566 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15567 if (user != 0 && newReceivers != null) { 15568 // If this is not the primary user, we need to check for 15569 // any receivers that should be filtered out. 15570 for (int i=0; i<newReceivers.size(); i++) { 15571 ResolveInfo ri = newReceivers.get(i); 15572 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15573 newReceivers.remove(i); 15574 i--; 15575 } 15576 } 15577 } 15578 if (newReceivers != null && newReceivers.size() == 0) { 15579 newReceivers = null; 15580 } 15581 if (receivers == null) { 15582 receivers = newReceivers; 15583 } else if (newReceivers != null) { 15584 // We need to concatenate the additional receivers 15585 // found with what we have do far. This would be easy, 15586 // but we also need to de-dup any receivers that are 15587 // singleUser. 15588 if (!scannedFirstReceivers) { 15589 // Collect any single user receivers we had already retrieved. 15590 scannedFirstReceivers = true; 15591 for (int i=0; i<receivers.size(); i++) { 15592 ResolveInfo ri = receivers.get(i); 15593 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15594 ComponentName cn = new ComponentName( 15595 ri.activityInfo.packageName, ri.activityInfo.name); 15596 if (singleUserReceivers == null) { 15597 singleUserReceivers = new HashSet<ComponentName>(); 15598 } 15599 singleUserReceivers.add(cn); 15600 } 15601 } 15602 } 15603 // Add the new results to the existing results, tracking 15604 // and de-dupping single user receivers. 15605 for (int i=0; i<newReceivers.size(); i++) { 15606 ResolveInfo ri = newReceivers.get(i); 15607 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15608 ComponentName cn = new ComponentName( 15609 ri.activityInfo.packageName, ri.activityInfo.name); 15610 if (singleUserReceivers == null) { 15611 singleUserReceivers = new HashSet<ComponentName>(); 15612 } 15613 if (!singleUserReceivers.contains(cn)) { 15614 singleUserReceivers.add(cn); 15615 receivers.add(ri); 15616 } 15617 } else { 15618 receivers.add(ri); 15619 } 15620 } 15621 } 15622 } 15623 } catch (RemoteException ex) { 15624 // pm is in same process, this will never happen. 15625 } 15626 return receivers; 15627 } 15628 15629 private final int broadcastIntentLocked(ProcessRecord callerApp, 15630 String callerPackage, Intent intent, String resolvedType, 15631 IIntentReceiver resultTo, int resultCode, String resultData, 15632 Bundle map, String requiredPermission, int appOp, 15633 boolean ordered, boolean sticky, int callingPid, int callingUid, 15634 int userId) { 15635 intent = new Intent(intent); 15636 15637 // By default broadcasts do not go to stopped apps. 15638 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15639 15640 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15641 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15642 + " ordered=" + ordered + " userid=" + userId); 15643 if ((resultTo != null) && !ordered) { 15644 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15645 } 15646 15647 userId = handleIncomingUser(callingPid, callingUid, userId, 15648 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15649 15650 // Make sure that the user who is receiving this broadcast is running. 15651 // If not, we will just skip it. 15652 15653 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15654 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15655 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15656 Slog.w(TAG, "Skipping broadcast of " + intent 15657 + ": user " + userId + " is stopped"); 15658 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15659 } 15660 } 15661 15662 /* 15663 * Prevent non-system code (defined here to be non-persistent 15664 * processes) from sending protected broadcasts. 15665 */ 15666 int callingAppId = UserHandle.getAppId(callingUid); 15667 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15668 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15669 || callingAppId == Process.NFC_UID || callingUid == 0) { 15670 // Always okay. 15671 } else if (callerApp == null || !callerApp.persistent) { 15672 try { 15673 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15674 intent.getAction())) { 15675 String msg = "Permission Denial: not allowed to send broadcast " 15676 + intent.getAction() + " from pid=" 15677 + callingPid + ", uid=" + callingUid; 15678 Slog.w(TAG, msg); 15679 throw new SecurityException(msg); 15680 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15681 // Special case for compatibility: we don't want apps to send this, 15682 // but historically it has not been protected and apps may be using it 15683 // to poke their own app widget. So, instead of making it protected, 15684 // just limit it to the caller. 15685 if (callerApp == null) { 15686 String msg = "Permission Denial: not allowed to send broadcast " 15687 + intent.getAction() + " from unknown caller."; 15688 Slog.w(TAG, msg); 15689 throw new SecurityException(msg); 15690 } else if (intent.getComponent() != null) { 15691 // They are good enough to send to an explicit component... verify 15692 // it is being sent to the calling app. 15693 if (!intent.getComponent().getPackageName().equals( 15694 callerApp.info.packageName)) { 15695 String msg = "Permission Denial: not allowed to send broadcast " 15696 + intent.getAction() + " to " 15697 + intent.getComponent().getPackageName() + " from " 15698 + callerApp.info.packageName; 15699 Slog.w(TAG, msg); 15700 throw new SecurityException(msg); 15701 } 15702 } else { 15703 // Limit broadcast to their own package. 15704 intent.setPackage(callerApp.info.packageName); 15705 } 15706 } 15707 } catch (RemoteException e) { 15708 Slog.w(TAG, "Remote exception", e); 15709 return ActivityManager.BROADCAST_SUCCESS; 15710 } 15711 } 15712 15713 final String action = intent.getAction(); 15714 if (action != null) { 15715 switch (action) { 15716 case Intent.ACTION_UID_REMOVED: 15717 case Intent.ACTION_PACKAGE_REMOVED: 15718 case Intent.ACTION_PACKAGE_CHANGED: 15719 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15720 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15721 // Handle special intents: if this broadcast is from the package 15722 // manager about a package being removed, we need to remove all of 15723 // its activities from the history stack. 15724 if (checkComponentPermission( 15725 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15726 callingPid, callingUid, -1, true) 15727 != PackageManager.PERMISSION_GRANTED) { 15728 String msg = "Permission Denial: " + intent.getAction() 15729 + " broadcast from " + callerPackage + " (pid=" + callingPid 15730 + ", uid=" + callingUid + ")" 15731 + " requires " 15732 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15733 Slog.w(TAG, msg); 15734 throw new SecurityException(msg); 15735 } 15736 switch (action) { 15737 case Intent.ACTION_UID_REMOVED: 15738 final Bundle intentExtras = intent.getExtras(); 15739 final int uid = intentExtras != null 15740 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15741 if (uid >= 0) { 15742 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15743 synchronized (bs) { 15744 bs.removeUidStatsLocked(uid); 15745 } 15746 mAppOpsService.uidRemoved(uid); 15747 } 15748 break; 15749 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15750 // If resources are unavailable just force stop all those packages 15751 // and flush the attribute cache as well. 15752 String list[] = 15753 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15754 if (list != null && list.length > 0) { 15755 for (int i = 0; i < list.length; i++) { 15756 forceStopPackageLocked(list[i], -1, false, true, true, 15757 false, false, userId, "storage unmount"); 15758 } 15759 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15760 sendPackageBroadcastLocked( 15761 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15762 userId); 15763 } 15764 break; 15765 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15766 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15767 break; 15768 case Intent.ACTION_PACKAGE_REMOVED: 15769 case Intent.ACTION_PACKAGE_CHANGED: 15770 Uri data = intent.getData(); 15771 String ssp; 15772 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15773 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15774 boolean fullUninstall = removed && 15775 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15776 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15777 forceStopPackageLocked(ssp, UserHandle.getAppId( 15778 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15779 false, true, true, false, fullUninstall, userId, 15780 removed ? "pkg removed" : "pkg changed"); 15781 } 15782 if (removed) { 15783 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15784 new String[] {ssp}, userId); 15785 if (fullUninstall) { 15786 mAppOpsService.packageRemoved( 15787 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15788 15789 // Remove all permissions granted from/to this package 15790 removeUriPermissionsForPackageLocked(ssp, userId, true); 15791 15792 removeTasksByPackageNameLocked(ssp, userId); 15793 } 15794 } else { 15795 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15796 } 15797 } 15798 break; 15799 } 15800 break; 15801 case Intent.ACTION_PACKAGE_ADDED: 15802 // Special case for adding a package: by default turn on compatibility mode. 15803 Uri data = intent.getData(); 15804 String ssp; 15805 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15806 final boolean replacing = 15807 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15808 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15809 15810 if (replacing) { 15811 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15812 } 15813 } 15814 break; 15815 case Intent.ACTION_TIMEZONE_CHANGED: 15816 // If this is the time zone changed action, queue up a message that will reset 15817 // the timezone of all currently running processes. This message will get 15818 // queued up before the broadcast happens. 15819 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15820 break; 15821 case Intent.ACTION_TIME_CHANGED: 15822 // If the user set the time, let all running processes know. 15823 final int is24Hour = 15824 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15825 : 0; 15826 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15827 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15828 synchronized (stats) { 15829 stats.noteCurrentTimeChangedLocked(); 15830 } 15831 break; 15832 case Intent.ACTION_CLEAR_DNS_CACHE: 15833 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15834 break; 15835 case Proxy.PROXY_CHANGE_ACTION: 15836 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15837 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15838 break; 15839 } 15840 } 15841 15842 // Add to the sticky list if requested. 15843 if (sticky) { 15844 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15845 callingPid, callingUid) 15846 != PackageManager.PERMISSION_GRANTED) { 15847 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15848 + callingPid + ", uid=" + callingUid 15849 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15850 Slog.w(TAG, msg); 15851 throw new SecurityException(msg); 15852 } 15853 if (requiredPermission != null) { 15854 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15855 + " and enforce permission " + requiredPermission); 15856 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15857 } 15858 if (intent.getComponent() != null) { 15859 throw new SecurityException( 15860 "Sticky broadcasts can't target a specific component"); 15861 } 15862 // We use userId directly here, since the "all" target is maintained 15863 // as a separate set of sticky broadcasts. 15864 if (userId != UserHandle.USER_ALL) { 15865 // But first, if this is not a broadcast to all users, then 15866 // make sure it doesn't conflict with an existing broadcast to 15867 // all users. 15868 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15869 UserHandle.USER_ALL); 15870 if (stickies != null) { 15871 ArrayList<Intent> list = stickies.get(intent.getAction()); 15872 if (list != null) { 15873 int N = list.size(); 15874 int i; 15875 for (i=0; i<N; i++) { 15876 if (intent.filterEquals(list.get(i))) { 15877 throw new IllegalArgumentException( 15878 "Sticky broadcast " + intent + " for user " 15879 + userId + " conflicts with existing global broadcast"); 15880 } 15881 } 15882 } 15883 } 15884 } 15885 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15886 if (stickies == null) { 15887 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15888 mStickyBroadcasts.put(userId, stickies); 15889 } 15890 ArrayList<Intent> list = stickies.get(intent.getAction()); 15891 if (list == null) { 15892 list = new ArrayList<Intent>(); 15893 stickies.put(intent.getAction(), list); 15894 } 15895 int N = list.size(); 15896 int i; 15897 for (i=0; i<N; i++) { 15898 if (intent.filterEquals(list.get(i))) { 15899 // This sticky already exists, replace it. 15900 list.set(i, new Intent(intent)); 15901 break; 15902 } 15903 } 15904 if (i >= N) { 15905 list.add(new Intent(intent)); 15906 } 15907 } 15908 15909 int[] users; 15910 if (userId == UserHandle.USER_ALL) { 15911 // Caller wants broadcast to go to all started users. 15912 users = mStartedUserArray; 15913 } else { 15914 // Caller wants broadcast to go to one specific user. 15915 users = new int[] {userId}; 15916 } 15917 15918 // Figure out who all will receive this broadcast. 15919 List receivers = null; 15920 List<BroadcastFilter> registeredReceivers = null; 15921 // Need to resolve the intent to interested receivers... 15922 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15923 == 0) { 15924 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15925 } 15926 if (intent.getComponent() == null) { 15927 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15928 // Query one target user at a time, excluding shell-restricted users 15929 UserManagerService ums = getUserManagerLocked(); 15930 for (int i = 0; i < users.length; i++) { 15931 if (ums.hasUserRestriction( 15932 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15933 continue; 15934 } 15935 List<BroadcastFilter> registeredReceiversForUser = 15936 mReceiverResolver.queryIntent(intent, 15937 resolvedType, false, users[i]); 15938 if (registeredReceivers == null) { 15939 registeredReceivers = registeredReceiversForUser; 15940 } else if (registeredReceiversForUser != null) { 15941 registeredReceivers.addAll(registeredReceiversForUser); 15942 } 15943 } 15944 } else { 15945 registeredReceivers = mReceiverResolver.queryIntent(intent, 15946 resolvedType, false, userId); 15947 } 15948 } 15949 15950 final boolean replacePending = 15951 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15952 15953 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15954 + " replacePending=" + replacePending); 15955 15956 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15957 if (!ordered && NR > 0) { 15958 // If we are not serializing this broadcast, then send the 15959 // registered receivers separately so they don't wait for the 15960 // components to be launched. 15961 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15962 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15963 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15964 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15965 ordered, sticky, false, userId); 15966 if (DEBUG_BROADCAST) Slog.v( 15967 TAG, "Enqueueing parallel broadcast " + r); 15968 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15969 if (!replaced) { 15970 queue.enqueueParallelBroadcastLocked(r); 15971 queue.scheduleBroadcastsLocked(); 15972 } 15973 registeredReceivers = null; 15974 NR = 0; 15975 } 15976 15977 // Merge into one list. 15978 int ir = 0; 15979 if (receivers != null) { 15980 // A special case for PACKAGE_ADDED: do not allow the package 15981 // being added to see this broadcast. This prevents them from 15982 // using this as a back door to get run as soon as they are 15983 // installed. Maybe in the future we want to have a special install 15984 // broadcast or such for apps, but we'd like to deliberately make 15985 // this decision. 15986 String skipPackages[] = null; 15987 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15988 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15989 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15990 Uri data = intent.getData(); 15991 if (data != null) { 15992 String pkgName = data.getSchemeSpecificPart(); 15993 if (pkgName != null) { 15994 skipPackages = new String[] { pkgName }; 15995 } 15996 } 15997 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15998 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15999 } 16000 if (skipPackages != null && (skipPackages.length > 0)) { 16001 for (String skipPackage : skipPackages) { 16002 if (skipPackage != null) { 16003 int NT = receivers.size(); 16004 for (int it=0; it<NT; it++) { 16005 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16006 if (curt.activityInfo.packageName.equals(skipPackage)) { 16007 receivers.remove(it); 16008 it--; 16009 NT--; 16010 } 16011 } 16012 } 16013 } 16014 } 16015 16016 int NT = receivers != null ? receivers.size() : 0; 16017 int it = 0; 16018 ResolveInfo curt = null; 16019 BroadcastFilter curr = null; 16020 while (it < NT && ir < NR) { 16021 if (curt == null) { 16022 curt = (ResolveInfo)receivers.get(it); 16023 } 16024 if (curr == null) { 16025 curr = registeredReceivers.get(ir); 16026 } 16027 if (curr.getPriority() >= curt.priority) { 16028 // Insert this broadcast record into the final list. 16029 receivers.add(it, curr); 16030 ir++; 16031 curr = null; 16032 it++; 16033 NT++; 16034 } else { 16035 // Skip to the next ResolveInfo in the final list. 16036 it++; 16037 curt = null; 16038 } 16039 } 16040 } 16041 while (ir < NR) { 16042 if (receivers == null) { 16043 receivers = new ArrayList(); 16044 } 16045 receivers.add(registeredReceivers.get(ir)); 16046 ir++; 16047 } 16048 16049 if ((receivers != null && receivers.size() > 0) 16050 || resultTo != null) { 16051 BroadcastQueue queue = broadcastQueueForIntent(intent); 16052 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16053 callerPackage, callingPid, callingUid, resolvedType, 16054 requiredPermission, appOp, receivers, resultTo, resultCode, 16055 resultData, map, ordered, sticky, false, userId); 16056 if (DEBUG_BROADCAST) Slog.v( 16057 TAG, "Enqueueing ordered broadcast " + r 16058 + ": prev had " + queue.mOrderedBroadcasts.size()); 16059 if (DEBUG_BROADCAST) { 16060 int seq = r.intent.getIntExtra("seq", -1); 16061 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16062 } 16063 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16064 if (!replaced) { 16065 queue.enqueueOrderedBroadcastLocked(r); 16066 queue.scheduleBroadcastsLocked(); 16067 } 16068 } 16069 16070 return ActivityManager.BROADCAST_SUCCESS; 16071 } 16072 16073 final Intent verifyBroadcastLocked(Intent intent) { 16074 // Refuse possible leaked file descriptors 16075 if (intent != null && intent.hasFileDescriptors() == true) { 16076 throw new IllegalArgumentException("File descriptors passed in Intent"); 16077 } 16078 16079 int flags = intent.getFlags(); 16080 16081 if (!mProcessesReady) { 16082 // if the caller really truly claims to know what they're doing, go 16083 // ahead and allow the broadcast without launching any receivers 16084 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16085 intent = new Intent(intent); 16086 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16087 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16088 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16089 + " before boot completion"); 16090 throw new IllegalStateException("Cannot broadcast before boot completed"); 16091 } 16092 } 16093 16094 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16095 throw new IllegalArgumentException( 16096 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16097 } 16098 16099 return intent; 16100 } 16101 16102 public final int broadcastIntent(IApplicationThread caller, 16103 Intent intent, String resolvedType, IIntentReceiver resultTo, 16104 int resultCode, String resultData, Bundle map, 16105 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16106 enforceNotIsolatedCaller("broadcastIntent"); 16107 synchronized(this) { 16108 intent = verifyBroadcastLocked(intent); 16109 16110 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16111 final int callingPid = Binder.getCallingPid(); 16112 final int callingUid = Binder.getCallingUid(); 16113 final long origId = Binder.clearCallingIdentity(); 16114 int res = broadcastIntentLocked(callerApp, 16115 callerApp != null ? callerApp.info.packageName : null, 16116 intent, resolvedType, resultTo, 16117 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16118 callingPid, callingUid, userId); 16119 Binder.restoreCallingIdentity(origId); 16120 return res; 16121 } 16122 } 16123 16124 int broadcastIntentInPackage(String packageName, int uid, 16125 Intent intent, String resolvedType, IIntentReceiver resultTo, 16126 int resultCode, String resultData, Bundle map, 16127 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16128 synchronized(this) { 16129 intent = verifyBroadcastLocked(intent); 16130 16131 final long origId = Binder.clearCallingIdentity(); 16132 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16133 resultTo, resultCode, resultData, map, requiredPermission, 16134 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16135 Binder.restoreCallingIdentity(origId); 16136 return res; 16137 } 16138 } 16139 16140 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16141 // Refuse possible leaked file descriptors 16142 if (intent != null && intent.hasFileDescriptors() == true) { 16143 throw new IllegalArgumentException("File descriptors passed in Intent"); 16144 } 16145 16146 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16147 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16148 16149 synchronized(this) { 16150 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16151 != PackageManager.PERMISSION_GRANTED) { 16152 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16153 + Binder.getCallingPid() 16154 + ", uid=" + Binder.getCallingUid() 16155 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16156 Slog.w(TAG, msg); 16157 throw new SecurityException(msg); 16158 } 16159 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16160 if (stickies != null) { 16161 ArrayList<Intent> list = stickies.get(intent.getAction()); 16162 if (list != null) { 16163 int N = list.size(); 16164 int i; 16165 for (i=0; i<N; i++) { 16166 if (intent.filterEquals(list.get(i))) { 16167 list.remove(i); 16168 break; 16169 } 16170 } 16171 if (list.size() <= 0) { 16172 stickies.remove(intent.getAction()); 16173 } 16174 } 16175 if (stickies.size() <= 0) { 16176 mStickyBroadcasts.remove(userId); 16177 } 16178 } 16179 } 16180 } 16181 16182 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16183 String resultData, Bundle resultExtras, boolean resultAbort) { 16184 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16185 if (r == null) { 16186 Slog.w(TAG, "finishReceiver called but not found on queue"); 16187 return false; 16188 } 16189 16190 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16191 } 16192 16193 void backgroundServicesFinishedLocked(int userId) { 16194 for (BroadcastQueue queue : mBroadcastQueues) { 16195 queue.backgroundServicesFinishedLocked(userId); 16196 } 16197 } 16198 16199 public void finishReceiver(IBinder who, int resultCode, String resultData, 16200 Bundle resultExtras, boolean resultAbort) { 16201 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16202 16203 // Refuse possible leaked file descriptors 16204 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16205 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16206 } 16207 16208 final long origId = Binder.clearCallingIdentity(); 16209 try { 16210 boolean doNext = false; 16211 BroadcastRecord r; 16212 16213 synchronized(this) { 16214 r = broadcastRecordForReceiverLocked(who); 16215 if (r != null) { 16216 doNext = r.queue.finishReceiverLocked(r, resultCode, 16217 resultData, resultExtras, resultAbort, true); 16218 } 16219 } 16220 16221 if (doNext) { 16222 r.queue.processNextBroadcast(false); 16223 } 16224 trimApplications(); 16225 } finally { 16226 Binder.restoreCallingIdentity(origId); 16227 } 16228 } 16229 16230 // ========================================================= 16231 // INSTRUMENTATION 16232 // ========================================================= 16233 16234 public boolean startInstrumentation(ComponentName className, 16235 String profileFile, int flags, Bundle arguments, 16236 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16237 int userId, String abiOverride) { 16238 enforceNotIsolatedCaller("startInstrumentation"); 16239 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16240 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16241 // Refuse possible leaked file descriptors 16242 if (arguments != null && arguments.hasFileDescriptors()) { 16243 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16244 } 16245 16246 synchronized(this) { 16247 InstrumentationInfo ii = null; 16248 ApplicationInfo ai = null; 16249 try { 16250 ii = mContext.getPackageManager().getInstrumentationInfo( 16251 className, STOCK_PM_FLAGS); 16252 ai = AppGlobals.getPackageManager().getApplicationInfo( 16253 ii.targetPackage, STOCK_PM_FLAGS, userId); 16254 } catch (PackageManager.NameNotFoundException e) { 16255 } catch (RemoteException e) { 16256 } 16257 if (ii == null) { 16258 reportStartInstrumentationFailure(watcher, className, 16259 "Unable to find instrumentation info for: " + className); 16260 return false; 16261 } 16262 if (ai == null) { 16263 reportStartInstrumentationFailure(watcher, className, 16264 "Unable to find instrumentation target package: " + ii.targetPackage); 16265 return false; 16266 } 16267 16268 int match = mContext.getPackageManager().checkSignatures( 16269 ii.targetPackage, ii.packageName); 16270 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16271 String msg = "Permission Denial: starting instrumentation " 16272 + className + " from pid=" 16273 + Binder.getCallingPid() 16274 + ", uid=" + Binder.getCallingPid() 16275 + " not allowed because package " + ii.packageName 16276 + " does not have a signature matching the target " 16277 + ii.targetPackage; 16278 reportStartInstrumentationFailure(watcher, className, msg); 16279 throw new SecurityException(msg); 16280 } 16281 16282 final long origId = Binder.clearCallingIdentity(); 16283 // Instrumentation can kill and relaunch even persistent processes 16284 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16285 "start instr"); 16286 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16287 app.instrumentationClass = className; 16288 app.instrumentationInfo = ai; 16289 app.instrumentationProfileFile = profileFile; 16290 app.instrumentationArguments = arguments; 16291 app.instrumentationWatcher = watcher; 16292 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16293 app.instrumentationResultClass = className; 16294 Binder.restoreCallingIdentity(origId); 16295 } 16296 16297 return true; 16298 } 16299 16300 /** 16301 * Report errors that occur while attempting to start Instrumentation. Always writes the 16302 * error to the logs, but if somebody is watching, send the report there too. This enables 16303 * the "am" command to report errors with more information. 16304 * 16305 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16306 * @param cn The component name of the instrumentation. 16307 * @param report The error report. 16308 */ 16309 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16310 ComponentName cn, String report) { 16311 Slog.w(TAG, report); 16312 try { 16313 if (watcher != null) { 16314 Bundle results = new Bundle(); 16315 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16316 results.putString("Error", report); 16317 watcher.instrumentationStatus(cn, -1, results); 16318 } 16319 } catch (RemoteException e) { 16320 Slog.w(TAG, e); 16321 } 16322 } 16323 16324 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16325 if (app.instrumentationWatcher != null) { 16326 try { 16327 // NOTE: IInstrumentationWatcher *must* be oneway here 16328 app.instrumentationWatcher.instrumentationFinished( 16329 app.instrumentationClass, 16330 resultCode, 16331 results); 16332 } catch (RemoteException e) { 16333 } 16334 } 16335 if (app.instrumentationUiAutomationConnection != null) { 16336 try { 16337 app.instrumentationUiAutomationConnection.shutdown(); 16338 } catch (RemoteException re) { 16339 /* ignore */ 16340 } 16341 // Only a UiAutomation can set this flag and now that 16342 // it is finished we make sure it is reset to its default. 16343 mUserIsMonkey = false; 16344 } 16345 app.instrumentationWatcher = null; 16346 app.instrumentationUiAutomationConnection = null; 16347 app.instrumentationClass = null; 16348 app.instrumentationInfo = null; 16349 app.instrumentationProfileFile = null; 16350 app.instrumentationArguments = null; 16351 16352 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16353 "finished inst"); 16354 } 16355 16356 public void finishInstrumentation(IApplicationThread target, 16357 int resultCode, Bundle results) { 16358 int userId = UserHandle.getCallingUserId(); 16359 // Refuse possible leaked file descriptors 16360 if (results != null && results.hasFileDescriptors()) { 16361 throw new IllegalArgumentException("File descriptors passed in Intent"); 16362 } 16363 16364 synchronized(this) { 16365 ProcessRecord app = getRecordForAppLocked(target); 16366 if (app == null) { 16367 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16368 return; 16369 } 16370 final long origId = Binder.clearCallingIdentity(); 16371 finishInstrumentationLocked(app, resultCode, results); 16372 Binder.restoreCallingIdentity(origId); 16373 } 16374 } 16375 16376 // ========================================================= 16377 // CONFIGURATION 16378 // ========================================================= 16379 16380 public ConfigurationInfo getDeviceConfigurationInfo() { 16381 ConfigurationInfo config = new ConfigurationInfo(); 16382 synchronized (this) { 16383 config.reqTouchScreen = mConfiguration.touchscreen; 16384 config.reqKeyboardType = mConfiguration.keyboard; 16385 config.reqNavigation = mConfiguration.navigation; 16386 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16387 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16388 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16389 } 16390 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16391 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16392 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16393 } 16394 config.reqGlEsVersion = GL_ES_VERSION; 16395 } 16396 return config; 16397 } 16398 16399 ActivityStack getFocusedStack() { 16400 return mStackSupervisor.getFocusedStack(); 16401 } 16402 16403 public Configuration getConfiguration() { 16404 Configuration ci; 16405 synchronized(this) { 16406 ci = new Configuration(mConfiguration); 16407 } 16408 return ci; 16409 } 16410 16411 public void updatePersistentConfiguration(Configuration values) { 16412 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16413 "updateConfiguration()"); 16414 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16415 "updateConfiguration()"); 16416 if (values == null) { 16417 throw new NullPointerException("Configuration must not be null"); 16418 } 16419 16420 synchronized(this) { 16421 final long origId = Binder.clearCallingIdentity(); 16422 updateConfigurationLocked(values, null, true, false); 16423 Binder.restoreCallingIdentity(origId); 16424 } 16425 } 16426 16427 public void updateConfiguration(Configuration values) { 16428 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16429 "updateConfiguration()"); 16430 16431 synchronized(this) { 16432 if (values == null && mWindowManager != null) { 16433 // sentinel: fetch the current configuration from the window manager 16434 values = mWindowManager.computeNewConfiguration(); 16435 } 16436 16437 if (mWindowManager != null) { 16438 mProcessList.applyDisplaySize(mWindowManager); 16439 } 16440 16441 final long origId = Binder.clearCallingIdentity(); 16442 if (values != null) { 16443 Settings.System.clearConfiguration(values); 16444 } 16445 updateConfigurationLocked(values, null, false, false); 16446 Binder.restoreCallingIdentity(origId); 16447 } 16448 } 16449 16450 /** 16451 * Do either or both things: (1) change the current configuration, and (2) 16452 * make sure the given activity is running with the (now) current 16453 * configuration. Returns true if the activity has been left running, or 16454 * false if <var>starting</var> is being destroyed to match the new 16455 * configuration. 16456 * @param persistent TODO 16457 */ 16458 boolean updateConfigurationLocked(Configuration values, 16459 ActivityRecord starting, boolean persistent, boolean initLocale) { 16460 int changes = 0; 16461 16462 if (values != null) { 16463 Configuration newConfig = new Configuration(mConfiguration); 16464 changes = newConfig.updateFrom(values); 16465 if (changes != 0) { 16466 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16467 Slog.i(TAG, "Updating configuration to: " + values); 16468 } 16469 16470 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16471 16472 if (values.locale != null && !initLocale) { 16473 saveLocaleLocked(values.locale, 16474 !values.locale.equals(mConfiguration.locale), 16475 values.userSetLocale); 16476 } 16477 16478 mConfigurationSeq++; 16479 if (mConfigurationSeq <= 0) { 16480 mConfigurationSeq = 1; 16481 } 16482 newConfig.seq = mConfigurationSeq; 16483 mConfiguration = newConfig; 16484 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16485 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16486 //mUsageStatsService.noteStartConfig(newConfig); 16487 16488 final Configuration configCopy = new Configuration(mConfiguration); 16489 16490 // TODO: If our config changes, should we auto dismiss any currently 16491 // showing dialogs? 16492 mShowDialogs = shouldShowDialogs(newConfig); 16493 16494 AttributeCache ac = AttributeCache.instance(); 16495 if (ac != null) { 16496 ac.updateConfiguration(configCopy); 16497 } 16498 16499 // Make sure all resources in our process are updated 16500 // right now, so that anyone who is going to retrieve 16501 // resource values after we return will be sure to get 16502 // the new ones. This is especially important during 16503 // boot, where the first config change needs to guarantee 16504 // all resources have that config before following boot 16505 // code is executed. 16506 mSystemThread.applyConfigurationToResources(configCopy); 16507 16508 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16509 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16510 msg.obj = new Configuration(configCopy); 16511 mHandler.sendMessage(msg); 16512 } 16513 16514 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16515 ProcessRecord app = mLruProcesses.get(i); 16516 try { 16517 if (app.thread != null) { 16518 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16519 + app.processName + " new config " + mConfiguration); 16520 app.thread.scheduleConfigurationChanged(configCopy); 16521 } 16522 } catch (Exception e) { 16523 } 16524 } 16525 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16526 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16527 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16528 | Intent.FLAG_RECEIVER_FOREGROUND); 16529 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16530 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16531 Process.SYSTEM_UID, UserHandle.USER_ALL); 16532 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16533 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16534 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16535 broadcastIntentLocked(null, null, intent, 16536 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16537 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16538 } 16539 } 16540 } 16541 16542 boolean kept = true; 16543 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16544 // mainStack is null during startup. 16545 if (mainStack != null) { 16546 if (changes != 0 && starting == null) { 16547 // If the configuration changed, and the caller is not already 16548 // in the process of starting an activity, then find the top 16549 // activity to check if its configuration needs to change. 16550 starting = mainStack.topRunningActivityLocked(null); 16551 } 16552 16553 if (starting != null) { 16554 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16555 // And we need to make sure at this point that all other activities 16556 // are made visible with the correct configuration. 16557 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16558 } 16559 } 16560 16561 if (values != null && mWindowManager != null) { 16562 mWindowManager.setNewConfiguration(mConfiguration); 16563 } 16564 16565 return kept; 16566 } 16567 16568 /** 16569 * Decide based on the configuration whether we should shouw the ANR, 16570 * crash, etc dialogs. The idea is that if there is no affordnace to 16571 * press the on-screen buttons, we shouldn't show the dialog. 16572 * 16573 * A thought: SystemUI might also want to get told about this, the Power 16574 * dialog / global actions also might want different behaviors. 16575 */ 16576 private static final boolean shouldShowDialogs(Configuration config) { 16577 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16578 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16579 } 16580 16581 /** 16582 * Save the locale. You must be inside a synchronized (this) block. 16583 */ 16584 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16585 if(isDiff) { 16586 SystemProperties.set("user.language", l.getLanguage()); 16587 SystemProperties.set("user.region", l.getCountry()); 16588 } 16589 16590 if(isPersist) { 16591 SystemProperties.set("persist.sys.language", l.getLanguage()); 16592 SystemProperties.set("persist.sys.country", l.getCountry()); 16593 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16594 16595 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16596 } 16597 } 16598 16599 @Override 16600 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16601 synchronized (this) { 16602 ActivityRecord srec = ActivityRecord.forToken(token); 16603 if (srec.task != null && srec.task.stack != null) { 16604 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16605 } 16606 } 16607 return false; 16608 } 16609 16610 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16611 Intent resultData) { 16612 16613 synchronized (this) { 16614 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16615 if (stack != null) { 16616 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16617 } 16618 return false; 16619 } 16620 } 16621 16622 public int getLaunchedFromUid(IBinder activityToken) { 16623 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16624 if (srec == null) { 16625 return -1; 16626 } 16627 return srec.launchedFromUid; 16628 } 16629 16630 public String getLaunchedFromPackage(IBinder activityToken) { 16631 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16632 if (srec == null) { 16633 return null; 16634 } 16635 return srec.launchedFromPackage; 16636 } 16637 16638 // ========================================================= 16639 // LIFETIME MANAGEMENT 16640 // ========================================================= 16641 16642 // Returns which broadcast queue the app is the current [or imminent] receiver 16643 // on, or 'null' if the app is not an active broadcast recipient. 16644 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16645 BroadcastRecord r = app.curReceiver; 16646 if (r != null) { 16647 return r.queue; 16648 } 16649 16650 // It's not the current receiver, but it might be starting up to become one 16651 synchronized (this) { 16652 for (BroadcastQueue queue : mBroadcastQueues) { 16653 r = queue.mPendingBroadcast; 16654 if (r != null && r.curApp == app) { 16655 // found it; report which queue it's in 16656 return queue; 16657 } 16658 } 16659 } 16660 16661 return null; 16662 } 16663 16664 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16665 boolean doingAll, long now) { 16666 if (mAdjSeq == app.adjSeq) { 16667 // This adjustment has already been computed. 16668 return app.curRawAdj; 16669 } 16670 16671 if (app.thread == null) { 16672 app.adjSeq = mAdjSeq; 16673 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16674 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16675 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16676 } 16677 16678 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16679 app.adjSource = null; 16680 app.adjTarget = null; 16681 app.empty = false; 16682 app.cached = false; 16683 16684 final int activitiesSize = app.activities.size(); 16685 16686 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16687 // The max adjustment doesn't allow this app to be anything 16688 // below foreground, so it is not worth doing work for it. 16689 app.adjType = "fixed"; 16690 app.adjSeq = mAdjSeq; 16691 app.curRawAdj = app.maxAdj; 16692 app.foregroundActivities = false; 16693 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16694 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16695 // System processes can do UI, and when they do we want to have 16696 // them trim their memory after the user leaves the UI. To 16697 // facilitate this, here we need to determine whether or not it 16698 // is currently showing UI. 16699 app.systemNoUi = true; 16700 if (app == TOP_APP) { 16701 app.systemNoUi = false; 16702 } else if (activitiesSize > 0) { 16703 for (int j = 0; j < activitiesSize; j++) { 16704 final ActivityRecord r = app.activities.get(j); 16705 if (r.visible) { 16706 app.systemNoUi = false; 16707 } 16708 } 16709 } 16710 if (!app.systemNoUi) { 16711 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16712 } 16713 return (app.curAdj=app.maxAdj); 16714 } 16715 16716 app.systemNoUi = false; 16717 16718 // Determine the importance of the process, starting with most 16719 // important to least, and assign an appropriate OOM adjustment. 16720 int adj; 16721 int schedGroup; 16722 int procState; 16723 boolean foregroundActivities = false; 16724 BroadcastQueue queue; 16725 if (app == TOP_APP) { 16726 // The last app on the list is the foreground app. 16727 adj = ProcessList.FOREGROUND_APP_ADJ; 16728 schedGroup = Process.THREAD_GROUP_DEFAULT; 16729 app.adjType = "top-activity"; 16730 foregroundActivities = true; 16731 procState = ActivityManager.PROCESS_STATE_TOP; 16732 } else if (app.instrumentationClass != null) { 16733 // Don't want to kill running instrumentation. 16734 adj = ProcessList.FOREGROUND_APP_ADJ; 16735 schedGroup = Process.THREAD_GROUP_DEFAULT; 16736 app.adjType = "instrumentation"; 16737 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16738 } else if ((queue = isReceivingBroadcast(app)) != null) { 16739 // An app that is currently receiving a broadcast also 16740 // counts as being in the foreground for OOM killer purposes. 16741 // It's placed in a sched group based on the nature of the 16742 // broadcast as reflected by which queue it's active in. 16743 adj = ProcessList.FOREGROUND_APP_ADJ; 16744 schedGroup = (queue == mFgBroadcastQueue) 16745 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16746 app.adjType = "broadcast"; 16747 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16748 } else if (app.executingServices.size() > 0) { 16749 // An app that is currently executing a service callback also 16750 // counts as being in the foreground. 16751 adj = ProcessList.FOREGROUND_APP_ADJ; 16752 schedGroup = app.execServicesFg ? 16753 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16754 app.adjType = "exec-service"; 16755 procState = ActivityManager.PROCESS_STATE_SERVICE; 16756 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16757 } else { 16758 // As far as we know the process is empty. We may change our mind later. 16759 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16760 // At this point we don't actually know the adjustment. Use the cached adj 16761 // value that the caller wants us to. 16762 adj = cachedAdj; 16763 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16764 app.cached = true; 16765 app.empty = true; 16766 app.adjType = "cch-empty"; 16767 } 16768 16769 // Examine all activities if not already foreground. 16770 if (!foregroundActivities && activitiesSize > 0) { 16771 for (int j = 0; j < activitiesSize; j++) { 16772 final ActivityRecord r = app.activities.get(j); 16773 if (r.app != app) { 16774 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16775 + app + "?!?"); 16776 continue; 16777 } 16778 if (r.visible) { 16779 // App has a visible activity; only upgrade adjustment. 16780 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16781 adj = ProcessList.VISIBLE_APP_ADJ; 16782 app.adjType = "visible"; 16783 } 16784 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16785 procState = ActivityManager.PROCESS_STATE_TOP; 16786 } 16787 schedGroup = Process.THREAD_GROUP_DEFAULT; 16788 app.cached = false; 16789 app.empty = false; 16790 foregroundActivities = true; 16791 break; 16792 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16793 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16794 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16795 app.adjType = "pausing"; 16796 } 16797 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16798 procState = ActivityManager.PROCESS_STATE_TOP; 16799 } 16800 schedGroup = Process.THREAD_GROUP_DEFAULT; 16801 app.cached = false; 16802 app.empty = false; 16803 foregroundActivities = true; 16804 } else if (r.state == ActivityState.STOPPING) { 16805 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16806 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16807 app.adjType = "stopping"; 16808 } 16809 // For the process state, we will at this point consider the 16810 // process to be cached. It will be cached either as an activity 16811 // or empty depending on whether the activity is finishing. We do 16812 // this so that we can treat the process as cached for purposes of 16813 // memory trimming (determing current memory level, trim command to 16814 // send to process) since there can be an arbitrary number of stopping 16815 // processes and they should soon all go into the cached state. 16816 if (!r.finishing) { 16817 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16818 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16819 } 16820 } 16821 app.cached = false; 16822 app.empty = false; 16823 foregroundActivities = true; 16824 } else { 16825 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16826 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16827 app.adjType = "cch-act"; 16828 } 16829 } 16830 } 16831 } 16832 16833 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16834 if (app.foregroundServices) { 16835 // The user is aware of this app, so make it visible. 16836 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16837 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16838 app.cached = false; 16839 app.adjType = "fg-service"; 16840 schedGroup = Process.THREAD_GROUP_DEFAULT; 16841 } else if (app.forcingToForeground != null) { 16842 // The user is aware of this app, so make it visible. 16843 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16844 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16845 app.cached = false; 16846 app.adjType = "force-fg"; 16847 app.adjSource = app.forcingToForeground; 16848 schedGroup = Process.THREAD_GROUP_DEFAULT; 16849 } 16850 } 16851 16852 if (app == mHeavyWeightProcess) { 16853 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16854 // We don't want to kill the current heavy-weight process. 16855 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16856 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16857 app.cached = false; 16858 app.adjType = "heavy"; 16859 } 16860 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16861 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16862 } 16863 } 16864 16865 if (app == mHomeProcess) { 16866 if (adj > ProcessList.HOME_APP_ADJ) { 16867 // This process is hosting what we currently consider to be the 16868 // home app, so we don't want to let it go into the background. 16869 adj = ProcessList.HOME_APP_ADJ; 16870 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16871 app.cached = false; 16872 app.adjType = "home"; 16873 } 16874 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16875 procState = ActivityManager.PROCESS_STATE_HOME; 16876 } 16877 } 16878 16879 if (app == mPreviousProcess && app.activities.size() > 0) { 16880 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16881 // This was the previous process that showed UI to the user. 16882 // We want to try to keep it around more aggressively, to give 16883 // a good experience around switching between two apps. 16884 adj = ProcessList.PREVIOUS_APP_ADJ; 16885 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16886 app.cached = false; 16887 app.adjType = "previous"; 16888 } 16889 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16890 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16891 } 16892 } 16893 16894 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16895 + " reason=" + app.adjType); 16896 16897 // By default, we use the computed adjustment. It may be changed if 16898 // there are applications dependent on our services or providers, but 16899 // this gives us a baseline and makes sure we don't get into an 16900 // infinite recursion. 16901 app.adjSeq = mAdjSeq; 16902 app.curRawAdj = adj; 16903 app.hasStartedServices = false; 16904 16905 if (mBackupTarget != null && app == mBackupTarget.app) { 16906 // If possible we want to avoid killing apps while they're being backed up 16907 if (adj > ProcessList.BACKUP_APP_ADJ) { 16908 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16909 adj = ProcessList.BACKUP_APP_ADJ; 16910 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16911 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16912 } 16913 app.adjType = "backup"; 16914 app.cached = false; 16915 } 16916 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16917 procState = ActivityManager.PROCESS_STATE_BACKUP; 16918 } 16919 } 16920 16921 boolean mayBeTop = false; 16922 16923 for (int is = app.services.size()-1; 16924 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16925 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16926 || procState > ActivityManager.PROCESS_STATE_TOP); 16927 is--) { 16928 ServiceRecord s = app.services.valueAt(is); 16929 if (s.startRequested) { 16930 app.hasStartedServices = true; 16931 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16932 procState = ActivityManager.PROCESS_STATE_SERVICE; 16933 } 16934 if (app.hasShownUi && app != mHomeProcess) { 16935 // If this process has shown some UI, let it immediately 16936 // go to the LRU list because it may be pretty heavy with 16937 // UI stuff. We'll tag it with a label just to help 16938 // debug and understand what is going on. 16939 if (adj > ProcessList.SERVICE_ADJ) { 16940 app.adjType = "cch-started-ui-services"; 16941 } 16942 } else { 16943 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16944 // This service has seen some activity within 16945 // recent memory, so we will keep its process ahead 16946 // of the background processes. 16947 if (adj > ProcessList.SERVICE_ADJ) { 16948 adj = ProcessList.SERVICE_ADJ; 16949 app.adjType = "started-services"; 16950 app.cached = false; 16951 } 16952 } 16953 // If we have let the service slide into the background 16954 // state, still have some text describing what it is doing 16955 // even though the service no longer has an impact. 16956 if (adj > ProcessList.SERVICE_ADJ) { 16957 app.adjType = "cch-started-services"; 16958 } 16959 } 16960 } 16961 for (int conni = s.connections.size()-1; 16962 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16963 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16964 || procState > ActivityManager.PROCESS_STATE_TOP); 16965 conni--) { 16966 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16967 for (int i = 0; 16968 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16969 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16970 || procState > ActivityManager.PROCESS_STATE_TOP); 16971 i++) { 16972 // XXX should compute this based on the max of 16973 // all connected clients. 16974 ConnectionRecord cr = clist.get(i); 16975 if (cr.binding.client == app) { 16976 // Binding to ourself is not interesting. 16977 continue; 16978 } 16979 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16980 ProcessRecord client = cr.binding.client; 16981 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16982 TOP_APP, doingAll, now); 16983 int clientProcState = client.curProcState; 16984 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16985 // If the other app is cached for any reason, for purposes here 16986 // we are going to consider it empty. The specific cached state 16987 // doesn't propagate except under certain conditions. 16988 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16989 } 16990 String adjType = null; 16991 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16992 // Not doing bind OOM management, so treat 16993 // this guy more like a started service. 16994 if (app.hasShownUi && app != mHomeProcess) { 16995 // If this process has shown some UI, let it immediately 16996 // go to the LRU list because it may be pretty heavy with 16997 // UI stuff. We'll tag it with a label just to help 16998 // debug and understand what is going on. 16999 if (adj > clientAdj) { 17000 adjType = "cch-bound-ui-services"; 17001 } 17002 app.cached = false; 17003 clientAdj = adj; 17004 clientProcState = procState; 17005 } else { 17006 if (now >= (s.lastActivity 17007 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17008 // This service has not seen activity within 17009 // recent memory, so allow it to drop to the 17010 // LRU list if there is no other reason to keep 17011 // it around. We'll also tag it with a label just 17012 // to help debug and undertand what is going on. 17013 if (adj > clientAdj) { 17014 adjType = "cch-bound-services"; 17015 } 17016 clientAdj = adj; 17017 } 17018 } 17019 } 17020 if (adj > clientAdj) { 17021 // If this process has recently shown UI, and 17022 // the process that is binding to it is less 17023 // important than being visible, then we don't 17024 // care about the binding as much as we care 17025 // about letting this process get into the LRU 17026 // list to be killed and restarted if needed for 17027 // memory. 17028 if (app.hasShownUi && app != mHomeProcess 17029 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17030 adjType = "cch-bound-ui-services"; 17031 } else { 17032 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17033 |Context.BIND_IMPORTANT)) != 0) { 17034 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17035 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17036 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17037 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17038 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17039 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17040 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17041 adj = clientAdj; 17042 } else { 17043 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17044 adj = ProcessList.VISIBLE_APP_ADJ; 17045 } 17046 } 17047 if (!client.cached) { 17048 app.cached = false; 17049 } 17050 adjType = "service"; 17051 } 17052 } 17053 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17054 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17055 schedGroup = Process.THREAD_GROUP_DEFAULT; 17056 } 17057 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17058 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17059 // Special handling of clients who are in the top state. 17060 // We *may* want to consider this process to be in the 17061 // top state as well, but only if there is not another 17062 // reason for it to be running. Being on the top is a 17063 // special state, meaning you are specifically running 17064 // for the current top app. If the process is already 17065 // running in the background for some other reason, it 17066 // is more important to continue considering it to be 17067 // in the background state. 17068 mayBeTop = true; 17069 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17070 } else { 17071 // Special handling for above-top states (persistent 17072 // processes). These should not bring the current process 17073 // into the top state, since they are not on top. Instead 17074 // give them the best state after that. 17075 clientProcState = 17076 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17077 } 17078 } 17079 } else { 17080 if (clientProcState < 17081 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17082 clientProcState = 17083 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17084 } 17085 } 17086 if (procState > clientProcState) { 17087 procState = clientProcState; 17088 } 17089 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17090 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17091 app.pendingUiClean = true; 17092 } 17093 if (adjType != null) { 17094 app.adjType = adjType; 17095 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17096 .REASON_SERVICE_IN_USE; 17097 app.adjSource = cr.binding.client; 17098 app.adjSourceProcState = clientProcState; 17099 app.adjTarget = s.name; 17100 } 17101 } 17102 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17103 app.treatLikeActivity = true; 17104 } 17105 final ActivityRecord a = cr.activity; 17106 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17107 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17108 (a.visible || a.state == ActivityState.RESUMED 17109 || a.state == ActivityState.PAUSING)) { 17110 adj = ProcessList.FOREGROUND_APP_ADJ; 17111 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17112 schedGroup = Process.THREAD_GROUP_DEFAULT; 17113 } 17114 app.cached = false; 17115 app.adjType = "service"; 17116 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17117 .REASON_SERVICE_IN_USE; 17118 app.adjSource = a; 17119 app.adjSourceProcState = procState; 17120 app.adjTarget = s.name; 17121 } 17122 } 17123 } 17124 } 17125 } 17126 17127 for (int provi = app.pubProviders.size()-1; 17128 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17129 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17130 || procState > ActivityManager.PROCESS_STATE_TOP); 17131 provi--) { 17132 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17133 for (int i = cpr.connections.size()-1; 17134 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17135 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17136 || procState > ActivityManager.PROCESS_STATE_TOP); 17137 i--) { 17138 ContentProviderConnection conn = cpr.connections.get(i); 17139 ProcessRecord client = conn.client; 17140 if (client == app) { 17141 // Being our own client is not interesting. 17142 continue; 17143 } 17144 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17145 int clientProcState = client.curProcState; 17146 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17147 // If the other app is cached for any reason, for purposes here 17148 // we are going to consider it empty. 17149 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17150 } 17151 if (adj > clientAdj) { 17152 if (app.hasShownUi && app != mHomeProcess 17153 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17154 app.adjType = "cch-ui-provider"; 17155 } else { 17156 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17157 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17158 app.adjType = "provider"; 17159 } 17160 app.cached &= client.cached; 17161 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17162 .REASON_PROVIDER_IN_USE; 17163 app.adjSource = client; 17164 app.adjSourceProcState = clientProcState; 17165 app.adjTarget = cpr.name; 17166 } 17167 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17168 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17169 // Special handling of clients who are in the top state. 17170 // We *may* want to consider this process to be in the 17171 // top state as well, but only if there is not another 17172 // reason for it to be running. Being on the top is a 17173 // special state, meaning you are specifically running 17174 // for the current top app. If the process is already 17175 // running in the background for some other reason, it 17176 // is more important to continue considering it to be 17177 // in the background state. 17178 mayBeTop = true; 17179 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17180 } else { 17181 // Special handling for above-top states (persistent 17182 // processes). These should not bring the current process 17183 // into the top state, since they are not on top. Instead 17184 // give them the best state after that. 17185 clientProcState = 17186 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17187 } 17188 } 17189 if (procState > clientProcState) { 17190 procState = clientProcState; 17191 } 17192 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17193 schedGroup = Process.THREAD_GROUP_DEFAULT; 17194 } 17195 } 17196 // If the provider has external (non-framework) process 17197 // dependencies, ensure that its adjustment is at least 17198 // FOREGROUND_APP_ADJ. 17199 if (cpr.hasExternalProcessHandles()) { 17200 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17201 adj = ProcessList.FOREGROUND_APP_ADJ; 17202 schedGroup = Process.THREAD_GROUP_DEFAULT; 17203 app.cached = false; 17204 app.adjType = "provider"; 17205 app.adjTarget = cpr.name; 17206 } 17207 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17208 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17209 } 17210 } 17211 } 17212 17213 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17214 // A client of one of our services or providers is in the top state. We 17215 // *may* want to be in the top state, but not if we are already running in 17216 // the background for some other reason. For the decision here, we are going 17217 // to pick out a few specific states that we want to remain in when a client 17218 // is top (states that tend to be longer-term) and otherwise allow it to go 17219 // to the top state. 17220 switch (procState) { 17221 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17222 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17223 case ActivityManager.PROCESS_STATE_SERVICE: 17224 // These all are longer-term states, so pull them up to the top 17225 // of the background states, but not all the way to the top state. 17226 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17227 break; 17228 default: 17229 // Otherwise, top is a better choice, so take it. 17230 procState = ActivityManager.PROCESS_STATE_TOP; 17231 break; 17232 } 17233 } 17234 17235 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17236 if (app.hasClientActivities) { 17237 // This is a cached process, but with client activities. Mark it so. 17238 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17239 app.adjType = "cch-client-act"; 17240 } else if (app.treatLikeActivity) { 17241 // This is a cached process, but somebody wants us to treat it like it has 17242 // an activity, okay! 17243 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17244 app.adjType = "cch-as-act"; 17245 } 17246 } 17247 17248 if (adj == ProcessList.SERVICE_ADJ) { 17249 if (doingAll) { 17250 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17251 mNewNumServiceProcs++; 17252 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17253 if (!app.serviceb) { 17254 // This service isn't far enough down on the LRU list to 17255 // normally be a B service, but if we are low on RAM and it 17256 // is large we want to force it down since we would prefer to 17257 // keep launcher over it. 17258 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17259 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17260 app.serviceHighRam = true; 17261 app.serviceb = true; 17262 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17263 } else { 17264 mNewNumAServiceProcs++; 17265 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17266 } 17267 } else { 17268 app.serviceHighRam = false; 17269 } 17270 } 17271 if (app.serviceb) { 17272 adj = ProcessList.SERVICE_B_ADJ; 17273 } 17274 } 17275 17276 app.curRawAdj = adj; 17277 17278 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17279 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17280 if (adj > app.maxAdj) { 17281 adj = app.maxAdj; 17282 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17283 schedGroup = Process.THREAD_GROUP_DEFAULT; 17284 } 17285 } 17286 17287 // Do final modification to adj. Everything we do between here and applying 17288 // the final setAdj must be done in this function, because we will also use 17289 // it when computing the final cached adj later. Note that we don't need to 17290 // worry about this for max adj above, since max adj will always be used to 17291 // keep it out of the cached vaues. 17292 app.curAdj = app.modifyRawOomAdj(adj); 17293 app.curSchedGroup = schedGroup; 17294 app.curProcState = procState; 17295 app.foregroundActivities = foregroundActivities; 17296 17297 return app.curRawAdj; 17298 } 17299 17300 /** 17301 * Schedule PSS collection of a process. 17302 */ 17303 void requestPssLocked(ProcessRecord proc, int procState) { 17304 if (mPendingPssProcesses.contains(proc)) { 17305 return; 17306 } 17307 if (mPendingPssProcesses.size() == 0) { 17308 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17309 } 17310 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17311 proc.pssProcState = procState; 17312 mPendingPssProcesses.add(proc); 17313 } 17314 17315 /** 17316 * Schedule PSS collection of all processes. 17317 */ 17318 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17319 if (!always) { 17320 if (now < (mLastFullPssTime + 17321 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17322 return; 17323 } 17324 } 17325 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17326 mLastFullPssTime = now; 17327 mFullPssPending = true; 17328 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17329 mPendingPssProcesses.clear(); 17330 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17331 ProcessRecord app = mLruProcesses.get(i); 17332 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17333 app.pssProcState = app.setProcState; 17334 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17335 isSleeping(), now); 17336 mPendingPssProcesses.add(app); 17337 } 17338 } 17339 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17340 } 17341 17342 /** 17343 * Ask a given process to GC right now. 17344 */ 17345 final void performAppGcLocked(ProcessRecord app) { 17346 try { 17347 app.lastRequestedGc = SystemClock.uptimeMillis(); 17348 if (app.thread != null) { 17349 if (app.reportLowMemory) { 17350 app.reportLowMemory = false; 17351 app.thread.scheduleLowMemory(); 17352 } else { 17353 app.thread.processInBackground(); 17354 } 17355 } 17356 } catch (Exception e) { 17357 // whatever. 17358 } 17359 } 17360 17361 /** 17362 * Returns true if things are idle enough to perform GCs. 17363 */ 17364 private final boolean canGcNowLocked() { 17365 boolean processingBroadcasts = false; 17366 for (BroadcastQueue q : mBroadcastQueues) { 17367 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17368 processingBroadcasts = true; 17369 } 17370 } 17371 return !processingBroadcasts 17372 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17373 } 17374 17375 /** 17376 * Perform GCs on all processes that are waiting for it, but only 17377 * if things are idle. 17378 */ 17379 final void performAppGcsLocked() { 17380 final int N = mProcessesToGc.size(); 17381 if (N <= 0) { 17382 return; 17383 } 17384 if (canGcNowLocked()) { 17385 while (mProcessesToGc.size() > 0) { 17386 ProcessRecord proc = mProcessesToGc.remove(0); 17387 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17388 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17389 <= SystemClock.uptimeMillis()) { 17390 // To avoid spamming the system, we will GC processes one 17391 // at a time, waiting a few seconds between each. 17392 performAppGcLocked(proc); 17393 scheduleAppGcsLocked(); 17394 return; 17395 } else { 17396 // It hasn't been long enough since we last GCed this 17397 // process... put it in the list to wait for its time. 17398 addProcessToGcListLocked(proc); 17399 break; 17400 } 17401 } 17402 } 17403 17404 scheduleAppGcsLocked(); 17405 } 17406 } 17407 17408 /** 17409 * If all looks good, perform GCs on all processes waiting for them. 17410 */ 17411 final void performAppGcsIfAppropriateLocked() { 17412 if (canGcNowLocked()) { 17413 performAppGcsLocked(); 17414 return; 17415 } 17416 // Still not idle, wait some more. 17417 scheduleAppGcsLocked(); 17418 } 17419 17420 /** 17421 * Schedule the execution of all pending app GCs. 17422 */ 17423 final void scheduleAppGcsLocked() { 17424 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17425 17426 if (mProcessesToGc.size() > 0) { 17427 // Schedule a GC for the time to the next process. 17428 ProcessRecord proc = mProcessesToGc.get(0); 17429 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17430 17431 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17432 long now = SystemClock.uptimeMillis(); 17433 if (when < (now+GC_TIMEOUT)) { 17434 when = now + GC_TIMEOUT; 17435 } 17436 mHandler.sendMessageAtTime(msg, when); 17437 } 17438 } 17439 17440 /** 17441 * Add a process to the array of processes waiting to be GCed. Keeps the 17442 * list in sorted order by the last GC time. The process can't already be 17443 * on the list. 17444 */ 17445 final void addProcessToGcListLocked(ProcessRecord proc) { 17446 boolean added = false; 17447 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17448 if (mProcessesToGc.get(i).lastRequestedGc < 17449 proc.lastRequestedGc) { 17450 added = true; 17451 mProcessesToGc.add(i+1, proc); 17452 break; 17453 } 17454 } 17455 if (!added) { 17456 mProcessesToGc.add(0, proc); 17457 } 17458 } 17459 17460 /** 17461 * Set up to ask a process to GC itself. This will either do it 17462 * immediately, or put it on the list of processes to gc the next 17463 * time things are idle. 17464 */ 17465 final void scheduleAppGcLocked(ProcessRecord app) { 17466 long now = SystemClock.uptimeMillis(); 17467 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17468 return; 17469 } 17470 if (!mProcessesToGc.contains(app)) { 17471 addProcessToGcListLocked(app); 17472 scheduleAppGcsLocked(); 17473 } 17474 } 17475 17476 final void checkExcessivePowerUsageLocked(boolean doKills) { 17477 updateCpuStatsNow(); 17478 17479 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17480 boolean doWakeKills = doKills; 17481 boolean doCpuKills = doKills; 17482 if (mLastPowerCheckRealtime == 0) { 17483 doWakeKills = false; 17484 } 17485 if (mLastPowerCheckUptime == 0) { 17486 doCpuKills = false; 17487 } 17488 if (stats.isScreenOn()) { 17489 doWakeKills = false; 17490 } 17491 final long curRealtime = SystemClock.elapsedRealtime(); 17492 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17493 final long curUptime = SystemClock.uptimeMillis(); 17494 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17495 mLastPowerCheckRealtime = curRealtime; 17496 mLastPowerCheckUptime = curUptime; 17497 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17498 doWakeKills = false; 17499 } 17500 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17501 doCpuKills = false; 17502 } 17503 int i = mLruProcesses.size(); 17504 while (i > 0) { 17505 i--; 17506 ProcessRecord app = mLruProcesses.get(i); 17507 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17508 long wtime; 17509 synchronized (stats) { 17510 wtime = stats.getProcessWakeTime(app.info.uid, 17511 app.pid, curRealtime); 17512 } 17513 long wtimeUsed = wtime - app.lastWakeTime; 17514 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17515 if (DEBUG_POWER) { 17516 StringBuilder sb = new StringBuilder(128); 17517 sb.append("Wake for "); 17518 app.toShortString(sb); 17519 sb.append(": over "); 17520 TimeUtils.formatDuration(realtimeSince, sb); 17521 sb.append(" used "); 17522 TimeUtils.formatDuration(wtimeUsed, sb); 17523 sb.append(" ("); 17524 sb.append((wtimeUsed*100)/realtimeSince); 17525 sb.append("%)"); 17526 Slog.i(TAG, sb.toString()); 17527 sb.setLength(0); 17528 sb.append("CPU for "); 17529 app.toShortString(sb); 17530 sb.append(": over "); 17531 TimeUtils.formatDuration(uptimeSince, sb); 17532 sb.append(" used "); 17533 TimeUtils.formatDuration(cputimeUsed, sb); 17534 sb.append(" ("); 17535 sb.append((cputimeUsed*100)/uptimeSince); 17536 sb.append("%)"); 17537 Slog.i(TAG, sb.toString()); 17538 } 17539 // If a process has held a wake lock for more 17540 // than 50% of the time during this period, 17541 // that sounds bad. Kill! 17542 if (doWakeKills && realtimeSince > 0 17543 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17544 synchronized (stats) { 17545 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17546 realtimeSince, wtimeUsed); 17547 } 17548 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17549 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17550 } else if (doCpuKills && uptimeSince > 0 17551 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17552 synchronized (stats) { 17553 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17554 uptimeSince, cputimeUsed); 17555 } 17556 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17557 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17558 } else { 17559 app.lastWakeTime = wtime; 17560 app.lastCpuTime = app.curCpuTime; 17561 } 17562 } 17563 } 17564 } 17565 17566 private final boolean applyOomAdjLocked(ProcessRecord app, 17567 ProcessRecord TOP_APP, boolean doingAll, long now) { 17568 boolean success = true; 17569 17570 if (app.curRawAdj != app.setRawAdj) { 17571 app.setRawAdj = app.curRawAdj; 17572 } 17573 17574 int changes = 0; 17575 17576 if (app.curAdj != app.setAdj) { 17577 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17578 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17579 TAG, "Set " + app.pid + " " + app.processName + 17580 " adj " + app.curAdj + ": " + app.adjType); 17581 app.setAdj = app.curAdj; 17582 } 17583 17584 if (app.setSchedGroup != app.curSchedGroup) { 17585 app.setSchedGroup = app.curSchedGroup; 17586 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17587 "Setting process group of " + app.processName 17588 + " to " + app.curSchedGroup); 17589 if (app.waitingToKill != null && 17590 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17591 app.kill(app.waitingToKill, true); 17592 success = false; 17593 } else { 17594 if (true) { 17595 long oldId = Binder.clearCallingIdentity(); 17596 try { 17597 Process.setProcessGroup(app.pid, app.curSchedGroup); 17598 } catch (Exception e) { 17599 Slog.w(TAG, "Failed setting process group of " + app.pid 17600 + " to " + app.curSchedGroup); 17601 e.printStackTrace(); 17602 } finally { 17603 Binder.restoreCallingIdentity(oldId); 17604 } 17605 } else { 17606 if (app.thread != null) { 17607 try { 17608 app.thread.setSchedulingGroup(app.curSchedGroup); 17609 } catch (RemoteException e) { 17610 } 17611 } 17612 } 17613 Process.setSwappiness(app.pid, 17614 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17615 } 17616 } 17617 if (app.repForegroundActivities != app.foregroundActivities) { 17618 app.repForegroundActivities = app.foregroundActivities; 17619 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17620 } 17621 if (app.repProcState != app.curProcState) { 17622 app.repProcState = app.curProcState; 17623 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17624 if (app.thread != null) { 17625 try { 17626 if (false) { 17627 //RuntimeException h = new RuntimeException("here"); 17628 Slog.i(TAG, "Sending new process state " + app.repProcState 17629 + " to " + app /*, h*/); 17630 } 17631 app.thread.setProcessState(app.repProcState); 17632 } catch (RemoteException e) { 17633 } 17634 } 17635 } 17636 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17637 app.setProcState)) { 17638 app.lastStateTime = now; 17639 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17640 isSleeping(), now); 17641 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17642 + ProcessList.makeProcStateString(app.setProcState) + " to " 17643 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17644 + (app.nextPssTime-now) + ": " + app); 17645 } else { 17646 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17647 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17648 requestPssLocked(app, app.setProcState); 17649 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17650 isSleeping(), now); 17651 } else if (false && DEBUG_PSS) { 17652 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17653 } 17654 } 17655 if (app.setProcState != app.curProcState) { 17656 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17657 "Proc state change of " + app.processName 17658 + " to " + app.curProcState); 17659 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17660 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17661 if (setImportant && !curImportant) { 17662 // This app is no longer something we consider important enough to allow to 17663 // use arbitrary amounts of battery power. Note 17664 // its current wake lock time to later know to kill it if 17665 // it is not behaving well. 17666 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17667 synchronized (stats) { 17668 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17669 app.pid, SystemClock.elapsedRealtime()); 17670 } 17671 app.lastCpuTime = app.curCpuTime; 17672 17673 } 17674 app.setProcState = app.curProcState; 17675 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17676 app.notCachedSinceIdle = false; 17677 } 17678 if (!doingAll) { 17679 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17680 } else { 17681 app.procStateChanged = true; 17682 } 17683 } 17684 17685 if (changes != 0) { 17686 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17687 int i = mPendingProcessChanges.size()-1; 17688 ProcessChangeItem item = null; 17689 while (i >= 0) { 17690 item = mPendingProcessChanges.get(i); 17691 if (item.pid == app.pid) { 17692 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17693 break; 17694 } 17695 i--; 17696 } 17697 if (i < 0) { 17698 // No existing item in pending changes; need a new one. 17699 final int NA = mAvailProcessChanges.size(); 17700 if (NA > 0) { 17701 item = mAvailProcessChanges.remove(NA-1); 17702 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17703 } else { 17704 item = new ProcessChangeItem(); 17705 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17706 } 17707 item.changes = 0; 17708 item.pid = app.pid; 17709 item.uid = app.info.uid; 17710 if (mPendingProcessChanges.size() == 0) { 17711 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17712 "*** Enqueueing dispatch processes changed!"); 17713 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17714 } 17715 mPendingProcessChanges.add(item); 17716 } 17717 item.changes |= changes; 17718 item.processState = app.repProcState; 17719 item.foregroundActivities = app.repForegroundActivities; 17720 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17721 + Integer.toHexString(System.identityHashCode(item)) 17722 + " " + app.toShortString() + ": changes=" + item.changes 17723 + " procState=" + item.processState 17724 + " foreground=" + item.foregroundActivities 17725 + " type=" + app.adjType + " source=" + app.adjSource 17726 + " target=" + app.adjTarget); 17727 } 17728 17729 return success; 17730 } 17731 17732 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17733 if (proc.thread != null) { 17734 if (proc.baseProcessTracker != null) { 17735 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17736 } 17737 if (proc.repProcState >= 0) { 17738 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17739 proc.repProcState); 17740 } 17741 } 17742 } 17743 17744 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17745 ProcessRecord TOP_APP, boolean doingAll, long now) { 17746 if (app.thread == null) { 17747 return false; 17748 } 17749 17750 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17751 17752 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17753 } 17754 17755 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17756 boolean oomAdj) { 17757 if (isForeground != proc.foregroundServices) { 17758 proc.foregroundServices = isForeground; 17759 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17760 proc.info.uid); 17761 if (isForeground) { 17762 if (curProcs == null) { 17763 curProcs = new ArrayList<ProcessRecord>(); 17764 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17765 } 17766 if (!curProcs.contains(proc)) { 17767 curProcs.add(proc); 17768 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17769 proc.info.packageName, proc.info.uid); 17770 } 17771 } else { 17772 if (curProcs != null) { 17773 if (curProcs.remove(proc)) { 17774 mBatteryStatsService.noteEvent( 17775 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17776 proc.info.packageName, proc.info.uid); 17777 if (curProcs.size() <= 0) { 17778 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17779 } 17780 } 17781 } 17782 } 17783 if (oomAdj) { 17784 updateOomAdjLocked(); 17785 } 17786 } 17787 } 17788 17789 private final ActivityRecord resumedAppLocked() { 17790 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17791 String pkg; 17792 int uid; 17793 if (act != null) { 17794 pkg = act.packageName; 17795 uid = act.info.applicationInfo.uid; 17796 } else { 17797 pkg = null; 17798 uid = -1; 17799 } 17800 // Has the UID or resumed package name changed? 17801 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17802 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17803 if (mCurResumedPackage != null) { 17804 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17805 mCurResumedPackage, mCurResumedUid); 17806 } 17807 mCurResumedPackage = pkg; 17808 mCurResumedUid = uid; 17809 if (mCurResumedPackage != null) { 17810 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17811 mCurResumedPackage, mCurResumedUid); 17812 } 17813 } 17814 return act; 17815 } 17816 17817 final boolean updateOomAdjLocked(ProcessRecord app) { 17818 final ActivityRecord TOP_ACT = resumedAppLocked(); 17819 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17820 final boolean wasCached = app.cached; 17821 17822 mAdjSeq++; 17823 17824 // This is the desired cached adjusment we want to tell it to use. 17825 // If our app is currently cached, we know it, and that is it. Otherwise, 17826 // we don't know it yet, and it needs to now be cached we will then 17827 // need to do a complete oom adj. 17828 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17829 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17830 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17831 SystemClock.uptimeMillis()); 17832 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17833 // Changed to/from cached state, so apps after it in the LRU 17834 // list may also be changed. 17835 updateOomAdjLocked(); 17836 } 17837 return success; 17838 } 17839 17840 final void updateOomAdjLocked() { 17841 final ActivityRecord TOP_ACT = resumedAppLocked(); 17842 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17843 final long now = SystemClock.uptimeMillis(); 17844 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17845 final int N = mLruProcesses.size(); 17846 17847 if (false) { 17848 RuntimeException e = new RuntimeException(); 17849 e.fillInStackTrace(); 17850 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17851 } 17852 17853 mAdjSeq++; 17854 mNewNumServiceProcs = 0; 17855 mNewNumAServiceProcs = 0; 17856 17857 final int emptyProcessLimit; 17858 final int cachedProcessLimit; 17859 if (mProcessLimit <= 0) { 17860 emptyProcessLimit = cachedProcessLimit = 0; 17861 } else if (mProcessLimit == 1) { 17862 emptyProcessLimit = 1; 17863 cachedProcessLimit = 0; 17864 } else { 17865 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17866 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17867 } 17868 17869 // Let's determine how many processes we have running vs. 17870 // how many slots we have for background processes; we may want 17871 // to put multiple processes in a slot of there are enough of 17872 // them. 17873 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17874 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17875 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17876 if (numEmptyProcs > cachedProcessLimit) { 17877 // If there are more empty processes than our limit on cached 17878 // processes, then use the cached process limit for the factor. 17879 // This ensures that the really old empty processes get pushed 17880 // down to the bottom, so if we are running low on memory we will 17881 // have a better chance at keeping around more cached processes 17882 // instead of a gazillion empty processes. 17883 numEmptyProcs = cachedProcessLimit; 17884 } 17885 int emptyFactor = numEmptyProcs/numSlots; 17886 if (emptyFactor < 1) emptyFactor = 1; 17887 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17888 if (cachedFactor < 1) cachedFactor = 1; 17889 int stepCached = 0; 17890 int stepEmpty = 0; 17891 int numCached = 0; 17892 int numEmpty = 0; 17893 int numTrimming = 0; 17894 17895 mNumNonCachedProcs = 0; 17896 mNumCachedHiddenProcs = 0; 17897 17898 // First update the OOM adjustment for each of the 17899 // application processes based on their current state. 17900 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17901 int nextCachedAdj = curCachedAdj+1; 17902 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17903 int nextEmptyAdj = curEmptyAdj+2; 17904 for (int i=N-1; i>=0; i--) { 17905 ProcessRecord app = mLruProcesses.get(i); 17906 if (!app.killedByAm && app.thread != null) { 17907 app.procStateChanged = false; 17908 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17909 17910 // If we haven't yet assigned the final cached adj 17911 // to the process, do that now. 17912 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17913 switch (app.curProcState) { 17914 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17915 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17916 // This process is a cached process holding activities... 17917 // assign it the next cached value for that type, and then 17918 // step that cached level. 17919 app.curRawAdj = curCachedAdj; 17920 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17921 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17922 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17923 + ")"); 17924 if (curCachedAdj != nextCachedAdj) { 17925 stepCached++; 17926 if (stepCached >= cachedFactor) { 17927 stepCached = 0; 17928 curCachedAdj = nextCachedAdj; 17929 nextCachedAdj += 2; 17930 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17931 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17932 } 17933 } 17934 } 17935 break; 17936 default: 17937 // For everything else, assign next empty cached process 17938 // level and bump that up. Note that this means that 17939 // long-running services that have dropped down to the 17940 // cached level will be treated as empty (since their process 17941 // state is still as a service), which is what we want. 17942 app.curRawAdj = curEmptyAdj; 17943 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17944 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17945 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17946 + ")"); 17947 if (curEmptyAdj != nextEmptyAdj) { 17948 stepEmpty++; 17949 if (stepEmpty >= emptyFactor) { 17950 stepEmpty = 0; 17951 curEmptyAdj = nextEmptyAdj; 17952 nextEmptyAdj += 2; 17953 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17954 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17955 } 17956 } 17957 } 17958 break; 17959 } 17960 } 17961 17962 applyOomAdjLocked(app, TOP_APP, true, now); 17963 17964 // Count the number of process types. 17965 switch (app.curProcState) { 17966 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17967 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17968 mNumCachedHiddenProcs++; 17969 numCached++; 17970 if (numCached > cachedProcessLimit) { 17971 app.kill("cached #" + numCached, true); 17972 } 17973 break; 17974 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17975 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17976 && app.lastActivityTime < oldTime) { 17977 app.kill("empty for " 17978 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17979 / 1000) + "s", true); 17980 } else { 17981 numEmpty++; 17982 if (numEmpty > emptyProcessLimit) { 17983 app.kill("empty #" + numEmpty, true); 17984 } 17985 } 17986 break; 17987 default: 17988 mNumNonCachedProcs++; 17989 break; 17990 } 17991 17992 if (app.isolated && app.services.size() <= 0) { 17993 // If this is an isolated process, and there are no 17994 // services running in it, then the process is no longer 17995 // needed. We agressively kill these because we can by 17996 // definition not re-use the same process again, and it is 17997 // good to avoid having whatever code was running in them 17998 // left sitting around after no longer needed. 17999 app.kill("isolated not needed", true); 18000 } 18001 18002 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18003 && !app.killedByAm) { 18004 numTrimming++; 18005 } 18006 } 18007 } 18008 18009 mNumServiceProcs = mNewNumServiceProcs; 18010 18011 // Now determine the memory trimming level of background processes. 18012 // Unfortunately we need to start at the back of the list to do this 18013 // properly. We only do this if the number of background apps we 18014 // are managing to keep around is less than half the maximum we desire; 18015 // if we are keeping a good number around, we'll let them use whatever 18016 // memory they want. 18017 final int numCachedAndEmpty = numCached + numEmpty; 18018 int memFactor; 18019 if (numCached <= ProcessList.TRIM_CACHED_APPS 18020 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18021 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18022 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18023 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18024 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18025 } else { 18026 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18027 } 18028 } else { 18029 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18030 } 18031 // We always allow the memory level to go up (better). We only allow it to go 18032 // down if we are in a state where that is allowed, *and* the total number of processes 18033 // has gone down since last time. 18034 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18035 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18036 + " last=" + mLastNumProcesses); 18037 if (memFactor > mLastMemoryLevel) { 18038 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18039 memFactor = mLastMemoryLevel; 18040 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18041 } 18042 } 18043 mLastMemoryLevel = memFactor; 18044 mLastNumProcesses = mLruProcesses.size(); 18045 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18046 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18047 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18048 if (mLowRamStartTime == 0) { 18049 mLowRamStartTime = now; 18050 } 18051 int step = 0; 18052 int fgTrimLevel; 18053 switch (memFactor) { 18054 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18055 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18056 break; 18057 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18058 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18059 break; 18060 default: 18061 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18062 break; 18063 } 18064 int factor = numTrimming/3; 18065 int minFactor = 2; 18066 if (mHomeProcess != null) minFactor++; 18067 if (mPreviousProcess != null) minFactor++; 18068 if (factor < minFactor) factor = minFactor; 18069 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18070 for (int i=N-1; i>=0; i--) { 18071 ProcessRecord app = mLruProcesses.get(i); 18072 if (allChanged || app.procStateChanged) { 18073 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18074 app.procStateChanged = false; 18075 } 18076 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18077 && !app.killedByAm) { 18078 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18079 try { 18080 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18081 "Trimming memory of " + app.processName 18082 + " to " + curLevel); 18083 app.thread.scheduleTrimMemory(curLevel); 18084 } catch (RemoteException e) { 18085 } 18086 if (false) { 18087 // For now we won't do this; our memory trimming seems 18088 // to be good enough at this point that destroying 18089 // activities causes more harm than good. 18090 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18091 && app != mHomeProcess && app != mPreviousProcess) { 18092 // Need to do this on its own message because the stack may not 18093 // be in a consistent state at this point. 18094 // For these apps we will also finish their activities 18095 // to help them free memory. 18096 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18097 } 18098 } 18099 } 18100 app.trimMemoryLevel = curLevel; 18101 step++; 18102 if (step >= factor) { 18103 step = 0; 18104 switch (curLevel) { 18105 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18106 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18107 break; 18108 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18109 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18110 break; 18111 } 18112 } 18113 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18114 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18115 && app.thread != null) { 18116 try { 18117 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18118 "Trimming memory of heavy-weight " + app.processName 18119 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18120 app.thread.scheduleTrimMemory( 18121 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18122 } catch (RemoteException e) { 18123 } 18124 } 18125 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18126 } else { 18127 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18128 || app.systemNoUi) && app.pendingUiClean) { 18129 // If this application is now in the background and it 18130 // had done UI, then give it the special trim level to 18131 // have it free UI resources. 18132 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18133 if (app.trimMemoryLevel < level && app.thread != null) { 18134 try { 18135 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18136 "Trimming memory of bg-ui " + app.processName 18137 + " to " + level); 18138 app.thread.scheduleTrimMemory(level); 18139 } catch (RemoteException e) { 18140 } 18141 } 18142 app.pendingUiClean = false; 18143 } 18144 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18145 try { 18146 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18147 "Trimming memory of fg " + app.processName 18148 + " to " + fgTrimLevel); 18149 app.thread.scheduleTrimMemory(fgTrimLevel); 18150 } catch (RemoteException e) { 18151 } 18152 } 18153 app.trimMemoryLevel = fgTrimLevel; 18154 } 18155 } 18156 } else { 18157 if (mLowRamStartTime != 0) { 18158 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18159 mLowRamStartTime = 0; 18160 } 18161 for (int i=N-1; i>=0; i--) { 18162 ProcessRecord app = mLruProcesses.get(i); 18163 if (allChanged || app.procStateChanged) { 18164 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18165 app.procStateChanged = false; 18166 } 18167 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18168 || app.systemNoUi) && app.pendingUiClean) { 18169 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18170 && app.thread != null) { 18171 try { 18172 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18173 "Trimming memory of ui hidden " + app.processName 18174 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18175 app.thread.scheduleTrimMemory( 18176 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18177 } catch (RemoteException e) { 18178 } 18179 } 18180 app.pendingUiClean = false; 18181 } 18182 app.trimMemoryLevel = 0; 18183 } 18184 } 18185 18186 if (mAlwaysFinishActivities) { 18187 // Need to do this on its own message because the stack may not 18188 // be in a consistent state at this point. 18189 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18190 } 18191 18192 if (allChanged) { 18193 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18194 } 18195 18196 if (mProcessStats.shouldWriteNowLocked(now)) { 18197 mHandler.post(new Runnable() { 18198 @Override public void run() { 18199 synchronized (ActivityManagerService.this) { 18200 mProcessStats.writeStateAsyncLocked(); 18201 } 18202 } 18203 }); 18204 } 18205 18206 if (DEBUG_OOM_ADJ) { 18207 if (false) { 18208 RuntimeException here = new RuntimeException("here"); 18209 here.fillInStackTrace(); 18210 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18211 } else { 18212 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18213 } 18214 } 18215 } 18216 18217 final void trimApplications() { 18218 synchronized (this) { 18219 int i; 18220 18221 // First remove any unused application processes whose package 18222 // has been removed. 18223 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18224 final ProcessRecord app = mRemovedProcesses.get(i); 18225 if (app.activities.size() == 0 18226 && app.curReceiver == null && app.services.size() == 0) { 18227 Slog.i( 18228 TAG, "Exiting empty application process " 18229 + app.processName + " (" 18230 + (app.thread != null ? app.thread.asBinder() : null) 18231 + ")\n"); 18232 if (app.pid > 0 && app.pid != MY_PID) { 18233 app.kill("empty", false); 18234 } else { 18235 try { 18236 app.thread.scheduleExit(); 18237 } catch (Exception e) { 18238 // Ignore exceptions. 18239 } 18240 } 18241 cleanUpApplicationRecordLocked(app, false, true, -1); 18242 mRemovedProcesses.remove(i); 18243 18244 if (app.persistent) { 18245 addAppLocked(app.info, false, null /* ABI override */); 18246 } 18247 } 18248 } 18249 18250 // Now update the oom adj for all processes. 18251 updateOomAdjLocked(); 18252 } 18253 } 18254 18255 /** This method sends the specified signal to each of the persistent apps */ 18256 public void signalPersistentProcesses(int sig) throws RemoteException { 18257 if (sig != Process.SIGNAL_USR1) { 18258 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18259 } 18260 18261 synchronized (this) { 18262 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18263 != PackageManager.PERMISSION_GRANTED) { 18264 throw new SecurityException("Requires permission " 18265 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18266 } 18267 18268 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18269 ProcessRecord r = mLruProcesses.get(i); 18270 if (r.thread != null && r.persistent) { 18271 Process.sendSignal(r.pid, sig); 18272 } 18273 } 18274 } 18275 } 18276 18277 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18278 if (proc == null || proc == mProfileProc) { 18279 proc = mProfileProc; 18280 profileType = mProfileType; 18281 clearProfilerLocked(); 18282 } 18283 if (proc == null) { 18284 return; 18285 } 18286 try { 18287 proc.thread.profilerControl(false, null, profileType); 18288 } catch (RemoteException e) { 18289 throw new IllegalStateException("Process disappeared"); 18290 } 18291 } 18292 18293 private void clearProfilerLocked() { 18294 if (mProfileFd != null) { 18295 try { 18296 mProfileFd.close(); 18297 } catch (IOException e) { 18298 } 18299 } 18300 mProfileApp = null; 18301 mProfileProc = null; 18302 mProfileFile = null; 18303 mProfileType = 0; 18304 mAutoStopProfiler = false; 18305 mSamplingInterval = 0; 18306 } 18307 18308 public boolean profileControl(String process, int userId, boolean start, 18309 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18310 18311 try { 18312 synchronized (this) { 18313 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18314 // its own permission. 18315 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18316 != PackageManager.PERMISSION_GRANTED) { 18317 throw new SecurityException("Requires permission " 18318 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18319 } 18320 18321 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18322 throw new IllegalArgumentException("null profile info or fd"); 18323 } 18324 18325 ProcessRecord proc = null; 18326 if (process != null) { 18327 proc = findProcessLocked(process, userId, "profileControl"); 18328 } 18329 18330 if (start && (proc == null || proc.thread == null)) { 18331 throw new IllegalArgumentException("Unknown process: " + process); 18332 } 18333 18334 if (start) { 18335 stopProfilerLocked(null, 0); 18336 setProfileApp(proc.info, proc.processName, profilerInfo); 18337 mProfileProc = proc; 18338 mProfileType = profileType; 18339 ParcelFileDescriptor fd = profilerInfo.profileFd; 18340 try { 18341 fd = fd.dup(); 18342 } catch (IOException e) { 18343 fd = null; 18344 } 18345 profilerInfo.profileFd = fd; 18346 proc.thread.profilerControl(start, profilerInfo, profileType); 18347 fd = null; 18348 mProfileFd = null; 18349 } else { 18350 stopProfilerLocked(proc, profileType); 18351 if (profilerInfo != null && profilerInfo.profileFd != null) { 18352 try { 18353 profilerInfo.profileFd.close(); 18354 } catch (IOException e) { 18355 } 18356 } 18357 } 18358 18359 return true; 18360 } 18361 } catch (RemoteException e) { 18362 throw new IllegalStateException("Process disappeared"); 18363 } finally { 18364 if (profilerInfo != null && profilerInfo.profileFd != null) { 18365 try { 18366 profilerInfo.profileFd.close(); 18367 } catch (IOException e) { 18368 } 18369 } 18370 } 18371 } 18372 18373 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18374 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18375 userId, true, ALLOW_FULL_ONLY, callName, null); 18376 ProcessRecord proc = null; 18377 try { 18378 int pid = Integer.parseInt(process); 18379 synchronized (mPidsSelfLocked) { 18380 proc = mPidsSelfLocked.get(pid); 18381 } 18382 } catch (NumberFormatException e) { 18383 } 18384 18385 if (proc == null) { 18386 ArrayMap<String, SparseArray<ProcessRecord>> all 18387 = mProcessNames.getMap(); 18388 SparseArray<ProcessRecord> procs = all.get(process); 18389 if (procs != null && procs.size() > 0) { 18390 proc = procs.valueAt(0); 18391 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18392 for (int i=1; i<procs.size(); i++) { 18393 ProcessRecord thisProc = procs.valueAt(i); 18394 if (thisProc.userId == userId) { 18395 proc = thisProc; 18396 break; 18397 } 18398 } 18399 } 18400 } 18401 } 18402 18403 return proc; 18404 } 18405 18406 public boolean dumpHeap(String process, int userId, boolean managed, 18407 String path, ParcelFileDescriptor fd) throws RemoteException { 18408 18409 try { 18410 synchronized (this) { 18411 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18412 // its own permission (same as profileControl). 18413 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18414 != PackageManager.PERMISSION_GRANTED) { 18415 throw new SecurityException("Requires permission " 18416 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18417 } 18418 18419 if (fd == null) { 18420 throw new IllegalArgumentException("null fd"); 18421 } 18422 18423 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18424 if (proc == null || proc.thread == null) { 18425 throw new IllegalArgumentException("Unknown process: " + process); 18426 } 18427 18428 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18429 if (!isDebuggable) { 18430 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18431 throw new SecurityException("Process not debuggable: " + proc); 18432 } 18433 } 18434 18435 proc.thread.dumpHeap(managed, path, fd); 18436 fd = null; 18437 return true; 18438 } 18439 } catch (RemoteException e) { 18440 throw new IllegalStateException("Process disappeared"); 18441 } finally { 18442 if (fd != null) { 18443 try { 18444 fd.close(); 18445 } catch (IOException e) { 18446 } 18447 } 18448 } 18449 } 18450 18451 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18452 public void monitor() { 18453 synchronized (this) { } 18454 } 18455 18456 void onCoreSettingsChange(Bundle settings) { 18457 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18458 ProcessRecord processRecord = mLruProcesses.get(i); 18459 try { 18460 if (processRecord.thread != null) { 18461 processRecord.thread.setCoreSettings(settings); 18462 } 18463 } catch (RemoteException re) { 18464 /* ignore */ 18465 } 18466 } 18467 } 18468 18469 // Multi-user methods 18470 18471 /** 18472 * Start user, if its not already running, but don't bring it to foreground. 18473 */ 18474 @Override 18475 public boolean startUserInBackground(final int userId) { 18476 return startUser(userId, /* foreground */ false); 18477 } 18478 18479 /** 18480 * Start user, if its not already running, and bring it to foreground. 18481 */ 18482 boolean startUserInForeground(final int userId, Dialog dlg) { 18483 boolean result = startUser(userId, /* foreground */ true); 18484 dlg.dismiss(); 18485 return result; 18486 } 18487 18488 /** 18489 * Refreshes the list of users related to the current user when either a 18490 * user switch happens or when a new related user is started in the 18491 * background. 18492 */ 18493 private void updateCurrentProfileIdsLocked() { 18494 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18495 mCurrentUserId, false /* enabledOnly */); 18496 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18497 for (int i = 0; i < currentProfileIds.length; i++) { 18498 currentProfileIds[i] = profiles.get(i).id; 18499 } 18500 mCurrentProfileIds = currentProfileIds; 18501 18502 synchronized (mUserProfileGroupIdsSelfLocked) { 18503 mUserProfileGroupIdsSelfLocked.clear(); 18504 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18505 for (int i = 0; i < users.size(); i++) { 18506 UserInfo user = users.get(i); 18507 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18508 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18509 } 18510 } 18511 } 18512 } 18513 18514 private Set getProfileIdsLocked(int userId) { 18515 Set userIds = new HashSet<Integer>(); 18516 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18517 userId, false /* enabledOnly */); 18518 for (UserInfo user : profiles) { 18519 userIds.add(Integer.valueOf(user.id)); 18520 } 18521 return userIds; 18522 } 18523 18524 @Override 18525 public boolean switchUser(final int userId) { 18526 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18527 String userName; 18528 synchronized (this) { 18529 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18530 if (userInfo == null) { 18531 Slog.w(TAG, "No user info for user #" + userId); 18532 return false; 18533 } 18534 if (userInfo.isManagedProfile()) { 18535 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18536 return false; 18537 } 18538 userName = userInfo.name; 18539 mTargetUserId = userId; 18540 } 18541 mHandler.removeMessages(START_USER_SWITCH_MSG); 18542 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18543 return true; 18544 } 18545 18546 private void showUserSwitchDialog(int userId, String userName) { 18547 // The dialog will show and then initiate the user switch by calling startUserInForeground 18548 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18549 true /* above system */); 18550 d.show(); 18551 } 18552 18553 private boolean startUser(final int userId, final boolean foreground) { 18554 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18555 != PackageManager.PERMISSION_GRANTED) { 18556 String msg = "Permission Denial: switchUser() from pid=" 18557 + Binder.getCallingPid() 18558 + ", uid=" + Binder.getCallingUid() 18559 + " requires " + INTERACT_ACROSS_USERS_FULL; 18560 Slog.w(TAG, msg); 18561 throw new SecurityException(msg); 18562 } 18563 18564 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18565 18566 final long ident = Binder.clearCallingIdentity(); 18567 try { 18568 synchronized (this) { 18569 final int oldUserId = mCurrentUserId; 18570 if (oldUserId == userId) { 18571 return true; 18572 } 18573 18574 mStackSupervisor.setLockTaskModeLocked(null, false); 18575 18576 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18577 if (userInfo == null) { 18578 Slog.w(TAG, "No user info for user #" + userId); 18579 return false; 18580 } 18581 if (foreground && userInfo.isManagedProfile()) { 18582 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18583 return false; 18584 } 18585 18586 if (foreground) { 18587 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18588 R.anim.screen_user_enter); 18589 } 18590 18591 boolean needStart = false; 18592 18593 // If the user we are switching to is not currently started, then 18594 // we need to start it now. 18595 if (mStartedUsers.get(userId) == null) { 18596 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18597 updateStartedUserArrayLocked(); 18598 needStart = true; 18599 } 18600 18601 final Integer userIdInt = Integer.valueOf(userId); 18602 mUserLru.remove(userIdInt); 18603 mUserLru.add(userIdInt); 18604 18605 if (foreground) { 18606 mCurrentUserId = userId; 18607 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18608 updateCurrentProfileIdsLocked(); 18609 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18610 // Once the internal notion of the active user has switched, we lock the device 18611 // with the option to show the user switcher on the keyguard. 18612 mWindowManager.lockNow(null); 18613 } else { 18614 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18615 updateCurrentProfileIdsLocked(); 18616 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18617 mUserLru.remove(currentUserIdInt); 18618 mUserLru.add(currentUserIdInt); 18619 } 18620 18621 final UserStartedState uss = mStartedUsers.get(userId); 18622 18623 // Make sure user is in the started state. If it is currently 18624 // stopping, we need to knock that off. 18625 if (uss.mState == UserStartedState.STATE_STOPPING) { 18626 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18627 // so we can just fairly silently bring the user back from 18628 // the almost-dead. 18629 uss.mState = UserStartedState.STATE_RUNNING; 18630 updateStartedUserArrayLocked(); 18631 needStart = true; 18632 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18633 // This means ACTION_SHUTDOWN has been sent, so we will 18634 // need to treat this as a new boot of the user. 18635 uss.mState = UserStartedState.STATE_BOOTING; 18636 updateStartedUserArrayLocked(); 18637 needStart = true; 18638 } 18639 18640 if (uss.mState == UserStartedState.STATE_BOOTING) { 18641 // Booting up a new user, need to tell system services about it. 18642 // Note that this is on the same handler as scheduling of broadcasts, 18643 // which is important because it needs to go first. 18644 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18645 } 18646 18647 if (foreground) { 18648 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18649 oldUserId)); 18650 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18651 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18652 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18653 oldUserId, userId, uss)); 18654 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18655 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18656 } 18657 18658 if (needStart) { 18659 // Send USER_STARTED broadcast 18660 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18661 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18662 | Intent.FLAG_RECEIVER_FOREGROUND); 18663 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18664 broadcastIntentLocked(null, null, intent, 18665 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18666 false, false, MY_PID, Process.SYSTEM_UID, userId); 18667 } 18668 18669 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18670 if (userId != UserHandle.USER_OWNER) { 18671 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18672 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18673 broadcastIntentLocked(null, null, intent, null, 18674 new IIntentReceiver.Stub() { 18675 public void performReceive(Intent intent, int resultCode, 18676 String data, Bundle extras, boolean ordered, 18677 boolean sticky, int sendingUser) { 18678 onUserInitialized(uss, foreground, oldUserId, userId); 18679 } 18680 }, 0, null, null, null, AppOpsManager.OP_NONE, 18681 true, false, MY_PID, Process.SYSTEM_UID, 18682 userId); 18683 uss.initializing = true; 18684 } else { 18685 getUserManagerLocked().makeInitialized(userInfo.id); 18686 } 18687 } 18688 18689 if (foreground) { 18690 if (!uss.initializing) { 18691 moveUserToForeground(uss, oldUserId, userId); 18692 } 18693 } else { 18694 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18695 } 18696 18697 if (needStart) { 18698 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18699 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18700 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18701 broadcastIntentLocked(null, null, intent, 18702 null, new IIntentReceiver.Stub() { 18703 @Override 18704 public void performReceive(Intent intent, int resultCode, String data, 18705 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18706 throws RemoteException { 18707 } 18708 }, 0, null, null, 18709 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18710 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18711 } 18712 } 18713 } finally { 18714 Binder.restoreCallingIdentity(ident); 18715 } 18716 18717 return true; 18718 } 18719 18720 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18721 long ident = Binder.clearCallingIdentity(); 18722 try { 18723 Intent intent; 18724 if (oldUserId >= 0) { 18725 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18726 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18727 int count = profiles.size(); 18728 for (int i = 0; i < count; i++) { 18729 int profileUserId = profiles.get(i).id; 18730 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18731 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18732 | Intent.FLAG_RECEIVER_FOREGROUND); 18733 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18734 broadcastIntentLocked(null, null, intent, 18735 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18736 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18737 } 18738 } 18739 if (newUserId >= 0) { 18740 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18741 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18742 int count = profiles.size(); 18743 for (int i = 0; i < count; i++) { 18744 int profileUserId = profiles.get(i).id; 18745 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18746 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18747 | Intent.FLAG_RECEIVER_FOREGROUND); 18748 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18749 broadcastIntentLocked(null, null, intent, 18750 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18751 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18752 } 18753 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18754 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18755 | Intent.FLAG_RECEIVER_FOREGROUND); 18756 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18757 broadcastIntentLocked(null, null, intent, 18758 null, null, 0, null, null, 18759 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18760 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18761 } 18762 } finally { 18763 Binder.restoreCallingIdentity(ident); 18764 } 18765 } 18766 18767 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18768 final int newUserId) { 18769 final int N = mUserSwitchObservers.beginBroadcast(); 18770 if (N > 0) { 18771 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18772 int mCount = 0; 18773 @Override 18774 public void sendResult(Bundle data) throws RemoteException { 18775 synchronized (ActivityManagerService.this) { 18776 if (mCurUserSwitchCallback == this) { 18777 mCount++; 18778 if (mCount == N) { 18779 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18780 } 18781 } 18782 } 18783 } 18784 }; 18785 synchronized (this) { 18786 uss.switching = true; 18787 mCurUserSwitchCallback = callback; 18788 } 18789 for (int i=0; i<N; i++) { 18790 try { 18791 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18792 newUserId, callback); 18793 } catch (RemoteException e) { 18794 } 18795 } 18796 } else { 18797 synchronized (this) { 18798 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18799 } 18800 } 18801 mUserSwitchObservers.finishBroadcast(); 18802 } 18803 18804 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18805 synchronized (this) { 18806 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18807 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18808 } 18809 } 18810 18811 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18812 mCurUserSwitchCallback = null; 18813 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18814 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18815 oldUserId, newUserId, uss)); 18816 } 18817 18818 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18819 synchronized (this) { 18820 if (foreground) { 18821 moveUserToForeground(uss, oldUserId, newUserId); 18822 } 18823 } 18824 18825 completeSwitchAndInitalize(uss, newUserId, true, false); 18826 } 18827 18828 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18829 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18830 if (homeInFront) { 18831 startHomeActivityLocked(newUserId); 18832 } else { 18833 mStackSupervisor.resumeTopActivitiesLocked(); 18834 } 18835 EventLogTags.writeAmSwitchUser(newUserId); 18836 getUserManagerLocked().userForeground(newUserId); 18837 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18838 } 18839 18840 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18841 completeSwitchAndInitalize(uss, newUserId, false, true); 18842 } 18843 18844 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18845 boolean clearInitializing, boolean clearSwitching) { 18846 boolean unfrozen = false; 18847 synchronized (this) { 18848 if (clearInitializing) { 18849 uss.initializing = false; 18850 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18851 } 18852 if (clearSwitching) { 18853 uss.switching = false; 18854 } 18855 if (!uss.switching && !uss.initializing) { 18856 mWindowManager.stopFreezingScreen(); 18857 unfrozen = true; 18858 } 18859 } 18860 if (unfrozen) { 18861 final int N = mUserSwitchObservers.beginBroadcast(); 18862 for (int i=0; i<N; i++) { 18863 try { 18864 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18865 } catch (RemoteException e) { 18866 } 18867 } 18868 mUserSwitchObservers.finishBroadcast(); 18869 } 18870 } 18871 18872 void scheduleStartProfilesLocked() { 18873 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18874 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18875 DateUtils.SECOND_IN_MILLIS); 18876 } 18877 } 18878 18879 void startProfilesLocked() { 18880 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18881 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18882 mCurrentUserId, false /* enabledOnly */); 18883 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18884 for (UserInfo user : profiles) { 18885 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18886 && user.id != mCurrentUserId) { 18887 toStart.add(user); 18888 } 18889 } 18890 final int n = toStart.size(); 18891 int i = 0; 18892 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18893 startUserInBackground(toStart.get(i).id); 18894 } 18895 if (i < n) { 18896 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18897 } 18898 } 18899 18900 void finishUserBoot(UserStartedState uss) { 18901 synchronized (this) { 18902 if (uss.mState == UserStartedState.STATE_BOOTING 18903 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18904 uss.mState = UserStartedState.STATE_RUNNING; 18905 final int userId = uss.mHandle.getIdentifier(); 18906 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18907 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18908 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18909 broadcastIntentLocked(null, null, intent, 18910 null, null, 0, null, null, 18911 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18912 true, false, MY_PID, Process.SYSTEM_UID, userId); 18913 } 18914 } 18915 } 18916 18917 void finishUserSwitch(UserStartedState uss) { 18918 synchronized (this) { 18919 finishUserBoot(uss); 18920 18921 startProfilesLocked(); 18922 18923 int num = mUserLru.size(); 18924 int i = 0; 18925 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18926 Integer oldUserId = mUserLru.get(i); 18927 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18928 if (oldUss == null) { 18929 // Shouldn't happen, but be sane if it does. 18930 mUserLru.remove(i); 18931 num--; 18932 continue; 18933 } 18934 if (oldUss.mState == UserStartedState.STATE_STOPPING 18935 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18936 // This user is already stopping, doesn't count. 18937 num--; 18938 i++; 18939 continue; 18940 } 18941 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18942 // Owner and current can't be stopped, but count as running. 18943 i++; 18944 continue; 18945 } 18946 // This is a user to be stopped. 18947 stopUserLocked(oldUserId, null); 18948 num--; 18949 i++; 18950 } 18951 } 18952 } 18953 18954 @Override 18955 public int stopUser(final int userId, final IStopUserCallback callback) { 18956 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18957 != PackageManager.PERMISSION_GRANTED) { 18958 String msg = "Permission Denial: switchUser() from pid=" 18959 + Binder.getCallingPid() 18960 + ", uid=" + Binder.getCallingUid() 18961 + " requires " + INTERACT_ACROSS_USERS_FULL; 18962 Slog.w(TAG, msg); 18963 throw new SecurityException(msg); 18964 } 18965 if (userId <= 0) { 18966 throw new IllegalArgumentException("Can't stop primary user " + userId); 18967 } 18968 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18969 synchronized (this) { 18970 return stopUserLocked(userId, callback); 18971 } 18972 } 18973 18974 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18975 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18976 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18977 return ActivityManager.USER_OP_IS_CURRENT; 18978 } 18979 18980 final UserStartedState uss = mStartedUsers.get(userId); 18981 if (uss == null) { 18982 // User is not started, nothing to do... but we do need to 18983 // callback if requested. 18984 if (callback != null) { 18985 mHandler.post(new Runnable() { 18986 @Override 18987 public void run() { 18988 try { 18989 callback.userStopped(userId); 18990 } catch (RemoteException e) { 18991 } 18992 } 18993 }); 18994 } 18995 return ActivityManager.USER_OP_SUCCESS; 18996 } 18997 18998 if (callback != null) { 18999 uss.mStopCallbacks.add(callback); 19000 } 19001 19002 if (uss.mState != UserStartedState.STATE_STOPPING 19003 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19004 uss.mState = UserStartedState.STATE_STOPPING; 19005 updateStartedUserArrayLocked(); 19006 19007 long ident = Binder.clearCallingIdentity(); 19008 try { 19009 // We are going to broadcast ACTION_USER_STOPPING and then 19010 // once that is done send a final ACTION_SHUTDOWN and then 19011 // stop the user. 19012 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19013 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19014 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19015 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19016 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19017 // This is the result receiver for the final shutdown broadcast. 19018 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19019 @Override 19020 public void performReceive(Intent intent, int resultCode, String data, 19021 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19022 finishUserStop(uss); 19023 } 19024 }; 19025 // This is the result receiver for the initial stopping broadcast. 19026 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19027 @Override 19028 public void performReceive(Intent intent, int resultCode, String data, 19029 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19030 // On to the next. 19031 synchronized (ActivityManagerService.this) { 19032 if (uss.mState != UserStartedState.STATE_STOPPING) { 19033 // Whoops, we are being started back up. Abort, abort! 19034 return; 19035 } 19036 uss.mState = UserStartedState.STATE_SHUTDOWN; 19037 } 19038 mBatteryStatsService.noteEvent( 19039 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19040 Integer.toString(userId), userId); 19041 mSystemServiceManager.stopUser(userId); 19042 broadcastIntentLocked(null, null, shutdownIntent, 19043 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19044 true, false, MY_PID, Process.SYSTEM_UID, userId); 19045 } 19046 }; 19047 // Kick things off. 19048 broadcastIntentLocked(null, null, stoppingIntent, 19049 null, stoppingReceiver, 0, null, null, 19050 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19051 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19052 } finally { 19053 Binder.restoreCallingIdentity(ident); 19054 } 19055 } 19056 19057 return ActivityManager.USER_OP_SUCCESS; 19058 } 19059 19060 void finishUserStop(UserStartedState uss) { 19061 final int userId = uss.mHandle.getIdentifier(); 19062 boolean stopped; 19063 ArrayList<IStopUserCallback> callbacks; 19064 synchronized (this) { 19065 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19066 if (mStartedUsers.get(userId) != uss) { 19067 stopped = false; 19068 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19069 stopped = false; 19070 } else { 19071 stopped = true; 19072 // User can no longer run. 19073 mStartedUsers.remove(userId); 19074 mUserLru.remove(Integer.valueOf(userId)); 19075 updateStartedUserArrayLocked(); 19076 19077 // Clean up all state and processes associated with the user. 19078 // Kill all the processes for the user. 19079 forceStopUserLocked(userId, "finish user"); 19080 } 19081 19082 // Explicitly remove the old information in mRecentTasks. 19083 removeRecentTasksForUserLocked(userId); 19084 } 19085 19086 for (int i=0; i<callbacks.size(); i++) { 19087 try { 19088 if (stopped) callbacks.get(i).userStopped(userId); 19089 else callbacks.get(i).userStopAborted(userId); 19090 } catch (RemoteException e) { 19091 } 19092 } 19093 19094 if (stopped) { 19095 mSystemServiceManager.cleanupUser(userId); 19096 synchronized (this) { 19097 mStackSupervisor.removeUserLocked(userId); 19098 } 19099 } 19100 } 19101 19102 @Override 19103 public UserInfo getCurrentUser() { 19104 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19105 != PackageManager.PERMISSION_GRANTED) && ( 19106 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19107 != PackageManager.PERMISSION_GRANTED)) { 19108 String msg = "Permission Denial: getCurrentUser() from pid=" 19109 + Binder.getCallingPid() 19110 + ", uid=" + Binder.getCallingUid() 19111 + " requires " + INTERACT_ACROSS_USERS; 19112 Slog.w(TAG, msg); 19113 throw new SecurityException(msg); 19114 } 19115 synchronized (this) { 19116 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19117 return getUserManagerLocked().getUserInfo(userId); 19118 } 19119 } 19120 19121 int getCurrentUserIdLocked() { 19122 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19123 } 19124 19125 @Override 19126 public boolean isUserRunning(int userId, boolean orStopped) { 19127 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19128 != PackageManager.PERMISSION_GRANTED) { 19129 String msg = "Permission Denial: isUserRunning() from pid=" 19130 + Binder.getCallingPid() 19131 + ", uid=" + Binder.getCallingUid() 19132 + " requires " + INTERACT_ACROSS_USERS; 19133 Slog.w(TAG, msg); 19134 throw new SecurityException(msg); 19135 } 19136 synchronized (this) { 19137 return isUserRunningLocked(userId, orStopped); 19138 } 19139 } 19140 19141 boolean isUserRunningLocked(int userId, boolean orStopped) { 19142 UserStartedState state = mStartedUsers.get(userId); 19143 if (state == null) { 19144 return false; 19145 } 19146 if (orStopped) { 19147 return true; 19148 } 19149 return state.mState != UserStartedState.STATE_STOPPING 19150 && state.mState != UserStartedState.STATE_SHUTDOWN; 19151 } 19152 19153 @Override 19154 public int[] getRunningUserIds() { 19155 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19156 != PackageManager.PERMISSION_GRANTED) { 19157 String msg = "Permission Denial: isUserRunning() from pid=" 19158 + Binder.getCallingPid() 19159 + ", uid=" + Binder.getCallingUid() 19160 + " requires " + INTERACT_ACROSS_USERS; 19161 Slog.w(TAG, msg); 19162 throw new SecurityException(msg); 19163 } 19164 synchronized (this) { 19165 return mStartedUserArray; 19166 } 19167 } 19168 19169 private void updateStartedUserArrayLocked() { 19170 int num = 0; 19171 for (int i=0; i<mStartedUsers.size(); i++) { 19172 UserStartedState uss = mStartedUsers.valueAt(i); 19173 // This list does not include stopping users. 19174 if (uss.mState != UserStartedState.STATE_STOPPING 19175 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19176 num++; 19177 } 19178 } 19179 mStartedUserArray = new int[num]; 19180 num = 0; 19181 for (int i=0; i<mStartedUsers.size(); i++) { 19182 UserStartedState uss = mStartedUsers.valueAt(i); 19183 if (uss.mState != UserStartedState.STATE_STOPPING 19184 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19185 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19186 num++; 19187 } 19188 } 19189 } 19190 19191 @Override 19192 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19193 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19194 != PackageManager.PERMISSION_GRANTED) { 19195 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19196 + Binder.getCallingPid() 19197 + ", uid=" + Binder.getCallingUid() 19198 + " requires " + INTERACT_ACROSS_USERS_FULL; 19199 Slog.w(TAG, msg); 19200 throw new SecurityException(msg); 19201 } 19202 19203 mUserSwitchObservers.register(observer); 19204 } 19205 19206 @Override 19207 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19208 mUserSwitchObservers.unregister(observer); 19209 } 19210 19211 private boolean userExists(int userId) { 19212 if (userId == 0) { 19213 return true; 19214 } 19215 UserManagerService ums = getUserManagerLocked(); 19216 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19217 } 19218 19219 int[] getUsersLocked() { 19220 UserManagerService ums = getUserManagerLocked(); 19221 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19222 } 19223 19224 UserManagerService getUserManagerLocked() { 19225 if (mUserManager == null) { 19226 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19227 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19228 } 19229 return mUserManager; 19230 } 19231 19232 private int applyUserId(int uid, int userId) { 19233 return UserHandle.getUid(userId, uid); 19234 } 19235 19236 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19237 if (info == null) return null; 19238 ApplicationInfo newInfo = new ApplicationInfo(info); 19239 newInfo.uid = applyUserId(info.uid, userId); 19240 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19241 + info.packageName; 19242 return newInfo; 19243 } 19244 19245 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19246 if (aInfo == null 19247 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19248 return aInfo; 19249 } 19250 19251 ActivityInfo info = new ActivityInfo(aInfo); 19252 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19253 return info; 19254 } 19255 19256 private final class LocalService extends ActivityManagerInternal { 19257 @Override 19258 public void onWakefulnessChanged(int wakefulness) { 19259 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19260 } 19261 19262 @Override 19263 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19264 String processName, String abiOverride, int uid, Runnable crashHandler) { 19265 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19266 processName, abiOverride, uid, crashHandler); 19267 } 19268 } 19269 19270 /** 19271 * An implementation of IAppTask, that allows an app to manage its own tasks via 19272 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19273 * only the process that calls getAppTasks() can call the AppTask methods. 19274 */ 19275 class AppTaskImpl extends IAppTask.Stub { 19276 private int mTaskId; 19277 private int mCallingUid; 19278 19279 public AppTaskImpl(int taskId, int callingUid) { 19280 mTaskId = taskId; 19281 mCallingUid = callingUid; 19282 } 19283 19284 private void checkCaller() { 19285 if (mCallingUid != Binder.getCallingUid()) { 19286 throw new SecurityException("Caller " + mCallingUid 19287 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19288 } 19289 } 19290 19291 @Override 19292 public void finishAndRemoveTask() { 19293 checkCaller(); 19294 19295 synchronized (ActivityManagerService.this) { 19296 long origId = Binder.clearCallingIdentity(); 19297 try { 19298 if (!removeTaskByIdLocked(mTaskId, false)) { 19299 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19300 } 19301 } finally { 19302 Binder.restoreCallingIdentity(origId); 19303 } 19304 } 19305 } 19306 19307 @Override 19308 public ActivityManager.RecentTaskInfo getTaskInfo() { 19309 checkCaller(); 19310 19311 synchronized (ActivityManagerService.this) { 19312 long origId = Binder.clearCallingIdentity(); 19313 try { 19314 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19315 if (tr == null) { 19316 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19317 } 19318 return createRecentTaskInfoFromTaskRecord(tr); 19319 } finally { 19320 Binder.restoreCallingIdentity(origId); 19321 } 19322 } 19323 } 19324 19325 @Override 19326 public void moveToFront() { 19327 checkCaller(); 19328 19329 final TaskRecord tr; 19330 synchronized (ActivityManagerService.this) { 19331 tr = recentTaskForIdLocked(mTaskId); 19332 if (tr == null) { 19333 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19334 } 19335 if (tr.getRootActivity() != null) { 19336 moveTaskToFrontLocked(tr.taskId, 0, null); 19337 return; 19338 } 19339 } 19340 19341 startActivityFromRecentsInner(tr.taskId, null); 19342 } 19343 19344 @Override 19345 public int startActivity(IBinder whoThread, String callingPackage, 19346 Intent intent, String resolvedType, Bundle options) { 19347 checkCaller(); 19348 19349 int callingUser = UserHandle.getCallingUserId(); 19350 TaskRecord tr; 19351 IApplicationThread appThread; 19352 synchronized (ActivityManagerService.this) { 19353 tr = recentTaskForIdLocked(mTaskId); 19354 if (tr == null) { 19355 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19356 } 19357 appThread = ApplicationThreadNative.asInterface(whoThread); 19358 if (appThread == null) { 19359 throw new IllegalArgumentException("Bad app thread " + appThread); 19360 } 19361 } 19362 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19363 resolvedType, null, null, null, null, 0, 0, null, null, 19364 null, options, callingUser, null, tr); 19365 } 19366 19367 @Override 19368 public void setExcludeFromRecents(boolean exclude) { 19369 checkCaller(); 19370 19371 synchronized (ActivityManagerService.this) { 19372 long origId = Binder.clearCallingIdentity(); 19373 try { 19374 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19375 if (tr == null) { 19376 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19377 } 19378 Intent intent = tr.getBaseIntent(); 19379 if (exclude) { 19380 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19381 } else { 19382 intent.setFlags(intent.getFlags() 19383 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19384 } 19385 } finally { 19386 Binder.restoreCallingIdentity(origId); 19387 } 19388 } 19389 } 19390 } 19391} 19392